Getting the Google Client to work in Lumen - php

I am trying to get the google api client for php to work in Lumen, however trying to create a client results in my api to give a 'Oops, something went wrong' error with no further useful information.
I think it is something to do with the way im trying to import the google api client into Lumen, i used composer to install it. But i am not sure if i am using the right thing for Lumen. If i change my require_once it would state that it could not find the 'autoload.php' in the current path. I've also tried the composer update -vvv
The Google folder is present in my vendor folder, and the composer.json also has a entry for the google/apiclient
"require": {
"php": ">=7.1.3",
"google/apiclient": "2.0",
"laravel/lumen-framework": "5.8.*"
},
<?php
namespace App\Http\Controllers;
require_once dirname(__DIR__).'\..\..\vendor\autoload.php';
use App\Author;
use Illuminate\Http\Request;
class AccessController extends Controller
{
private function getToken()
{
$credentialsFilePath = 'service_account.json';
$client = new Google_Client();
$client->setAuthConfig($credentialsFilePath);
$client->addScope('https://googleapis.com/auth/analytics.readonly');
$client->setApplicationName("GoogleAnalytics");
$client->refreshTokenWithAssertion();
$token = $client->getAccessToken();
$accessToken = $token['access_token'];
return $accessToken;
}
public function showAccess()
{
$at = getToken();
return response('Token: ');
}
}
As you can see im trying to get the service account access token from a json that is saved at the server (no problems). but whenever the line $client = new Google_Client();
is called, i get the 'woops, something went wrong' error from Lumen

It appears i forgot the use Google_Client; Pretty simple but something i completely overlooked.

Related

How to create a credential (for google sheets) on GCE with php code?

I put my php code in GCE and wanna to modify google sheets.
Google told me that i don't have to apply a extra credential by using GCP>API because there's a strategy called Application Default Credentials (ADC) will find application's credentials.
I first check the environment variable "GOOGLE_APPLICATION_CREDENTIALS" in GCE server but it's empty.
Then i follow this tutorial https://cloud.google.com/docs/authentication/production?hl=zh_TW#auth-cloud-implicit-php and install this:
composer require google/cloud-storage
I tried the code under and got some error.
namespace Google\Cloud\Samples\Auth;
// Imports GCECredentials and the Cloud Storage client library.
use Google\Auth\Credentials\GCECredentials;
use Google\Cloud\Storage\StorageClient;
function auth_cloud_explicit_compute_engine($projectId)
{
$gceCredentials = new GCECredentials();
$config = [
'projectId' => $projectId,
'credentialsFetcher' => $gceCredentials,
];
$storage = new StorageClient($config);
# Make an authenticated API request (listing storage buckets)
foreach ($storage->buckets() as $bucket) {
printf('Bucket: %s' . PHP_EOL, $bucket->name());
}
}
PHP Fatal error: Uncaught Error: Class 'GCECredentials' not found in /var/www/html/google_sheets/t2.php:5
More question:
Will this code create a json file as credential for me to access google sheets?
$gceCredentials = new GCECredentials();
Or where can i find the service account key??
Please tell me what should i do, thanks a lot.

Asynchronous API calls from PHP application using Slim + Guzzle

I'm working on a php application using Slim framework. My application homepage is making about 20 REST API calls, which is slowing down the page load.
I read that I can use Http Clients like Guzzle to call these API's asynchronously but I couldn't find any article that tells how to use Guzzle with Slim.
Can someone tell how to use Guzzle with Slim.
Or is there any other solution that can speed up the page load?
N.B: I'm a novice in PHP
To use Guzzle with Slim, you need to
Install it by running composer
$ composer require guzzlehttp/guzzle:~6.0
Guzzle installation
Guzzle Quickstart
Create dependency registration, for example
<?php
use GuzzleHttp\Client;
$container = $app->getContainer();
$container['httpClient'] = function ($cntr) {
return new Client();
};
and put it somewhere where it will be executed when index.php the main bootstrap file is loaded.
Then in your code, you can get guzzle instance from container
$guzzle = $container->httpClient;
For example if you have following route
$app->get('/example', App\Controllers\Example::class);
And controller Example as follow
<?php
namespace App\Controllers;
use GuzzleHttp\ClientInterface;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
class Example
{
private $httpClient;
public function __construct(ClientInterface $httpClient)
{
$this->httpClient = $httpClient;
}
public function __invoke(Request $request, Response $response, array $args)
{
//call api, etc..etc
$apiResponse = $this->httpClient->get('http://api.blabla.org/get');
//do something with api response
return $response;
}
}
To inject guzzle instance to Example controller, you create its dependency registration
use App\Controllers\Example;
$container[Example::class] = function ($cntr) {
return new Example($cntr->httpClient);
}
To speed up your page load, if you are API developer then start from there. If you are not API developer and have no control, try to think if you can reduce number of API calls by removing non essential ones. Or as last resort, cache API call response to storage that is faster for your application to retrieve later.
For example using redis.
You calculate hash of API url call including its querystring and use hash as key to access cached API call response.

How to create a spreadsheet with google api and set a proper permissions with PHP?

I have this
define('CLIENT_SECRET_PATH', __DIR__ . '/config_api.json');
define('ACCESS_TOKEN', '0b502651********c52b3');
I can create a spreadsheet with this and get the id and url.
$requestBody = new Google_Service_Sheets_Spreadsheet();
$response = $service->spreadsheets->create($requestBody);
print_r($response);
$new_spr_id = $response['spreadsheetId'];
But this spreadsheet does not appears in the google sheets list as it is "protected" or something.
I am trying to set the permissions with this but get an error: Fatal error: Call to undefined method Google_Service_Drive_Permission::setValue()
insertPermission($service, $new_spr_id, '**#gmail.com' , 'user', 'owner');
function insertPermission($service, $fileId, $value, $type, $role) {
$newPermission = new Google_Service_Drive_Permission();
$newPermission->setValue($value);
$newPermission->setType($type);
$newPermission->setRole($role);
try {
return $service->permissions->insert($fileId, $newPermission);
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
return NULL;
}
I need an example of creating a new spreadsheet and setting the proper permissions to it so I can modify this spreadsheet from my account etc.
Many many thanks!
Your code is not able to locate class and unable to create instance of Google_Service_Drive_Permission(). I would suggest, don't use individual function to create object of Google_Service_Drive_Permission(). Place all your code to set permissions within the code part, where you are creating file. Also if you are using multiple files, check if your files are loading properly and are located by PHP parser. Because Fatal Error for undefined method call is not due to implementation of API methods, its due to calling for methods that does not exist or you PHP parser is unable to locate.
For reference this might be helpful
http://hotexamples.com/examples/-/Google_Service_Drive_Permission/setValue/php-google_service_drive_permission-setvalue-method-examples.html
I had the same problem and wasn't able to figure it out using Google API PHP Client methods designed specifically for altering permissions. However, there is a possibility to retrieve a Guzzle instance with the authentication info from PHP Client. Therefore, we can simply call the desired API endpoint to send the request. The code below is a complete workaround for changing file owner/permission on Google Drive:
//if you're using Service Account, otherwise follow your normal authorization
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/json');
$client = new Google_Client();
$client->setScopes(Google_Service_Drive::DRIVE);
$client->useApplicationDefaultCredentials();
//Now the main code to change the file permission begins
$httpClient = $client->authorize(); //It returns a Guzzle instance with proper Headers
$result = $httpClient->request('POST', 'https://www.googleapis.com/drive/v3/files/[FILE_ID]/permissions?transferOwnership=true', [
'json' => [
'role' => 'owner',
'type' => 'user',
'emailAddress' => 'email#example.com'
]
]);
And the sample response of $result->getBody()->getContents() is:
{
"kind": "drive#permission",
"id": "14...",
"type": "user",
"role": "owner"
}
I think you're on the wrong API. Setting permission for files are found in Drive API permissions.
But to answer your question, here's how to create a new spreadsheet using spreadsheets.create from the Sheets API:
<?php
/*
* BEFORE RUNNING:
* ---------------
* 1. If not already done, enable the Google Sheets API
* and check the quota for your project at
* https://console.developers.google.com/apis/api/sheets
* 2. Install the PHP client library with Composer. Check installation
* instructions at https://github.com/google/google-api-php-client.
*/
// Autoload Composer.
require_once __DIR__ . '/vendor/autoload.php';
$client = getClient();
$service = new Google_Service_Sheets($client);
// TODO: Assign values to desired properties of `requestBody`:
$requestBody = new Google_Service_Sheets_Spreadsheet();
$response = $service->spreadsheets->create($requestBody);
// TODO: Change code below to process the `response` object:
echo '<pre>', var_export($response, true), '</pre>', "\n";
function getClient() {
// TODO: Change placeholder below to generate authentication credentials. See
// https://developers.google.com/sheets/quickstart/php#step_3_set_up_the_sample
//
// Authorize using one of the following scopes:
// 'https://www.googleapis.com/auth/drive'
// 'https://www.googleapis.com/auth/spreadsheets'
return null;
}
?>
When the files has been created and saved in your Google Drive, you can now try to set Permissions using the Drive REST API.

PHP - How to access Twilio in a composer namespace environment

I've been working with Rachet WebSockets and created a simple chat application. The example uses a WebSocket namespace. This is my first time using namespace. Now I'm trying to add Twilio service but can seem to add Twilio to my namespace.
I know it is autoloaded in the autoload_files.php
<?php
// autoload_files.php #generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/twilio/sdk/Services/Twilio.php',
);
In the composer.json file
{
"autoload": {
"psr-0": {
"Websocket": "src"
}
},
"require": {
"cboden/ratchet": "^0.3.3",
"twilio/sdk": "^4.5"
}
}
I followed the steps from this website : https://www.twilio.com/docs/libraries/php#using-without-composer
I'm calling twilio inside a method of my class like this:
$AccountSid = "xxxxxxxxxxxxxxxxx";
$AuthToken = "xxxxxxxxxxxxxxxxx";
$client = new Client($sid, $token);
$message = $client->account->messages->create(array(
'To' => "+555555555",
'From' => "+555555555",
'Body' => "This is a test",
));
Keep getting this error: Uncaught Error: Class 'Websocket\Client' not found in ......
I'm very new to composer and namespace, hope this is enough information to help me.
I had to update Twilio,
ran composer require twilio/sd
- Removing twilio/sdk (4.12.0)
- Installing twilio/sdk (5.4.1)
Downloading: 100%
Now I'm able to use Twilio\Rest\Client; since it was missing before.
When using namespaces, PHP will always start looking for classes which aren't prepended with their own namespace in the current one.
In your case the current namespace would be Websocket, thus PHP is trying to autoload the class Websocket\Client, to prevent this, you have two options :
1) Tell PHP where to look by using use :
use Twilio\Rest\Client;
2) Prepend the correct namespace
$client = new \Twilio\Rest\Client($sid, $token);

Using AdWords BatchJob in PHP

I'm trying to get new BatchJob (https://developers.google.com/adwords/api/docs/guides/batch-jobs) up and running, however missing one part.
Docs says:
The good news is that your client library of choice will have a
utility that handles constructing and sending the request for you. The
example below uses the BatchJobHelper utility from the Java client
library.
However PHP library is missing that Helper and any method that should do that...
Anyone had any luck sending request to API using BatchJob? I can't find any working example anywhere.
Thanks!
In the branch experimental they are rewriting the API. It seems that the BatchJobHelper is missing still (current day of write this), see my issue in github requesting it.
For get BatchJobs you should use the BatchJobService class, which is instantiated from the adword service. This is a example snippet:
$batch_job_service = $adWordsServices->get($session, 'BatchJobService', 'v201605', 'cm');
try
{
/** #var BatchJobReturnValue $result */
$result = $batch_job_service->mutate($operations);
}
catch(ApiException $e)
{
echo $e->getMessage() . PHP_EOL;
}
if(!empty($result) && $result instanceof Google\AdsApi\AdWords\v201605\cm\BatchJobReturnValue)
{
$batch_job = reset($result->getValue());
}
else
{
echo 'Result is empty or no valid';
}
If you are using composer to load the new v201603 version of adwords you will need to also adjust your composer file to map the utils since they are duplicated across the other versions for some reason.. Not sure why they did this. you should be able to find the class you need with the following path. Hope this helps.
{
"require": {
"googleads/googleads-php-lib": "8.3.0"
},
"autoload": {
"classmap": [
"vendor/googleads/googleads-php-lib/src/Google/Api/Ads/AdWords/Util/v201601"
]
}
}

Categories