3

I want to use My Google drive for storing my files which users will upload on my website. Here is the code what I am using so far.

<!-- this is my index.php-->
<?php
ob_start();
error_reporting(E_ALL);
 ini_set('display_errors', '1');
require("functions.php");
session_start();
header('Content-Type: text/html; charset=utf-8');
$authUrl = getAuthorizationUrl("", "");
?>
<!DOCTYPE html>
<html lang="fi">
<head>
    <title>Google Drive Login and Upload</title>
    <meta charset="UTF-8">
</head>
<body>
<a href=<?php echo "'" . $authUrl . "'" ?>>Authorize</a>
</body>
</html>


<!--This is my fileUpload.php-->
<?php
ob_start();
require_once("functions.php");
session_start();

header('Content-Type: text/html; charset=utf-8');

global $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI;
$client = new Google_Client();
$client->setClientId($CLIENT_ID);
$client->setClientSecret($CLIENT_SECRET);
$client->setRedirectUri($REDIRECT_URI);
$client->setScopes('email');

$authUrl = $client->createAuthUrl();    
getCredentials($_GET['code'], $authUrl);

$userName = $_SESSION["userInfo"]["name"];
$userEmail = $_SESSION["userInfo"]["email"];

?>
<!DOCTYPE html>
<html lang="fi">
<head>
    <title>Logged in</title>
    <meta charset="UTF-8">
</head>
<body>

    Hello <?php echo $userName; ?>!
    <br>
    <?php echo $userEmail; ?>

    <br><br><br>

    <form enctype="multipart/form-data" action="formAction.php" method="POST">
        <input type="file" name="file" required>
        <br><br>
        <label for="folderName">Folder name, this either uploads file to an existing folder or creates a new one based on the name</label>
        <br>
        <input type="text" name="folderName" placeholder="My cat Whiskers">

        <br><br>
        <input type="submit" name="submit" value="Upload to Drive">
    </form>

</body>
</html>

<!-- this is my formaction.php where the action goes after submitting the file upload form-->
<?php
require_once 'google-api-php-client/src/Google/Client.php';
require_once 'google-api-php-client/src/Google/Service/Oauth2.php';
require_once 'google-api-php-client/src/Google/Service/Drive.php';
session_start();

header('Content-Type: text/html; charset=utf-8');

// Init the variables
$driveInfo = "";
$folderName = "";
$folderDesc = "";

// Get the file path from the variable
$file_tmp_name = $_FILES["file"]["tmp_name"];

// Get the client Google credentials
$credentials = $_COOKIE["credentials"];

// Get your app info from JSON downloaded from google dev console
$json = json_decode(file_get_contents("composer.json"), true);
$CLIENT_ID = $json['web']['client_id'];
$CLIENT_SECRET = $json['web']['client_secret'];
$REDIRECT_URI = $json['web']['redirect_uris'][0];

// Create a new Client
$client = new Google_Client();
$client->setClientId($CLIENT_ID);
$client->setClientSecret($CLIENT_SECRET);
$client->setRedirectUri($REDIRECT_URI);
$client->addScope(
    "https://www.googleapis.com/auth/drive", 
    "https://www.googleapis.com/auth/drive.appfolder");

// Refresh the user token and grand the privileges
$client->setAccessToken($credentials);
$service = new Google_Service_Drive($client);

// Set the file metadata for drive
$mimeType = $_FILES["file"]["type"];
$title = $_FILES["file"]["name"];
$description = "Uploaded from your very first google drive application!";

// Get the folder metadata
if (!empty($_POST["folderName"]))
    $folderName = $_POST["folderName"];
if (!empty($_POST["folderDesc"]))
    $folderDesc = $_POST["folderDesc"];

// Call the insert function with parameters listed below
$driveInfo = insertFile($service, $title, $description, $mimeType, $file_tmp_name, $folderName, $folderDesc);

/**
* Get the folder ID if it exists, if it doesnt exist, create it and return the ID
*
* @param Google_DriveService $service Drive API service instance.
* @param String $folderName Name of the folder you want to search or create
* @param String $folderDesc Description metadata for Drive about the folder (optional)
* @return Google_Drivefile that was created or got. Returns NULL if an API error occured
*/
function getFolderExistsCreate($service, $folderName, $folderDesc) {
    // List all user files (and folders) at Drive root
    $files = $service->files->listFiles();
    $found = false;

    // Go through each one to see if there is already a folder with the specified name
    foreach ($files['items'] as $item) {
        if ($item['title'] == $folderName) {
            $found = true;
            return $item['id'];
            break;
        }
    }

    // If not, create one
    if ($found == false) {
        $folder = new Google_Service_Drive_DriveFile();

        //Setup the folder to create
        $folder->setTitle($folderName);

        if(!empty($folderDesc))
            $folder->setDescription($folderDesc);

        $folder->setMimeType('application/vnd.google-apps.folder');

        //Create the Folder
        try {
            $createdFile = $service->files->insert($folder, array(
                'mimeType' => 'application/vnd.google-apps.folder',
                ));

            // Return the created folder's id
            return $createdFile->id;
        } catch (Exception $e) {
            print "An error occurred: " . $e->getMessage();
        }
    }
}

/**
 * Insert new file in the Application Data folder.
 *
 * @param Google_DriveService $service Drive API service instance.
 * @param string $title Title of the file to insert, including the extension.
 * @param string $description Description of the file to insert.
 * @param string $mimeType MIME type of the file to insert.
 * @param string $filename Filename of the file to insert.
 * @return Google_DriveFile The file that was inserted. NULL is returned if an API error occurred.
 */
function insertFile($service, $title, $description, $mimeType, $filename, $folderName, $folderDesc) {
    $file = new Google_Service_Drive_DriveFile();

    // Set the metadata
    $file->setTitle($title);
    $file->setDescription($description);
    $file->setMimeType($mimeType);

    // Setup the folder you want the file in, if it is wanted in a folder
    if(isset($folderName)) {
        if(!empty($folderName)) {
            $parent = new Google_Service_Drive_ParentReference();
            $parent->setId(getFolderExistsCreate($service, $folderName, $folderDesc));
            $file->setParents(array($parent));
        }
    }
    try {
        // Get the contents of the file uploaded
        $data = file_get_contents($filename);

        // Try to upload the file, you can add the parameters e.g. if you want to convert a .doc to editable google format, add 'convert' = 'true'
        $createdFile = $service->files->insert($file, array(
            'data' => $data,
            'mimeType' => $mimeType,
            'uploadType'=> 'multipart'
            ));

        // Return a bunch of data including the link to the file we just uploaded
        return $createdFile;
    } catch (Exception $e) {
        print "An error occurred: " . $e->getMessage();
    }
}

echo "<br>Link to file: " . $driveInfo["alternateLink"];

?>

The Problem I getting is, When a user upload a file it doesn't come to my google drive But it goes to that user's Drive. :( What I do not want. I want to store that file into my Google drive.

Please help!! Thanks.

pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • Have a look at quick start, its straight forward as long as settings are correct. Quick Start is [here](https://developers.google.com/drive/web/quickstart/php) – PM. Aug 11 '15 at 05:21
  • Quick start is what he's already using – pinoyyid Aug 11 '15 at 08:46

2 Answers2

0

If you're successfully uploading files to the user's Google Drive, then congratulations. You're nearly there. The only thing you need to change is how you get the access token. See How do I authorise an app (web or installed) without user intervention? (canonical ?)

Community
  • 1
  • 1
pinoyyid
  • 21,499
  • 14
  • 64
  • 115
  • that linked answer is fine but i added a comment there. don't throw away your current flow. instead of using the playground (as suggested in that link) turn your current flow into an admin-only page that saves the admin refresh token. then all users use that token. beware of rate limit quotas and handle them well (exponential backoff) – Zig Mandel Aug 11 '15 at 14:26
  • do NOT use exponential backoff for rate limit problems. It will kill you – pinoyyid Aug 11 '15 at 15:41
  • a trivial exp. backoff would be ineficient but not one that adapts and retains an optimum delay and doesnt go back to zero on success. ive done it. – Zig Mandel Aug 11 '15 at 15:44
  • adaptive backoff is good, well done. adaptive backoff is not exponential backoff – pinoyyid Aug 11 '15 at 15:50
  • yes I should have mentioned that. its really a combination of both. – Zig Mandel Aug 11 '15 at 15:53
  • there shouldn't be any exponential component whatsoever. Drive flow control uses an internal bucket/token algorithm. Once you've emptied the bucket you simply need to delay each subsequent change call (reads aren't affected) to attempt to match it to the internal token replenishment rate. What this means in practice is you initially backoff for say 2s (experiment to find the best value). If it works, slightly reduce the backoff; if it fails, slightly increase the backoff. – pinoyyid Aug 11 '15 at 15:59
  • @ZigMandel thanks for the reply. can you please tell me how can i achieve that? – user3226995 Aug 12 '15 at 09:27
  • @pinoyyid :many many thanks for the reply. can you please tell me about this point(this is in that link) Include https://developers.google.com/oauthplayground as a valid callback URL – user3226995 Aug 12 '15 at 09:34
-3

Check this out

require_once 'Google/Client.php';
require_once 'Google/Service/Drive.php';

$client = new Google_Client();
// create an app in google and use credential form that app
$client->setClientId('<HERE_YOUR_CLIENT_ID>');
$client->setClientSecret('<HERE_YOUR_CLIENT_SECRET>');
$client->setRedirectUri('<HERE_YOUR_REGISTERED_REDIRECT_URI>');
$client->setScopes(array('https://www.googleapis.com/auth/drive.file'));

session_start();

if (isset($_GET['code']) || (isset($_SESSION['access_token']) && $_SESSION['access_token'])) {
    if (isset($_GET['code'])) {
        $client->authenticate($_GET['code']);
        $_SESSION['access_token'] = $client->getAccessToken();
    } else
        $client->setAccessToken($_SESSION['access_token']);

    $service = new Google_Service_Drive($client);

    //Insert a file
    $file = new Google_Service_Drive_DriveFile();
    $file->setTitle(uniqid().'.jpg');
    $file->setDescription('A test document');
    $file->setMimeType('image/jpeg');

    $data = file_get_contents('a.jpg');

    $createdFile = $service->files->insert($file, array(
          'data' => $data,
          'mimeType' => 'image/jpeg',
          'uploadType' => 'multipart'
    ));

    print_r($createdFile);

} else {
    $authUrl = $client->createAuthUrl();
    header('Location: ' . $authUrl);
    die();
}

Before use this you must have a google app, and the sdk.

Thanks

mizan3008
  • 369
  • 3
  • 17