Search code examples
phpgoogle-apigoogle-oauthgoogle-plusgoogle-api-php-client

How to specify fields for $plus->people->get('me') call?


With Google API PHP client library I use the following code, which works well and prints lot of information about the user, who authorizes my application via OAuth2:

<?php

require_once('google-api-php-client-1.1.7/src/Google/autoload.php');

const TITLE = 'My amazing app';
const REDIRECT = 'https://example.com/myapp/';

session_start();

$client = new Google_Client();
$client->setApplicationName(TITLE);
$client->setClientId('REPLACE_ME.apps.googleusercontent.com');
$client->setClientSecret('REPLACE_ME');
$client->setRedirectUri(REDIRECT);
$client->setScopes(array(Google_Service_Plus::PLUS_ME));
$plus = new Google_Service_Plus($client);

if (isset($_REQUEST['logout'])) {
        unset($_SESSION['access_token']);
}

if (isset($_GET['code'])) {
        if (strval($_SESSION['state']) !== strval($_GET['state'])) {
                error_log('The session state did not match.');
                exit(1);
        }

        $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();
        header('Location: ' . REDIRECT);
}

if (isset($_SESSION['access_token'])) {
        $client->setAccessToken($_SESSION['access_token']);
}

if ($client->getAccessToken() && !$client->isAccessTokenExpired()) {
        try {
                $me = $plus->people->get('me'); # HOW TO SPECIFY FIELDS?
                $body = '<PRE>' . print_r($me, TRUE) . '</PRE>';
        } catch (Google_Exception $e) {
                error_log($e);
                $body = htmlspecialchars($e->getMessage());
        }
        # the access token may have been updated lazily
        $_SESSION['access_token'] = $client->getAccessToken();
} else {
        $state = mt_rand();
        $client->setState($state);
        $_SESSION['state'] = $state;
        $body = sprintf('<P><A HREF="%s">Login</A></P>',
            $client->createAuthUrl());
}

?>

<!DOCTYPE HTML>
<HTML>
<HEAD>
        <TITLE><?= TITLE ?></TITLE>
</HEAD>
<BODY>
        <?= $body ?>
        <P><A HREF="<?= REDIRECT ?>?logout">Logout</A></P>
</BODY>
</HTML>

However I need less info than returned by the above script.

When entering just the fields I am interested in at the People: get "API explorer":

id,gender,name,image,placesLived

screenshot 1

this again works well and prints only the specified fields:

screenshot 2

MY QUESTION:

How to specify the fields in the above $me = $plus->people->get('me'); call?

After studying 1.1.7/src/Google/Service/Plus.php with the code:

/**
 * Get a person's profile. If your app uses scope
 * https://www.googleapis.com/auth/plus.login, this method is 
 * guaranteed to return ageRange and language. (people.get)
 *
 * @param string $userId The ID of the person to get the profile for. The
 * special value "me" can be used to indicate the authenticated user.
 * @param array $optParams Optional parameters.
 * @return Google_Service_Plus_Person
 */
public function get($userId, $optParams = array())
{
  $params = array('userId' => $userId);
  $params = array_merge($params, $optParams);
  return $this->call('get', array($params), "Google_Service_Plus_Person");
}

I have tried the following PHP code:

const FIELDS = 'id,gender,name,image,placesLived';

$me = $plus->people->get('me', array('fields' => urlencode(FIELDS)));

but for some reason it prints a lot of :protected strings:

Google_Service_Plus_Person Object
(
    [collection_key:protected] => urls
    [internal_gapi_mappings:protected] => Array
        (
        )

    [aboutMe] => 
    [ageRangeType:protected] => Google_Service_Plus_PersonAgeRange
    [ageRangeDataType:protected] => 
    [birthday] => 
    [braggingRights] => 
    [circledByCount] => 
    [coverType:protected] => Google_Service_Plus_PersonCover
    [coverDataType:protected] => 
    [currentLocation] => 
    [displayName] => 
    [domain] => 
    [emailsType:protected] => Google_Service_Plus_PersonEmails
    [emailsDataType:protected] => array
    [etag] => 
    [gender] => male
    ...

Also I have tried just appending the fields after me:

$me = $plus->people->get('me?fields=' . urlencode(FIELDS)));

but get the 404 error:

Error calling GET https://www.googleapis.com/plus/v1/people/me%3Ffields%3Did%252Cgender%252Cname%252Cimage%252CplacesLived: (404) Not Found

UPDATE: I have created Issue #948 at GitHUb.


Solution

  • To specify which fields to get from the G+ API, you just have to specify a fields member in the options array. So actually you got very close to the solution:

    $me = $plus->people->get('me', array('fields' => 'id,gender,name,image,placesLived'));
    

    You don't even have to urlencode, as it is a default safety feature of the library itself.

    The thing that might have tricked you is, that the Google_Service_Plus_Person class contains all the possible fields a protected members, not regarding the actual fields that were sent by the API. Not included fields will be empty in the object. As always, protected members should not be used in any way by the user of the class.

    You, as the user of the library should only use public members, such as $me->getPlacesLived() and $me->getId(). Dumping whole objects is a nice tool during development, but in production calling the public interface is the way to go.