Google Analytics service API (ERR_CONNECTION_RESET) - php

IMPORTANT EDIT: Found out that issue is caused by my web server (I don't know how to fix that) - tags changed. I use latest XAMPP.
I am trying to set up server to server connection with Google Analytics API with OAuth following this guide:
Service Applications and Google Analytics API V3: Server-to-server OAuth2 authentication?
I have following code:
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_AnalyticsService.php';
// create client object and set app name
$client = new Google_Client();
$client -> setApplicationName("------------"); // name of your app
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
"------------#developer.gserviceaccount.com", // email you added to GA
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents("-:/-----------/-----/------/----/---------------------------------------------------.p12") // keyfile you downloaded
));
// other settings
$client->setClientId("------------.apps.googleusercontent.com"); // from API console
$client->setAccessType('offline_access'); // this may be unnecessary?
// create service and get data
$service = new Google_AnalyticsService($client);
$ids = "ga:--------";
$startDate = "2013-05-01";
$endDate = "2013-05-26";
$metrics = "ga:visitors";
var_dump($service->data_ga->get($ids, $startDate, $endDate, $metrics));
Which causes HTTP error #101 (ERR_CONNECTION_RESET). My issue is similar to: Service Applications and Google Analytics API V3: Error 101 (net::ERR_CONNECTION_RESET) but I have no other calls to Google_AnalyticsService().
I have PHP version 5.4.7 (XAMPP version) with enabled OpenSSL (enabled via uncommeting line in php.ini).
Thank you in advance for any answers. How to deal with ones like this (producing some HTTP error and stopping? Are there logs that produce any useful informations?)?
EDIT: Copying code from post: "Not sufficient permissions" google analytics API service account to me causes same error (no other messages printed).

I found way to deal with this issue. It's caused by Apache and PHP together - they use different version of OpenSSL.
First workaround (one that does not work for me as I write it 05-28-3013) on XAMPP 1.8.1 (release date 30.9.2012) is to replace files ssleay32.dll and libeay32.dll within Apache /bin/ folder with these from php folder. It does not work for me because mod_ssl can't work with PHP's DLLs.
Second workaround is to install other package. Personally, I switched to ZendServer which has synced versions of OpenSSL and Apache.
Of course you can always build your own Apache and PHP making sure you have OpenSSL and mod_ssl cooperating and in latest version.

Related

Getting started with Google Storage

I am having really difficult time trying to connect Google Storage. All I need is to be able to upload PDF file to a bucket that I've created on Google Storage Console. The documentation seems to be all over the place and lacking simple examples of PHP code. So here's what I've done so far:
Installed cloud storage
$ composer require google/cloud-storage
Added billing as per Google's requirement. Enabled Cloud Storage API. Created project and added a bucket.
Attempted to use the following example:
require '../vendor/autoload.php';
define("PROJECT_ID", "my-project");
define("BUCKET_NAME", "my-bucket");
$client = new Google_Client();
$client->setApplicationName("API_Cloud_Storage");
$client->useApplicationDefaultCredentials();
$client->setScopes(["https://www.googleapis.com/auth/cloud-platform"]);
$service = new Google_Service_Storage($client);
$request = $service->buckets->listBuckets(PROJECT_ID);
foreach ($request["items"] as $bucket)
printf("%s\n", $bucket->getName());
Keep on getting error on
Fatal error: Uncaught Error: Class 'Google_Client' not found in /home/domain/public_html/test.php:11 ...
I know the vendor/autoload.php file is loading because I have no issues with AWS in a different script.
I didn't even pass the first line. What am I missing?
You have the documentation page for Cloud Storage Client Libraries with a PHP sample and detailed instructions. There's also a link to the GitHub repo for that quickstart, in addition to the one shared by ceejayoz in the comments.

Access Google Cloud Storage from Local Env PHP

I am just trying to do a very simple file_get_contents('gs://[bucket][file]');
I am getting this error when I run locally.
"\google\appengine\ext\cloud_storage_streams\CloudStorageStreamWrapper::stream_open" call failed.
However, when I run it on my production env it works fine.
I know I am missing something with the setup, and I am just not sure what.
I have set the project gcloud config set project PROJECT_ID, set the account gcloud config set account ACCOUNT, and run gcloud auth login. Any ideas on what I am missing in my setup here?
I ran composer install , composer require google/cloud, I don't get any errors when including use Google\Cloud\Storage\StorageClient; I created the service-account-keyfile as an owner of the bucket. Set owners to full permissions. Ran this code...
require __DIR__ . '/vendor/autoload.php';
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient([
'keyFilePath' => __DIR__ .'/../keys/appdocs-com.json',
]);
echo file_get_contents('gs://[myBucket][myFile]');
and I am still getting ...streamWrapper::stream_open" call failed
I even tried the service builder approach.
require __DIR__ . '/vendor/autoload.php';
use Google\Cloud\ServiceBuilder;
use Google\Cloud\Storage\StorageClient;
$gcloud = new ServiceBuilder([
'keyFilePath' => __DIR__ .'/../keys/appdocs-com.json',
'projectId' => 'appdocs-com',
]);
$storage = $gcloud->storage();
$bucket = $storage->bucket('test-appdocs-sendgrid-inbound');
$object = $bucket->object('4/envelope.json');
$stream = $object->downloadAsStream();
echo $stream->getContents();
this returns
Fatal error: Uncaught exception 'Google\Cloud\Core\Exception\ServiceException' with message 'No system CA bundle could be found in any of the the common system locations. PHP versions earlier than 5.6 are not properly configured to use the system's CA bundle by default. In order to verify peer certificates, you will need to supply the path on disk to a certificate bundle to the 'verify' request option: http://docs.guzzlephp.org/en/latest/clients.html#verify. If you do not need a specific certificate bundle, then Mozilla provides a commonly used CA bundle which can be downloaded here (provided by the maintainer of cURL): https://raw.githubusercontent.com/bagder/ca-bundle/master/ca-bundle.crt. Once you have a CA bundle available on disk, you can set the 'openssl.cafile' PHP ini setting to point to the path to the file, allowing you to omit the 'verify' request option. See http://curl.haxx.se/docs/sslcerts.html for more information.' in /Users/thom/Engine/appdocs-com/vendor/google/cloud-core/RequestWrapper.php:241 Stack trac in /Users/thom/Engine/appdocs-com/vendor/google/cloud-core/RequestWrapper.php on line 241
I have my runtime at php55. Could that be preventing me from using StorageClient or serviceBuilder
When outside the appengine environment, you will need to manually register the cloud storage stream wrapper to access files using the gs:// protocol:
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient([
'keyFilePath' => '/path/to/service-account-keyfile.json'
]);
$storage->registerStreamWrapper();
This example assumes you have Google Cloud PHP installed.
More information is available in the Google Cloud PHP docs.
To resolve the guzzle ssh error, refer to this answer. NOTE that setting verify to false is not safe, and should only be used to test, never in production.
As #jdp mentioned in his answer, the error I was getting was related to my installation of curl.
So I looked at Google's php_ini docs to see if I could set the openssl.cafile. https://cloud.google.com/appengine/docs/standard/php/config/php_ini
If you want to use Google Storage Client you need to change from standard to flexible env.
https://cloud.google.com/appengine/docs/flexible/php/quickstart
Then read through cloud storage docs to see how to download dependencies for the API usage: https://cloud.google.com/storage/docs/reference/libraries
Once you have set up your flex env and gathered dependencies, you can then follow these directions to set up the connection.
Set up a service account key In Google Cloud Console:
Select "your-project"->IAM & ADMIN-> Service Accounts.
Click the "Create Service Account" button.
Assign role (in my case I assigned the role "owner" since this service account was specific to my local development), mark the checkbox "Furnish New Private Key".
This just downloaded your "service-account-keyfile.json"
Then in the code initiate Cloud Storage like so:
use Google\Cloud\Storage\StorageClient;
$storage = new StorageClient([
'keyFilePath' => '/path/to/service-account-keyfile.json'
]);
$storage->registerStreamWrapper();
You can now retrieve bucket data like you would from the production env.
echo file_get_contents('gs://[Bucket][File]');
Make sure you have set the bucket permissions to allow the previously selected role to access the bucket.
However, I would still love to find a way to set up a local environment with with php standard that can interact with gs://[bucket]/[file].

Class not found in Google Cloud app

I am getting the following error:
Fatal error: Class 'Google\Cloud\Datastore\DatastoreClient' not found in /base/data/home/apps/e~brookes-room-usage/1.3998538263957262‌​38/record-usage.php on line 84
so presumably I have failed to point my app correctly to that class.
I have enabled the Datastore API on the cloud console.
I have tried to find documentation relating to how to set up a PHP connection to the Datastore API.
I tried to create a settings.yml file using the instructions here but I didn't know what my client ID or my client secret were.
# Google credentials and configuration
google_client_id: YOUR_CLIENT_ID
google_client_secret: YOUR_CLIENT_SECRET
google_project_id: YOUR_PROJECT_ID
# options are "cloudsql", "mongodb", or "datastore"
bookshelf_backend: datastore
(source on Github)
What do I need to get my PHP app on Google Cloud to recognise Google\Cloud\Datastore\DatastoreClient and connect to the Datastore API so that I can retrieve and post data?
I think you forgot to include google/cloud-datastore library. Install via composer as below.
$ composer require google/cloud-datastore
and you can use as below.
<?php
require 'vendor/autoload.php';
use Google\Cloud\Datastore\DatastoreClient;
$datastore = new DatastoreClient([
'projectId' => 'my_project'
]);
// Create an entity
$bob = $datastore->entity('Person');
$bob['firstName'] = 'Bob';
$bob['email'] = 'bob#example.com';
$datastore->insert($bob);
// Update the entity
$bob['email'] = 'bobV2#example.com';
$datastore->update($bob);
// If you know the ID of the entity, you can look it up
$key = $datastore->key('Person', '12345328897844');
$entity = $datastore->lookup($key);
More details: https://github.com/GoogleCloudPlatform/google-cloud-php#google-cloud-datastore-ga
I am already using this and working fine for me.
So it turns out that you can only run PHP with Datastore on a Google Cloud app on your local device, not on Google Appengine, unless you use a third-party library.
Which is why I am now writing my app in Python instead.
(Update: this may no longer be the case. This answer was written in 2017.)

Google Calendar API with a Service Account Problems

I've been trying for days to get Google's Calendar PHP API working on my local Laravel development site. Here's the problem:
I'm using a service account so I can perform functions on one calendar (the service accounts calendar). I'm not authenticating users and requesting access to their calendar.
I've verified everything from my client ID, the service email address, the key.P12 file, still nothing happens.
Here is my code:
$key = File::get($this->key);
$credentialObj = new \Google_Auth_AssertionCredentials(
$this->serviceAccountName,
array('https://www.googleapis.com/auth/calendar'),
$key,
'notasecret'
);
$client = new \Google_Client();
$client->setApplicationName($this->applicationName);
$client->setClientId($this->clientId);
$client->setAssertionCredentials($credentialObj);
\session_start();
$calendarServiceObj = new \Google_Service_Calendar($client);
$events = $calendarServiceObj->events->listEvents('mygmail#gmail.com');
dd($events->getItems());
I've even tried using Google's own example here:
https://github.com/google/google-api-php-client/blob/master/examples/service-account.php
No errors, nothing. Just a blank error page every single time. I've tried so many examples all over the internet, even here on stack overflow, and at the end, all I get is a 'This webpage is not available'. This happens on every browser.
Laravel is set to development mode so all errors are displayed, and I've even force set the ini using ini_set("display_errors", 1);.
I know everything works fine up until I request anything from the service object. All the calendar api's are set to on in my developer account. Does my local development domain need to have SSL enabled?
It be so nice if I could figure out at least what is going on, but with this obscure error, I have no idea.
If anyone has any tips, I'd really appreciate it. Thanks!!
EDIT: I've scoured through googles API code, and this is exactly where the request fails:
vendor\google\apiclient\src\Google\Signer\P12.php
Line 77 to 92:
public function sign($data)
{
if (version_compare(PHP_VERSION, '5.3.0') < 0) {
throw new Google_Auth_Exception(
"PHP 5.3.0 or higher is required to use service accounts."
);
}
$hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256";
//If I die(); here, I receive the response
if (!openssl_sign($data, $signature, $this->privateKey, $hash)) {
//Something happens here, or inside the openssl_sign command, I never reach the exception
throw new Google_Auth_Exception("Unable to sign data");
}
//It never reaches here
return $signature;
}
In my PHP Info:
Solved by updating PHP. I was using Softaculous AMPPs 2.3 with PHP 5.4.27. Upgrading to AMPPs 2.6 fixed the issue. My Open SSL in my config is now:
Nothing was done to my code above since, and it now works. This was definitely an open ssl issue. Anyone receiving an ERR_CONNECTION_RESET must update their open_ssl version.
I hope this helps anyone trying to figure this out.

PHP SoapClient not working - no error

I have some code that connects to a newsletter service via SOAP. It works with no problem on our dev server, but on our live server it doesn't work at all. It's not returning any errors; just a blank white page. I've put some error_logs into the code and found exactly where it stops working - on the line creating the new SoapClient. Is there some kind of server config that needs to be set? Our code is identical between dev and prod, so the only thing I can figure is a server issue. (Note that the first chunk of code below was provided by the newsletter service, not written by me.)
# bronto API session/connection setup
ini_set("soap.wsdl_cache_enabled", "0");
date_default_timezone_set('America/Chicago');
$wsdl = "https://api.bronto.com/v4?wsdl";
$url = "https://api.bronto.com/v4";
/*error log statements up to this point return what is expected;
an error log after the following line (starting with $client = new SoapClient)
does not get triggered at all. */
$client = new SoapClient($wsdl, array('trace' => 1, 'encoding' => 'UTF-8'));
$client->__setLocation($url);
$token = "XXX";
$sessionId = $client->login(array("apiToken" => $token))->return;
$client->__setSoapHeaders(array(new SoapHeader("http://api.bronto.com/v4",
'sessionHeader',
array('sessionId' => $sessionId))));
I've also tried something like this to explicitly see any errors, but no luck - still nothing in the error log.
try {
$client = #new SoapClient($wsdl, array('trace' => 1, 'encoding' => 'UTF-8'));
}
catch (SoapFault $E) {
error_log($E->faultstring) ;
}
error_log("ok");
I would check the installed PHP packages on the dev server and compare to the Prod server. fr2.php.net/manual/en/soap.setup.php
This will more than likly be a config setup for php on the live server, but here are the common problems i have had with SOAP on php,
First thing is check the allowed memory for php on live comparable with dev (SOAP is big and bad for memory)
Is the php on the live server the same version as the dev server,
Is the live server authorized to access the SOAP server (if auth is used on an IP Level)
as one of the SOAP packages i have used did this to me i found out there was a version mismatch, last but not least could you tell us what SOAP Library if any other then php default your using so we can help as your code looks good :)
thinking about it have you install soap i don't think php natively supports it i think its a pear or pecl package and if your using XAMPP or easyPHP on dev these have all of both all ready included in php.

Categories