Completed
Push — master ( d5f261...ed671f )
by Joseph
01:44
created

Adapter::mapUserDetails()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace STS\StorageConnect\Drivers\Google;
4
5
use Google_Client;
6
use Google_Http_MediaFileUpload;
7
use Google_Service_Drive;
8
use Google_Service_Drive_DriveFile;
9
use STS\StorageConnect\Drivers\AbstractAdapter;
10
use STS\StorageConnect\Models\Quota;
11
use StorageConnect;
12
use STS\StorageConnect\UploadRequest;
13
use STS\StorageConnect\UploadResponse;
14
15
class Adapter extends AbstractAdapter
16
{
17
    /**
18
     * @var string
19
     */
20
    protected $driver = "google";
21
22
    /**
23
     * @var string
24
     */
25
    protected $providerClass = Provider::class;
26
27
    /**
28
     * @param $user
29
     *
30
     * @return array
31
     */
32
    protected function mapUserDetails($user)
33
    {
34
        return [
35
            'name'  => $user->name,
36
            'email' => $user->email,
37
        ];
38
    }
39
40
    /**
41
     * @return Quota
42
     */
43
    public function getQuota()
44
    {
45
        $about = $this->service()->about->get();
46
47
        return new Quota($about->getQuotaBytesTotal(), $about->getQuotaBytesUsed());
48
    }
49
50
    /**
51
     * @return Google_Service_Drive
52
     */
53
    protected function makeService()
54
    {
55
        $client = new Google_Client([
56
            'client_id'     => $this->config['client_id'],
57
            'client_secret' => $this->config['client_secret']
58
        ]);
59
60
        $client->setApplicationName(
61
            config('storage-connect.app_name', config('app.name'))
62
        );
63
64
        $client->setAccessToken($this->token);
65
66
        if ($client->isAccessTokenExpired()) {
67
            $this->updateToken($client->refreshToken($client->getRefreshToken()));
68
        }
69
70
        return new Google_Service_Drive($client);
71
    }
72
73
    /**
74
     * @param UploadRequest $request
75
     *
76
     * @return string
77
     *
78
     */
79
    public function upload( UploadRequest $request )
80
    {
81
        $file = $this->prepareFile($request->getDestinationPath());
82
        list($filesize, $mimeType) = $this->stat($request->getSourcePath());
83
84
        if ($filesize >= 5 * 1024 * 1024) {
85
            return $this->uploadChunked($request->getSourcePath(), $file, $filesize);
86
        }
87
88
        return $this->service()->files->create($file, [
89
            'data'       => file_get_contents($request->getSourcePath()),
90
            'mimeType'   => $mimeType,
91
            'uploadType' => 'media',
92
        ])->id;
93
    }
94
95
    /**
96
     * @param $destinationPath
97
     *
98
     * @return Google_Service_Drive_DriveFile
99
     */
100
    protected function prepareFile( $destinationPath )
101
    {
102
        $folderId = $this->getFolderIdForPath(StorageConnect::appName() . "/" . dirname($destinationPath));
103
104
        return new Google_Service_Drive_DriveFile([
105
            'name'    => basename($destinationPath),
106
            'parents' => [$folderId],
107
        ]);
108
    }
109
110
    /**
111
     * @param $sourcePath
112
     *
113
     * @return array
114
     */
115
    protected function stat( $sourcePath )
116
    {
117
        if (starts_with($sourcePath, "http")) {
118
            $headers = array_change_key_case(get_headers($sourcePath, 1));
119
            return [$headers['content-length'], $headers['content-type']];
120
        }
121
122
        return [filesize($sourcePath), mime_content_type($sourcePath)];
123
    }
124
125
    /**
126
     * @param $path
127
     *
128
     * @return mixed
129
     */
130
    protected function getFolderIdForPath( $path )
131
    {
132
        return $this->prepareFolderTree(
133
            array_filter(explode("/", $path))
134
        );
135
    }
136
137
    /**
138
     * @param                                $sourcePath
139
     * @param Google_Service_Drive_DriveFile $file
140
     * @param                                $filesize
141
     *
142
     * @return string
143
     */
144
    protected function uploadChunked( $sourcePath, Google_Service_Drive_DriveFile $file, $filesize )
145
    {
146
        $chunkSize = 2 * 1024 * 1024;
147
148
        $this->service()->getClient()->setDefer(true);
149
        $request = $this->service()->files->create($file);
150
151
        $upload = new Google_Http_MediaFileUpload(
152
            $this->service()->getClient(),
153
            $request,
154
            $file->getMimeType(),
155
            null,
156
            true,
157
            $chunkSize
0 ignored issues
show
Documentation introduced by
$chunkSize is of type integer, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
158
        );
159
        $upload->setFileSize($filesize);
160
161
        $file = false;
162
        $handle = fopen($sourcePath, "rb");
163
164
        while (!$file && !feof($handle)) {
165
            $chunk = fread($handle, $chunkSize);
166
            $file = $upload->nextChunk($chunk);
0 ignored issues
show
Documentation introduced by
$chunk is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
167
        }
168
169
        fclose($handle);
170
        $this->service()->getClient()->setDefer(false);
171
172
        return $file->id;
173
    }
174
175
    /**
176
     * @param array  $folders
177
     * @param string $parentFolderId
178
     *
179
     * @return mixed
180
     */
181
    protected function prepareFolderTree( array $folders, $parentFolderId = 'root' )
182
    {
183
        $foldername = array_shift($folders);
184
185
        if (!$folder = $this->folderExists($foldername, $parentFolderId)) {
186
            $fileMetadata = new Google_Service_Drive_DriveFile([
187
                'name'     => $foldername,
188
                'parents'  => [$parentFolderId],
189
                'mimeType' => 'application/vnd.google-apps.folder'
190
            ]);
191
192
            $folder = $this->service()->files->create($fileMetadata, [
193
                'fields' => 'id'
194
            ]);
195
        }
196
197
        return count($folders)
198
            ? $this->prepareFolderTree($folders, $folder->id)
199
            : $folder->id;
200
    }
201
202
    /**
203
     * @param        $name
204
     * @param string $parentFolderId
205
     *
206
     * @return mixed
207
     */
208
    protected function folderExists( $name, $parentFolderId = 'root' )
209
    {
210
        $name = str_replace("'", "", $name);
211
212
        return collect($this->service()->files->listFiles([
213
            'q'      => "mimeType = 'application/vnd.google-apps.folder' and name = '$name' and trashed = false  and '$parentFolderId' in parents",
214
            'spaces' => 'drive',
215
            'fields' => 'files(id, name)',
216
        ]))->first();
217
    }
218
    
219
    public function checkUploadStatus( UploadResponse $response )
220
    {
221
222
    }
223
}