Completed
Push — master ( 29dd4a...211d70 )
by Joseph
11:41
created

Adapter::pathExists()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
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 Illuminate\Support\Str;
10
use STS\StorageConnect\Drivers\AbstractAdapter;
11
use STS\StorageConnect\Models\Quota;
12
use StorageConnect;
13
use STS\StorageConnect\UploadRequest;
14
use STS\StorageConnect\UploadResponse;
15
16
class Adapter extends AbstractAdapter
17
{
18
    /**
19
     * @var string
20
     */
21
    protected $driver = "google";
22
23
    /**
24
     * @var string
25
     */
26
    protected $providerClass = Provider::class;
27
28
    /**
29
     * @param $user
30
     *
31
     * @return array
32
     */
33
    protected function mapUserDetails($user)
34
    {
35
        return [
36
            'name'  => $user->name,
37
            'email' => $user->email,
38
        ];
39
    }
40
41
    /**
42
     * @return Quota
43
     */
44
    public function getQuota()
45
    {
46
        $about = $this->service()->about->get();
47
48
        return new Quota($about->getQuotaBytesTotal(), $about->getQuotaBytesUsed());
49
    }
50
51
    /**
52
     * @return Google_Service_Drive
53
     */
54
    protected function makeService()
55
    {
56
        $client = new Google_Client([
57
            'client_id'     => $this->config['client_id'],
58
            'client_secret' => $this->config['client_secret']
59
        ]);
60
61
        $client->setApplicationName(
62
            config('storage-connect.app_name', config('app.name'))
63
        );
64
65
        $client->setAccessToken($this->token);
66
67
        if ($client->isAccessTokenExpired()) {
68
            $this->updateToken($client->refreshToken($client->getRefreshToken()));
69
        }
70
71
        return new Google_Service_Drive($client);
72
    }
73
74
    /**
75
     * @param UploadRequest $request
76
     *
77
     * @return string
78
     *
79
     */
80
    public function upload( UploadRequest $request )
81
    {
82
        $file = $this->prepareFile($request->getDestinationPath());
83
        list($filesize, $mimeType) = $this->stat($request->getSourcePath());
84
85
        if ($filesize >= 5 * 1024 * 1024) {
86
            return $this->uploadChunked($request->getSourcePath(), $file, $filesize);
87
        }
88
89
        return $this->service()->files->create($file, [
90
            'data'       => file_get_contents($request->getSourcePath()),
91
            'mimeType'   => $mimeType,
92
            'uploadType' => 'media',
93
        ])->id;
94
    }
95
96
    /**
97
     * @param $destinationPath
98
     *
99
     * @return Google_Service_Drive_DriveFile
100
     */
101
    protected function prepareFile( $destinationPath )
102
    {
103
        $folderId = $this->getFolderIdForPath(StorageConnect::appName() . "/" . dirname($destinationPath));
104
105
        return new Google_Service_Drive_DriveFile([
106
            'name'    => basename($destinationPath),
107
            'parents' => [$folderId],
108
        ]);
109
    }
110
111
    /**
112
     * @param $sourcePath
113
     *
114
     * @return array
115
     */
116
    protected function stat( $sourcePath )
117
    {
118
        if (Str::startsWith($sourcePath, "http")) {
119
            $headers = array_change_key_case(get_headers($sourcePath, 1));
120
            return [$headers['content-length'], $headers['content-type']];
121
        }
122
123
        return [filesize($sourcePath), mime_content_type($sourcePath)];
124
    }
125
126
    /**
127
     * @param $path
128
     *
129
     * @return mixed
130
     */
131
    protected function getFolderIdForPath( $path )
132
    {
133
        return $this->prepareFolderTree(
134
            array_filter(explode("/", $path))
135
        );
136
    }
137
138
    /**
139
     * @param                                $sourcePath
140
     * @param Google_Service_Drive_DriveFile $file
141
     * @param                                $filesize
142
     *
143
     * @return string
144
     */
145
    protected function uploadChunked( $sourcePath, Google_Service_Drive_DriveFile $file, $filesize )
146
    {
147
        $chunkSize = 2 * 1024 * 1024;
148
149
        $this->service()->getClient()->setDefer(true);
150
        $request = $this->service()->files->create($file);
151
152
        $upload = new Google_Http_MediaFileUpload(
153
            $this->service()->getClient(),
154
            $request,
155
            $file->getMimeType(),
156
            null,
157
            true,
158
            $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...
159
        );
160
        $upload->setFileSize($filesize);
161
162
        $file = false;
163
        $handle = fopen($sourcePath, "rb");
164
165
        while (!$file && !feof($handle)) {
166
            $chunk = fread($handle, $chunkSize);
167
            $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...
168
        }
169
170
        fclose($handle);
171
        $this->service()->getClient()->setDefer(false);
172
173
        return $file->id;
174
    }
175
176
    /**
177
     * @param array  $folders
178
     * @param string $parentFolderId
179
     *
180
     * @return mixed
181
     */
182
    protected function prepareFolderTree( array $folders, $parentFolderId = 'root' )
183
    {
184
        $foldername = array_shift($folders);
185
186
        if (!$folder = $this->folderExists($foldername, $parentFolderId)) {
187
            $fileMetadata = new Google_Service_Drive_DriveFile([
188
                'name'     => $foldername,
189
                'parents'  => [$parentFolderId],
190
                'mimeType' => 'application/vnd.google-apps.folder'
191
            ]);
192
193
            $folder = $this->service()->files->create($fileMetadata, [
194
                'fields' => 'id'
195
            ]);
196
        }
197
198
        return count($folders)
199
            ? $this->prepareFolderTree($folders, $folder->id)
200
            : $folder->id;
201
    }
202
203
    /**
204
     * @param        $name
205
     * @param string $parentFolderId
206
     *
207
     * @return mixed
208
     */
209
    protected function folderExists( $name, $parentFolderId = 'root' )
210
    {
211
        $name = str_replace("'", "", $name);
212
213
        return collect($this->service()->files->listFiles([
214
            'q'      => "mimeType = 'application/vnd.google-apps.folder' and name = '$name' and trashed = false  and '$parentFolderId' in parents",
215
            'spaces' => 'drive',
216
            'fields' => 'files(id, name)',
217
        ]))->first();
218
    }
219
    
220
    public function checkUploadStatus( UploadResponse $response )
221
    {
222
223
    }
224
225
    public function pathExists($remotePath)
226
    {
227
        // stub
228
    }
229
}