молча не удается отправить изображения на Google Drive пользователя через PHP SDK - PullRequest
0 голосов
/ 31 октября 2018

Я создаю приложение с открытым исходным кодом, в котором пользователь может создавать резервные копии своих альбомов в Facebook на диске Google с помощью PHP SDK. Я закончил с частью Facebook и теперь застрял в ужасно написанной документации Google. Итак, вот как я работаю, шаг за шагом:

аутентификация пользователя: все мои запросы и обратные вызовы обрабатываются в одном PHP-файле, который работает как API. Так что это блок кода, который обрабатывает запрос на загрузку документов в Google:

<?php
session_start();
require_once __DIR__.'/classes/facebook.class.php';
require_once __DIR__.'/classes/drive.class.php';
$fb = new Facebook();
$google = Drive::getInstance();
$query = $_REQUEST['i'];
switch($query){
        case "backup_req":
            $agent = $google->getAgent();
            if(!isset($_SESSION['google_access_token'])){
                $_SESSION['album_temp'] = $_REQUEST['album'];
                header("location: ".filter_var($agent->createAuthUrl(), FILTER_SANITIZE_URL));
            } else{
                $google->uploadAlbum($fb, $_REQUEST['album']);
            }
        break;
        case "google_callback":
            $agent = $google->getAgent();
            if(!isset($_SESSION['google_access_token'])){
                $code = $_GET['code']; // just to keep the code neat.. no need to store in other var!
                $res = $google->getAgent()->authenticate($code); // hope this works
                $_SESSION['google_access_token'] = $agent->getAccessToken();
            }
            $google->uploadAlbum($fb, $_SESSION['album_temp']);
        break;
}

Вот что я пытаюсь сделать, если в сеансе нет маркера доступа Google, мы перенаправляем пользователя на страницу входа Google. который после завершения перенаправляет в тот же файл, но на этот раз запрашивая google_callback вместе с кодом. Затем он сохраняется в сеансе, и мы переходим к методу uploadAlbum.

ПРИМЕЧАНИЕ. Я повторил содержимое сервера, и да, я получил токен доступа и обновил токен

Теперь для загрузки альбома есть 4 метода в классе Drive, который является одиночным. вот код:

    class Drive{
    private static $instance;
    private $fileRequest;
    private $mimeType;
    private $filename;
    private $path;
    private $client;
    private $clientId = "<client-id>";
    private $clientSecret = "<client-secret>";
    private final function __construct(){
        $this->client = new Google_Client();
        $this->client->setApplicationName("fb album backup tool");
        $this->client->setClientId($this->clientId);
        $this->client->setClientSecret($this->clientSecret);
        $this->client->setRedirectUri("https://fbrtc.sameer-manek.com/fb_caller.php?i=google_callback");
        $this->client->setScopes(array('https://www.googleapis.com/auth/drive.file'));
        $this->client->setAccessType("offline");
        $this->client->setApprovalPrompt('force');
    }
    public static function getInstance(){
        if(self::$instance == null) {
            self::$instance = new Drive();
        }
        return self::$instance;
    }
    public function getAgent(){
        return $this->client;
    }
    public function uploadAlbum($fb, $album){
            $nodes = $fb->get_photos($album);
            $client = new GearmanClient();
            $client->addServer();
            foreach ($nodes as $node) {
                //$client->addTask('init', $node['picture']);
                try{
                    $data = file_get_contents($node['picture']);
                    $saveto = __DIR__."/../scripts/tmp/".rand().".jpg";
                    $file = fopen($saveto, "w+");
                    fwrite($file, $data);
                    fclose($file);
                    $this->init($saveto);
                    echo "uploaded ".$saveto."\n";
                } catch(Exception $e) {
                    return false;
                }

            }
            return true;
            //$client->runTasks();
    }
    public function init($file){
        $at = $_SESSION['google_access_token']['access_token'];
        $this->client->setAccessToken($at);
        $this->fileRequest = $file;
        $client = $this->client;
        //$client->refreshToken($_SESSION['google_access_token']['refreshToken']);
        $tokens = $client->getAccessToken();
        $client->setAccessToken($tokens);
        $client->setDefer(true);
        $this->client->setAccessToken($at);
        $this->processFile();
    }
    public function processFile(){
        $fileRequest = $this->fileRequest;
        $path_parts = pathinfo($this->fileRequest);
        $this->path = $path_parts['dirname'];
        $this->fileName = $path_parts['basename'];
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $this->mimeType = finfo_file($finfo, $fileRequest);
        finfo_close($finfo);
        $this->upload();
    }
    public function upload(){
        $client = $this->client;
        $service = new Google_Service_Drive($this->client);
        //Insert a file
        $file = new Google_Service_Drive_DriveFile();
        $file->setName($this->fileName.'.jpg');
        $file->setDescription('A test document');
        $file->setMimeType('image/jpeg');
        $data = file_get_contents($this->fileRequest);
        $createdFile = $service->files->create($file, array(
              'data' => $data,
              'mimeType' => 'image/jpeg',
              'uploadType' => 'multipart'
        ));
    }
}

uploadAlbum() метод извлечения изображений из запрошенного альбома. init() метод готовит объект для загрузки этого изображения (здесь мы используем маркер назначения доступа к объекту) processFile() метод извлечения и хранения информации об изображении. upload() метод на самом деле загружает изображение на Google Drive пользователя.

после того, как это было выполнено, не генерируются никакие исключения, ни генерируется какая-либо ошибка, но изображение не загружается на диск при перекрестной проверке.

Я не могу точно определить, в чем проблема, пожалуйста, помогите мне решить эту ошибку. Спасибо.

[РЕДАКТИРОВАТЬ] Я var_dumped содержимое $createdFile, и он вывел на экран следующее:

object(GuzzleHttp\Psr7\Request)#73 (7) { ["method":"GuzzleHttp\Psr7\Request":private]=> string(4) "POST" ["requestTarget":"GuzzleHttp\Psr7\Request":private]=> NULL ["uri":"GuzzleHttp\Psr7\Request":private]=> object(GuzzleHttp\Psr7\Uri)#69 (7) { ["scheme":"GuzzleHttp\Psr7\Uri":private]=> string(5) "https" ["userInfo":"GuzzleHttp\Psr7\Uri":private]=> string(0) "" ["host":"GuzzleHttp\Psr7\Uri":private]=> string(18) "www.googleapis.com" ["port":"GuzzleHttp\Psr7\Uri":private]=> NULL ["path":"GuzzleHttp\Psr7\Uri":private]=> string(22) "/upload/drive/v3/files" ["query":"GuzzleHttp\Psr7\Uri":private]=> string(20) "uploadType=multipart" ["fragment":"GuzzleHttp\Psr7\Uri":private]=> string(0) "" } ["headers":"GuzzleHttp\Psr7\Request":private]=> array(3) { ["Host"]=> array(1) { [0]=> string(18) "www.googleapis.com" } ["content-type"]=> array(1) { [0]=> string(37) "multipart/related; boundary=344323595" } ["X-Php-Expected-Class"]=> array(1) { [0]=> string(30) "Google_Service_Drive_DriveFile" } } ["headerNames":"GuzzleHttp\Psr7\Request":private]=> array(3) { ["content-type"]=> string(12) "content-type" ["host"]=> string(4) "Host" ["x-php-expected-class"]=> string(20) "X-Php-Expected-Class" } ["protocol":"GuzzleHttp\Psr7\Request":private]=> string(3) "1.1" ["stream":"GuzzleHttp\Psr7\Request":private]=> object(GuzzleHttp\Psr7\Stream)#67 (7) { ["stream":"GuzzleHttp\Psr7\Stream":private]=> resource(11) of type (stream) ["size":"GuzzleHttp\Psr7\Stream":private]=> NULL ["seekable":"GuzzleHttp\Psr7\Stream":private]=> bool(true) ["readable":"GuzzleHttp\Psr7\Stream":private]=> bool(true) ["writable":"GuzzleHttp\Psr7\Stream":private]=> bool(true) ["uri":"GuzzleHttp\Psr7\Stream":private]=> string(10) "php://temp" ["customMetadata":"GuzzleHttp\Psr7\Stream":private]=> array(0) { } } } uploaded /sites/facebook_backup/classes/../scripts/tmp/264708337.jpg

вот ссылка на репозиторий GitHub для справки.

...