Completed
Push — master ( d1be6d...8440b6 )
by Andrey
07:58
created

getSingleBlobUploadThresholdInBytes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * LICENSE: The MIT License (the "License")
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 * https://github.com/azure/azure-storage-php/LICENSE
8
 *
9
 * Unless required by applicable law or agreed to in writing, software
10
 * distributed under the License is distributed on an "AS IS" BASIS,
11
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
 * See the License for the specific language governing permissions and
13
 * limitations under the License.
14
 *
15
 * PHP version 5
16
 *
17
 * @category  Microsoft
18
 * @package   MicrosoftAzure\Storage\Blob
19
 * @author    Azure Storage PHP SDK <[email protected]>
20
 * @copyright 2016 Microsoft Corporation
21
 * @license   https://github.com/azure/azure-storage-php/LICENSE
22
 * @link      https://github.com/azure/azure-storage-php
23
 */
24
25
namespace MicrosoftAzure\Storage\Blob;
26
27
use MicrosoftAzure\Storage\Common\Internal\ServiceRestTrait;
28
use MicrosoftAzure\Storage\Common\Internal\Http\HttpFormatter;
29
use MicrosoftAzure\Storage\Common\Internal\Utilities;
30
use MicrosoftAzure\Storage\Common\Internal\Resources;
31
use MicrosoftAzure\Storage\Common\Internal\Validate;
32
use MicrosoftAzure\Storage\Common\Internal\ServiceRestProxy;
33
use MicrosoftAzure\Storage\Common\LocationMode;
34
use MicrosoftAzure\Storage\Common\Models\Range;
35
use MicrosoftAzure\Storage\Blob\Internal\IBlob;
36
use MicrosoftAzure\Storage\Blob\Models\AppendBlockOptions;
37
use MicrosoftAzure\Storage\Blob\Models\AppendBlockResult;
38
use MicrosoftAzure\Storage\Blob\Models\BlobServiceOptions;
39
use MicrosoftAzure\Storage\Blob\Models\ListContainersOptions;
40
use MicrosoftAzure\Storage\Blob\Models\ListContainersResult;
41
use MicrosoftAzure\Storage\Blob\Models\CreateContainerOptions;
42
use MicrosoftAzure\Storage\Blob\Models\GetContainerPropertiesResult;
43
use MicrosoftAzure\Storage\Blob\Models\GetContainerACLResult;
44
use MicrosoftAzure\Storage\Blob\Models\ListBlobsOptions;
45
use MicrosoftAzure\Storage\Blob\Models\ListBlobsResult;
46
use MicrosoftAzure\Storage\Blob\Models\BlobType;
47
use MicrosoftAzure\Storage\Blob\Models\Block;
48
use MicrosoftAzure\Storage\Blob\Models\CreateBlobOptions;
49
use MicrosoftAzure\Storage\Blob\Models\BlobProperties;
50
use MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesOptions;
51
use MicrosoftAzure\Storage\Blob\Models\GetBlobPropertiesResult;
52
use MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesOptions;
53
use MicrosoftAzure\Storage\Blob\Models\SetBlobPropertiesResult;
54
use MicrosoftAzure\Storage\Blob\Models\GetBlobMetadataOptions;
55
use MicrosoftAzure\Storage\Blob\Models\GetBlobMetadataResult;
56
use MicrosoftAzure\Storage\Blob\Models\SetBlobMetadataResult;
57
use MicrosoftAzure\Storage\Blob\Models\GetBlobOptions;
58
use MicrosoftAzure\Storage\Blob\Models\GetBlobResult;
59
use MicrosoftAzure\Storage\Blob\Models\DeleteBlobOptions;
60
use MicrosoftAzure\Storage\Blob\Models\LeaseMode;
61
use MicrosoftAzure\Storage\Blob\Models\LeaseResult;
62
use MicrosoftAzure\Storage\Blob\Models\CreateBlobPagesOptions;
63
use MicrosoftAzure\Storage\Blob\Models\CreateBlobPagesResult;
64
use MicrosoftAzure\Storage\Blob\Models\PageWriteOption;
65
use MicrosoftAzure\Storage\Blob\Models\ListPageBlobRangesOptions;
66
use MicrosoftAzure\Storage\Blob\Models\ListPageBlobRangesResult;
67
use MicrosoftAzure\Storage\Blob\Models\CreateBlobBlockOptions;
68
use MicrosoftAzure\Storage\Blob\Models\CommitBlobBlocksOptions;
69
use MicrosoftAzure\Storage\Blob\Models\BlockList;
70
use MicrosoftAzure\Storage\Blob\Models\ListBlobBlocksOptions;
71
use MicrosoftAzure\Storage\Blob\Models\ContainerACL;
72
use MicrosoftAzure\Storage\Blob\Models\ListBlobBlocksResult;
73
use MicrosoftAzure\Storage\Blob\Models\CopyBlobOptions;
74
use MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotOptions;
75
use MicrosoftAzure\Storage\Blob\Models\CreateBlobSnapshotResult;
76
use MicrosoftAzure\Storage\Blob\Models\CopyBlobResult;
77
use MicrosoftAzure\Storage\Blob\Models\BreakLeaseResult;
78
use MicrosoftAzure\Storage\Blob\Models\PutBlockResult;
79
use MicrosoftAzure\Storage\Blob\Models\PutBlobResult;
80
use Psr\Http\Message\StreamInterface;
81
use GuzzleHttp\Promise\PromiseInterface;
82
use GuzzleHttp\Psr7;
83
84
/**
85
 * This class constructs HTTP requests and receive HTTP responses for blob
86
 * service layer.
87
 *
88
 * @category  Microsoft
89
 * @package   MicrosoftAzure\Storage\Blob
90
 * @author    Azure Storage PHP SDK <[email protected]>
91
 * @copyright 2016 Microsoft Corporation
92
 * @license   https://github.com/azure/azure-storage-php/LICENSE
93
 * @link      https://github.com/azure/azure-storage-php
94
 */
95
class BlobRestProxy extends ServiceRestProxy implements IBlob
96
{
97
    use ServiceRestTrait;
98
99
    private $_SingleBlobUploadThresholdInBytes = Resources::MB_IN_BYTES_32;
100
101
    /**
102
     * Get the value for SingleBlobUploadThresholdInBytes
103
     *
104
     * @return int
105
     */
106
    public function getSingleBlobUploadThresholdInBytes()
107
    {
108
        return $this->_SingleBlobUploadThresholdInBytes;
109
    }
110
111
    /**
112
     * Set the value for SingleBlobUploadThresholdInBytes, Max 64MB
113
     *
114
     * @param int $val The max size to send as a single blob block
115
     *
116
     * @return void
117
     */
118
    public function setSingleBlobUploadThresholdInBytes($val)
119
    {
120
        if ($val > Resources::MB_IN_BYTES_64) {
121
            // What should the proper action here be?
122
            $val = Resources::MB_IN_BYTES_64;
123
        } elseif ($val < 1) {
124
            // another spot that could use looking at
125
            $val = Resources::MB_IN_BYTES_32;
126
        }
127
        $this->_SingleBlobUploadThresholdInBytes = $val;
128
    }
129
130
    /**
131
     * Gets the copy blob source name with specified parameters.
132
     *
133
     * @param string                 $containerName The name of the container.
134
     * @param string                 $blobName      The name of the blob.
135
     * @param Models\CopyBlobOptions $options       The optional parameters.
136
     *
137
     * @return string
138
     */
139
    private function _getCopyBlobSourceName(
140
        $containerName,
141
        $blobName,
142
        Models\CopyBlobOptions $options
143
    ) {
144
        $sourceName = $this->_getBlobUrl($containerName, $blobName);
145
146
        if (!is_null($options->getSourceSnapshot())) {
147
            $sourceName .= '?snapshot=' . $options->getSourceSnapshot();
148
        }
149
150
        return $sourceName;
151
    }
152
    
153
    /**
154
     * Creates URI path for blob or container.
155
     *
156
     * @param string $container The container name.
157
     * @param string $blob      The blob name.
158
     *
159
     * @return string
160
     */
161 View Code Duplication
    private function _createPath($container, $blob = '')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
    {
163
        if (empty($blob)) {
164
            if (!empty($container)) {
165
                return $container;
166
            } else {
167
                return '/' . $container;
168
            }
169
        } else {
170
            $encodedBlob = urlencode($blob);
171
            // Unencode the forward slashes to match what the server expects.
172
            $encodedBlob = str_replace('%2F', '/', $encodedBlob);
173
            // Unencode the backward slashes to match what the server expects.
174
            $encodedBlob = str_replace('%5C', '/', $encodedBlob);
175
            // Re-encode the spaces (encoded as space) to the % encoding.
176
            $encodedBlob = str_replace('+', '%20', $encodedBlob);
177
            // Empty container means accessing default container
178
            if (empty($container)) {
179
                return $encodedBlob;
180
            } else {
181
                return '/' . $container . '/' . $encodedBlob;
182
            }
183
        }
184
    }
185
    
186
    /**
187
     * Creates full URI to the given blob.
188
     *
189
     * @param string $container The container name.
190
     * @param string $blob      The blob name.
191
     *
192
     * @return string
193
     */
194
    private function _getBlobUrl($container, $blob)
195
    {
196
        $encodedBlob = $this->_createPath($container, $blob);
197
198
        return (string)($this->getPsrPrimaryUri()->withPath($encodedBlob));
199
    }
200
      
201
    /**
202
     * Helper method to create promise for getContainerProperties API call.
203
     *
204
     * @param string                    $container The container name.
205
     * @param Models\BlobServiceOptions $options   The optional parameters.
206
     * @param string                    $operation The operation string. Should be
207
     * 'metadata' to get metadata.
208
     *
209
     * @return \GuzzleHttp\Promise\PromiseInterface
210
     */
211
    private function _getContainerPropertiesAsyncImpl(
212
        $container,
213
        Models\BlobServiceOptions $options = null,
214
        $operation = null
215
    ) {
216
        Validate::isString($container, 'container');
217
        
218
        $method      = Resources::HTTP_GET;
219
        $headers     = array();
220
        $queryParams = array();
221
        $postParams  = array();
222
        $path        = $this->_createPath($container);
223
        
224
        if (is_null($options)) {
225
            $options = new BlobServiceOptions();
226
        }
227
        
228
        $this->addOptionalQueryParam(
229
            $queryParams,
230
            Resources::QP_REST_TYPE,
231
            'container'
232
        );
233
        $this->addOptionalQueryParam(
234
            $queryParams,
235
            Resources::QP_COMP,
236
            $operation
237
        );
238
239
        $this->addOptionalHeader(
240
            $headers,
241
            Resources::X_MS_LEASE_ID,
242
            $options->getLeaseId()
243
        );
244
        $this->addOptionalAccessConditionHeader(
245
            $headers,
246
            $options->getAccessConditions()
247
        );
248
        
249
        return $this->sendAsync(
250
            $method,
251
            $headers,
252
            $queryParams,
253
            $postParams,
254
            $path,
255
            Resources::STATUS_OK,
256
            Resources::EMPTY_STRING,
257
            $options
258
        )->then(function ($response) {
259
            $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders());
260
            return GetContainerPropertiesResult::create($responseHeaders);
261
        }, null);
262
    }
263
    
264
    /**
265
     * Adds optional create blob headers.
266
     *
267
     * @param CreateBlobOptions $options The optional parameters.
268
     * @param array             $headers The HTTP request headers.
269
     *
270
     * @return array
271
     */
272
    private function _addCreateBlobOptionalHeaders(
273
        CreateBlobOptions $options,
274
        array $headers
275
    ) {
276
        $headers = $this->addOptionalAccessConditionHeader(
277
            $headers,
278
            $options->getAccessConditions()
279
        );
280
        
281
        $this->addOptionalHeader(
282
            $headers,
283
            Resources::X_MS_LEASE_ID,
284
            $options->getLeaseId()
285
        );
286
287
        $headers = $this->addMetadataHeaders(
288
            $headers,
289
            $options->getMetadata()
290
        );
291
292
        $contentType = $options->getContentType();
293
        if (is_null($contentType)) {
294
            $contentType = Resources::BINARY_FILE_TYPE;
295
        }
296
297
        $this->addOptionalHeader(
298
            $headers,
299
            Resources::X_MS_BLOB_CONTENT_TYPE,
300
            $contentType
301
        );
302
        $this->addOptionalHeader(
303
            $headers,
304
            Resources::X_MS_BLOB_CONTENT_ENCODING,
305
            $options->getContentEncoding()
306
        );
307
        $this->addOptionalHeader(
308
            $headers,
309
            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
310
            $options->getContentLanguage()
311
        );
312
        $this->addOptionalHeader(
313
            $headers,
314
            Resources::X_MS_BLOB_CONTENT_MD5,
315
            $options->getContentMD5()
316
        );
317
        $this->addOptionalHeader(
318
            $headers,
319
            Resources::X_MS_BLOB_CACHE_CONTROL,
320
            $options->getCacheControl()
321
        );
322
        $this->addOptionalHeader(
323
            $headers,
324
            Resources::X_MS_BLOB_CONTENT_DISPOSITION,
325
            $options->getContentDisposition()
326
        );
327
        $this->addOptionalHeader(
328
            $headers,
329
            Resources::CONTENT_TYPE,
330
            Resources::URL_ENCODED_CONTENT_TYPE
331
        );
332
        
333
        return $headers;
334
    }
335
    
336
    /**
337
     * Adds Range header to the headers array.
338
     *
339
     * @param array   $headers The HTTP request headers.
340
     * @param integer $start   The start byte.
341
     * @param integer $end     The end byte.
342
     *
343
     * @return array
344
     */
345
    private function _addOptionalRangeHeader(array $headers, $start, $end)
346
    {
347
        if (!is_null($start) || !is_null($end)) {
348
            $range      = $start . '-' . $end;
349
            $rangeValue = 'bytes=' . $range;
350
            $this->addOptionalHeader($headers, Resources::RANGE, $rangeValue);
351
        }
352
        
353
        return $headers;
354
    }
355
356
    /**
357
     * Get the expected status code of a given lease action.
358
     *
359
     * @param  string $leaseAction The given lease action
360
     *
361
     * @return string
362
     */
363
    private static function getStatusCodeOfLeaseAction($leaseAction)
364
    {
365
        $statusCode = Resources::EMPTY_STRING;
0 ignored issues
show
Unused Code introduced by
$statusCode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
366 View Code Duplication
        switch ($leaseAction) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
367
            case LeaseMode::ACQUIRE_ACTION:
368
                $statusCode = Resources::STATUS_CREATED;
369
                break;
370
            case LeaseMode::RENEW_ACTION:
371
                $statusCode = Resources::STATUS_OK;
372
                break;
373
            case LeaseMode::RELEASE_ACTION:
374
                $statusCode = Resources::STATUS_OK;
375
                break;
376
            case LeaseMode::BREAK_ACTION:
377
                $statusCode = Resources::STATUS_ACCEPTED;
378
                break;
379
            default:
380
                throw new \Exception(Resources::NOT_IMPLEMENTED_MSG);
381
        }
382
383
        return $statusCode;
384
    }
385
386
    /**
387
     * Creates promise that does the actual work for leasing a blob.
388
     *
389
     * @param string                    $leaseAction        Lease action string.
390
     * @param string                    $container          Container name.
391
     * @param string                    $blob               Blob to lease name.
392
     * @param string                    $leaseId            Existing lease id.
393
     * @param string                    $expectedStatusCode Expected status code.
394
     * @param Models\BlobServiceOptions $options            Optional parameters.
395
     * @param Models\AccessCondition    $accessCondition    Access conditions.
396
     *
397
     * @return \GuzzleHttp\Promise\PromiseInterface
398
     */
399
    private function _putLeaseAsyncImpl(
400
        $leaseAction,
401
        $container,
402
        $blob,
403
        $proposedLeaseId,
404
        $leaseDuration,
405
        $leaseId,
406
        $breakPeriod,
407
        $expectedStatusCode,
408
        Models\BlobServiceOptions $options,
409
        Models\AccessCondition $accessCondition = null
410
    ) {
411
        Validate::isString($blob, 'blob');
412
        Validate::isString($container, 'container');
413
        Validate::notNullOrEmpty($container, 'container');
414
        
415
        $method      = Resources::HTTP_PUT;
416
        $headers     = array();
417
        $queryParams = array();
418
        $postParams  = array();
419
        $path;
0 ignored issues
show
Bug introduced by
The variable $path seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
420
421
        if (empty($blob)) {
422
            $path = $this->_createPath($container);
423
            $this->addOptionalQueryParam(
424
                $queryParams,
425
                Resources::QP_REST_TYPE,
426
                'container'
427
            );
428
        } else {
429
            $path = $this->_createPath($container, $blob);
430
        }
431
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'lease');
432
        $this->addOptionalQueryParam(
433
            $queryParams,
434
            Resources::QP_TIMEOUT,
435
            $options->getTimeout()
436
        );
437
        
438
        $this->addOptionalHeader($headers, Resources::X_MS_LEASE_ID, $leaseId);
439
        $this->addOptionalHeader(
440
            $headers,
441
            Resources::X_MS_LEASE_ACTION,
442
            $leaseAction
443
        );
444
        $this->addOptionalHeader(
445
            $headers,
446
            Resources::X_MS_LEASE_BREAK_PERIOD,
447
            $breakPeriod
448
        );
449
        $this->addOptionalHeader(
450
            $headers,
451
            Resources::X_MS_LEASE_DURATION,
452
            $leaseDuration
453
        );
454
        $this->addOptionalHeader(
455
            $headers,
456
            Resources::X_MS_PROPOSED_LEASE_ID,
457
            $proposedLeaseId
458
        );
459
        $this->addOptionalAccessConditionHeader($headers, $accessCondition);
0 ignored issues
show
Bug introduced by
It seems like $accessCondition defined by parameter $accessCondition on line 409 can also be of type object<MicrosoftAzure\St...Models\AccessCondition>; however, MicrosoftAzure\Storage\B...AccessConditionHeader() does only seem to accept null|array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
460
461
        if (!is_null($options)) {
462
            $options = new BlobServiceOptions();
463
        }
464
        
465
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
0 ignored issues
show
Bug introduced by
It seems like $options is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
466
467
        return $this->sendAsync(
468
            $method,
469
            $headers,
470
            $queryParams,
471
            $postParams,
472
            $path,
473
            $expectedStatusCode,
474
            Resources::EMPTY_STRING,
475
            $options
476
        );
477
    }
478
479
    /**
480
     * Creates promise that does actual work for create and clear blob pages.
481
     *
482
     * @param string                 $action    Either clear or create.
483
     * @param string                 $container The container name.
484
     * @param string                 $blob      The blob name.
485
     * @param Range          $range     The page ranges.
486
     * @param string                 $content   The content string.
487
     * @param CreateBlobPagesOptions $options   The optional parameters.
488
     *
489
     * @return \GuzzleHttp\Promise\PromiseInterface
490
     */
491
    private function _updatePageBlobPagesAsyncImpl(
492
        $action,
493
        $container,
494
        $blob,
495
        Range $range,
496
        $content,
497
        CreateBlobPagesOptions $options = null
498
    ) {
499
        Validate::isString($blob, 'blob');
500
        Validate::notNullOrEmpty($blob, 'blob');
501
        Validate::isString($container, 'container');
502
        Validate::isString($content, 'content');
503
        Validate::isTrue(
504
            $range instanceof Range,
505
            sprintf(
506
                Resources::INVALID_PARAM_MSG,
507
                'range',
508
                get_class(new Range(0))
509
            )
510
        );
511
        $body = Psr7\stream_for($content);
512
        
513
        $method      = Resources::HTTP_PUT;
514
        $headers     = array();
515
        $queryParams = array();
516
        $postParams  = array();
517
        $path        = $this->_createPath($container, $blob);
518
        
519
        if (is_null($options)) {
520
            $options = new CreateBlobPagesOptions();
521
        }
522
        
523
        $headers = $this->_addOptionalRangeHeader(
524
            $headers,
525
            $range->getStart(),
526
            $range->getEnd()
527
        );
528
        
529
        $headers = $this->addOptionalAccessConditionHeader(
530
            $headers,
531
            $options->getAccessConditions()
532
        );
533
        
534
        $this->addOptionalHeader(
535
            $headers,
536
            Resources::X_MS_LEASE_ID,
537
            $options->getLeaseId()
538
        );
539
        $this->addOptionalHeader(
540
            $headers,
541
            Resources::CONTENT_MD5,
542
            $options->getContentMD5()
543
        );
544
        $this->addOptionalHeader(
545
            $headers,
546
            Resources::X_MS_PAGE_WRITE,
547
            $action
548
        );
549
        $this->addOptionalHeader(
550
            $headers,
551
            Resources::CONTENT_TYPE,
552
            Resources::URL_ENCODED_CONTENT_TYPE
553
        );
554
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page');
555
        
556
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
557
558
        return $this->sendAsync(
559
            $method,
560
            $headers,
561
            $queryParams,
562
            $postParams,
563
            $path,
564
            Resources::STATUS_CREATED,
565
            $body,
566
            $options
567
        )->then(function ($response) {
568
            return CreateBlobPagesResult::create(
569
                HttpFormatter::formatHeaders($response->getHeaders())
570
            );
571
        }, null);
572
    }
573
    
574
    /**
575
     * Lists all of the containers in the given storage account.
576
     *
577
     * @param ListContainersOptions $options The optional parameters.
578
     *
579
     * @return ListContainersResult
580
     *
581
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx
582
     */
583
    public function listContainers(ListContainersOptions $options = null)
584
    {
585
        return $this->listContainersAsync($options)->wait();
586
    }
587
588
    /**
589
     * Create a promise for lists all of the containers in the given
590
     * storage account.
591
     *
592
     * @param  ListContainersOptions $options The optional parameters.
593
     *
594
     * @return \GuzzleHttp\Promise\PromiseInterface
595
     */
596
    public function listContainersAsync(
597
        ListContainersOptions $options = null
598
    ) {
599
        $method      = Resources::HTTP_GET;
600
        $headers     = array();
601
        $queryParams = array();
602
        $postParams  = array();
603
        $path        = Resources::EMPTY_STRING;
604
        
605
        if (is_null($options)) {
606
            $options = new ListContainersOptions();
607
        }
608
        
609
        $this->addOptionalQueryParam(
610
            $queryParams,
611
            Resources::QP_COMP,
612
            'list'
613
        );
614
        $this->addOptionalQueryParam(
615
            $queryParams,
616
            Resources::QP_PREFIX,
617
            $options->getPrefix()
618
        );
619
        $this->addOptionalQueryParam(
620
            $queryParams,
621
            Resources::QP_MARKER,
622
            $options->getNextMarker()
623
        );
624
        $this->addOptionalQueryParam(
625
            $queryParams,
626
            Resources::QP_MAX_RESULTS,
627
            $options->getMaxResults()
628
        );
629
        $isInclude = $options->getIncludeMetadata();
630
        $isInclude = $isInclude ? 'metadata' : null;
631
        $this->addOptionalQueryParam(
632
            $queryParams,
633
            Resources::QP_INCLUDE,
634
            $isInclude
635
        );
636
637
        $dataSerializer = $this->dataSerializer;
638
639
        return $this->sendAsync(
640
            $method,
641
            $headers,
642
            $queryParams,
643
            $postParams,
644
            $path,
645
            Resources::STATUS_OK,
646
            Resources::EMPTY_STRING,
647
            $options
648
        )->then(function ($response) use ($dataSerializer) {
649
            $parsed = $this->dataSerializer->unserialize($response->getBody());
650
            return ListContainersResult::create(
651
                $parsed,
652
                Utilities::getLocationFromHeaders($response->getHeaders())
653
            );
654
        });
655
    }
656
    
657
    /**
658
     * Creates a new container in the given storage account.
659
     *
660
     * @param string                        $container The container name.
661
     * @param Models\CreateContainerOptions $options   The optional parameters.
662
     *
663
     * @return void
664
     *
665
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx
666
     */
667
    public function createContainer(
668
        $container,
669
        Models\CreateContainerOptions $options = null
670
    ) {
671
        $this->createContainerAsync($container, $options)->wait();
672
    }
673
674
    /**
675
     * Creates a new container in the given storage account.
676
     *
677
     * @param string                        $container The container name.
678
     * @param Models\CreateContainerOptions $options   The optional parameters.
679
     *
680
     * @return \GuzzleHttp\Promise\PromiseInterface
681
     *
682
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx
683
     */
684
    public function createContainerAsync(
685
        $container,
686
        Models\CreateContainerOptions $options = null
687
    ) {
688
        Validate::isString($container, 'container');
689
        Validate::notNullOrEmpty($container, 'container');
690
        
691
        $method      = Resources::HTTP_PUT;
692
        $headers     = array();
0 ignored issues
show
Unused Code introduced by
$headers is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
693
        $postParams  = array();
694
        $queryParams = array(Resources::QP_REST_TYPE => 'container');
695
        $path        = $this->_createPath($container);
696
        
697
        if (is_null($options)) {
698
            $options = new CreateContainerOptions();
699
        }
700
701
        $metadata = $options->getMetadata();
702
        $headers  = $this->generateMetadataHeaders($metadata);
703
        $this->addOptionalHeader(
704
            $headers,
705
            Resources::X_MS_BLOB_PUBLIC_ACCESS,
706
            $options->getPublicAccess()
707
        );
708
709
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
710
        
711
        return $this->sendAsync(
712
            $method,
713
            $headers,
714
            $queryParams,
715
            $postParams,
716
            $path,
717
            Resources::STATUS_CREATED,
718
            Resources::EMPTY_STRING,
719
            $options
720
        );
721
    }
722
    
723
    /**
724
     * Deletes a container in the given storage account.
725
     *
726
     * @param string                        $container The container name.
727
     * @param Models\BlobServiceOptions     $options   The optional parameters.
728
     *
729
     * @return void
730
     *
731
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx
732
     */
733
    public function deleteContainer(
734
        $container,
735
        Models\BlobServiceOptions $options = null
736
    ) {
737
        $this->deleteContainerAsync($container, $options)->wait();
738
    }
739
740
    /**
741
     * Create a promise for deleting a container.
742
     *
743
     * @param  string                             $container name of the container
744
     * @param  Models\BlobServiceOptions|null     $options   optional parameters
745
     *
746
     * @return \GuzzleHttp\Promise\PromiseInterface
747
     */
748
    public function deleteContainerAsync(
749
        $container,
750
        Models\BlobServiceOptions $options = null
751
    ) {
752
        Validate::isString($container, 'container');
753
        Validate::notNullOrEmpty($container, 'container');
754
        
755
        $method      = Resources::HTTP_DELETE;
756
        $headers     = array();
757
        $postParams  = array();
758
        $queryParams = array();
759
        $path        = $this->_createPath($container);
760
        
761
        if (is_null($options)) {
762
            $options = new BlobServiceOptions();
763
        }
764
        
765
        $this->addOptionalHeader(
766
            $headers,
767
            Resources::X_MS_LEASE_ID,
768
            $options->getLeaseId()
769
        );
770
        $headers = $this->addOptionalAccessConditionHeader(
771
            $headers,
772
            $options->getAccessConditions()
773
        );
774
        
775
        $this->addOptionalQueryParam(
776
            $queryParams,
777
            Resources::QP_REST_TYPE,
778
            'container'
779
        );
780
781
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
782
783
        return $this->sendAsync(
784
            $method,
785
            $headers,
786
            $queryParams,
787
            $postParams,
788
            $path,
789
            Resources::STATUS_ACCEPTED,
790
            Resources::EMPTY_STRING,
791
            $options
792
        );
793
    }
794
    
795
    /**
796
     * Returns all properties and metadata on the container.
797
     *
798
     * @param string                    $container name
799
     * @param Models\BlobServiceOptions $options   optional parameters
800
     *
801
     * @return Models\GetContainerPropertiesResult
802
     *
803
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx
804
     */
805
    public function getContainerProperties(
806
        $container,
807
        Models\BlobServiceOptions $options = null
808
    ) {
809
        return $this->getContainerPropertiesAsync($container, $options)->wait();
810
    }
811
812
    /**
813
     * Create promise to return all properties and metadata on the container.
814
     *
815
     * @param string                    $container name
816
     * @param Models\BlobServiceOptions $options   optional parameters
817
     *
818
     * @return \GuzzleHttp\Promise\PromiseInterface
819
     *
820
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx
821
     */
822
    public function getContainerPropertiesAsync(
823
        $container,
824
        Models\BlobServiceOptions $options = null
825
    ) {
826
        return $this->_getContainerPropertiesAsyncImpl($container, $options);
827
    }
828
    
829
    /**
830
     * Returns only user-defined metadata for the specified container.
831
     *
832
     * @param string                    $container name
833
     * @param Models\BlobServiceOptions $options   optional parameters
834
     *
835
     * @return Models\GetContainerPropertiesResult
836
     *
837
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx
838
     */
839
    public function getContainerMetadata(
840
        $container,
841
        Models\BlobServiceOptions $options = null
842
    ) {
843
        return $this->getContainerMetadataAsync($container, $options)->wait();
844
    }
845
846
    /**
847
     * Create promise to return only user-defined metadata for the specified
848
     * container.
849
     *
850
     * @param string                    $container name
851
     * @param Models\BlobServiceOptions $options   optional parameters
852
     *
853
     * @return \GuzzleHttp\Promise\PromiseInterface
854
     *
855
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx
856
     */
857
    public function getContainerMetadataAsync(
858
        $container,
859
        Models\BlobServiceOptions $options = null
860
    ) {
861
        return $this->_getContainerPropertiesAsyncImpl($container, $options, 'metadata');
862
    }
863
    
864
    /**
865
     * Gets the access control list (ACL) and any container-level access policies
866
     * for the container.
867
     *
868
     * @param string                    $container The container name.
869
     * @param Models\BlobServiceOptions $options   The optional parameters.
870
     *
871
     * @return Models\GetContainerACLResult
872
     *
873
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx
874
     */
875
    public function getContainerAcl(
876
        $container,
877
        Models\BlobServiceOptions $options = null
878
    ) {
879
        return $this->getContainerAclAsync($container, $options)->wait();
880
    }
881
882
    /**
883
     * Creates the promise to get the access control list (ACL) and any
884
     * container-level access policies for the container.
885
     *
886
     * @param string                    $container The container name.
887
     * @param Models\BlobServiceOptions $options   The optional parameters.
888
     *
889
     * @return \GuzzleHttp\Promise\PromiseInterface
890
     *
891
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx
892
     */
893
    public function getContainerAclAsync(
894
        $container,
895
        Models\BlobServiceOptions $options = null
896
    ) {
897
        Validate::isString($container, 'container');
898
        
899
        $method      = Resources::HTTP_GET;
900
        $headers     = array();
901
        $postParams  = array();
902
        $queryParams = array();
903
        $path        = $this->_createPath($container);
904
        $statusCode  = Resources::STATUS_OK;
0 ignored issues
show
Unused Code introduced by
$statusCode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
905
        
906
        if (is_null($options)) {
907
            $options = new BlobServiceOptions();
908
        }
909
        
910
        $this->addOptionalQueryParam(
911
            $queryParams,
912
            Resources::QP_REST_TYPE,
913
            'container'
914
        );
915
        $this->addOptionalQueryParam(
916
            $queryParams,
917
            Resources::QP_COMP,
918
            'acl'
919
        );
920
921
        $this->addOptionalHeader(
922
            $headers,
923
            Resources::X_MS_LEASE_ID,
924
            $options->getLeaseId()
925
        );
926
        $this->addOptionalAccessConditionHeader(
927
            $headers,
928
            $options->getAccessConditions()
929
        );
930
931
        $dataSerializer = $this->dataSerializer;
932
        
933
        $promise = $this->sendAsync(
934
            $method,
935
            $headers,
936
            $queryParams,
937
            $postParams,
938
            $path,
939
            Resources::STATUS_OK,
940
            Resources::EMPTY_STRING,
941
            $options
942
        );
943
944
        return $promise->then(function ($response) use ($dataSerializer) {
945
            $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders());
946
            
947
            $access = Utilities::tryGetValue(
948
                $responseHeaders,
949
                Resources::X_MS_BLOB_PUBLIC_ACCESS
950
            );
951
            $etag = Utilities::tryGetValue($responseHeaders, Resources::ETAG);
952
            $modified = Utilities::tryGetValue(
953
                $responseHeaders,
954
                Resources::LAST_MODIFIED
955
            );
956
            $modifiedDate = Utilities::convertToDateTime($modified);
957
            $parsed       = $dataSerializer->unserialize($response->getBody());
958
            
959
            return GetContainerAclResult::create(
960
                $access,
961
                $etag,
962
                $modifiedDate,
963
                $parsed
964
            );
965
        }, null);
966
    }
967
    
968
    /**
969
     * Sets the ACL and any container-level access policies for the container.
970
     *
971
     * @param string                    $container name
972
     * @param Models\ContainerACL       $acl       access control list for container
973
     * @param Models\BlobServiceOptions $options   optional parameters
974
     *
975
     * @return void
976
     *
977
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx
978
     */
979
    public function setContainerAcl(
980
        $container,
981
        Models\ContainerACL $acl,
982
        Models\BlobServiceOptions $options = null
983
    ) {
984
        $this->setContainerAclAsync($container, $acl, $options)->wait();
985
    }
986
987
    /**
988
     * Creates promise to set the ACL and any container-level access policies
989
     * for the container.
990
     *
991
     * @param string                    $container name
992
     * @param Models\ContainerACL       $acl       access control list for container
993
     * @param Models\BlobServiceOptions $options   optional parameters
994
     *
995
     * @return \GuzzleHttp\Promise\PromiseInterface
996
     *
997
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx
998
     */
999
    public function setContainerAclAsync(
1000
        $container,
1001
        Models\ContainerACL $acl,
1002
        Models\BlobServiceOptions $options = null
1003
    ) {
1004
        Validate::isString($container, 'container');
1005
        Validate::notNullOrEmpty($acl, 'acl');
1006
        
1007
        $method      = Resources::HTTP_PUT;
1008
        $headers     = array();
1009
        $postParams  = array();
1010
        $queryParams = array();
1011
        $path        = $this->_createPath($container);
1012
        $body        = $acl->toXml($this->dataSerializer);
0 ignored issues
show
Compatibility introduced by
$this->dataSerializer of type object<MicrosoftAzure\St...ialization\ISerializer> is not a sub-type of object<MicrosoftAzure\St...lization\XmlSerializer>. It seems like you assume a concrete implementation of the interface MicrosoftAzure\Storage\C...rialization\ISerializer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
1013
        
1014
        if (is_null($options)) {
1015
            $options = new BlobServiceOptions();
1016
        }
1017
        
1018
        $this->addOptionalQueryParam(
1019
            $queryParams,
1020
            Resources::QP_REST_TYPE,
1021
            'container'
1022
        );
1023
        $this->addOptionalQueryParam(
1024
            $queryParams,
1025
            Resources::QP_COMP,
1026
            'acl'
1027
        );
1028
        $this->addOptionalHeader(
1029
            $headers,
1030
            Resources::X_MS_BLOB_PUBLIC_ACCESS,
1031
            $acl->getPublicAccess()
1032
        );
1033
        $this->addOptionalHeader(
1034
            $headers,
1035
            Resources::CONTENT_TYPE,
1036
            Resources::URL_ENCODED_CONTENT_TYPE
1037
        );
1038
        $this->addOptionalHeader(
1039
            $headers,
1040
            Resources::X_MS_LEASE_ID,
1041
            $options->getLeaseId()
1042
        );
1043
        $this->addOptionalAccessConditionHeader(
1044
            $headers,
1045
            $options->getAccessConditions()
1046
        );
1047
1048
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1049
1050
        return $this->sendAsync(
1051
            $method,
1052
            $headers,
1053
            $queryParams,
1054
            $postParams,
1055
            $path,
1056
            Resources::STATUS_OK,
1057
            $body,
0 ignored issues
show
Security Bug introduced by
It seems like $body defined by $acl->toXml($this->dataSerializer) on line 1012 can also be of type false; however, MicrosoftAzure\Storage\C...eRestProxy::sendAsync() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
1058
            $options
1059
        );
1060
    }
1061
    
1062
    /**
1063
     * Sets metadata headers on the container.
1064
     *
1065
     * @param string                    $container name
1066
     * @param array                     $metadata  metadata key/value pair.
1067
     * @param Models\BlobServiceOptions $options   optional parameters
1068
     *
1069
     * @return void
1070
     *
1071
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx
1072
     */
1073
    public function setContainerMetadata(
1074
        $container,
1075
        array $metadata,
1076
        Models\BlobServiceOptions $options = null
1077
    ) {
1078
        $this->setContainerMetadataAsync($container, $metadata, $options)->wait();
1079
    }
1080
1081
    /**
1082
     * Sets metadata headers on the container.
1083
     *
1084
     * @param string                   $container name
1085
     * @param array                    $metadata  metadata key/value pair.
1086
     * @param Models\BlobServiceOptions $options   optional parameters
1087
     *
1088
     * @return \GuzzleHttp\Promise\PromiseInterface
1089
     *
1090
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx
1091
     */
1092
    public function setContainerMetadataAsync(
1093
        $container,
1094
        array $metadata,
1095
        Models\BlobServiceOptions $options = null
1096
    ) {
1097
        Validate::isString($container, 'container');
1098
        Utilities::validateMetadata($metadata);
1099
        
1100
        $method      = Resources::HTTP_PUT;
1101
        $headers     = $this->generateMetadataHeaders($metadata);
1102
        $postParams  = array();
1103
        $queryParams = array();
1104
        $path        = $this->_createPath($container);
1105
        
1106
        if (is_null($options)) {
1107
            $options = new BlobServiceOptions();
1108
        }
1109
        
1110
        $this->addOptionalQueryParam(
1111
            $queryParams,
1112
            Resources::QP_REST_TYPE,
1113
            'container'
1114
        );
1115
        $this->addOptionalQueryParam(
1116
            $queryParams,
1117
            Resources::QP_COMP,
1118
            'metadata'
1119
        );
1120
1121
        $this->addOptionalHeader(
1122
            $headers,
1123
            Resources::X_MS_LEASE_ID,
1124
            $options->getLeaseId()
1125
        );
1126
        
1127
        $headers = $this->addOptionalAccessConditionHeader(
1128
            $headers,
1129
            $options->getAccessConditions()
1130
        );
1131
1132
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1133
1134
        return $this->sendAsync(
1135
            $method,
1136
            $headers,
1137
            $queryParams,
1138
            $postParams,
1139
            $path,
1140
            Resources::STATUS_OK,
1141
            Resources::EMPTY_STRING,
1142
            $options
1143
        );
1144
    }
1145
    
1146
    /**
1147
     * Lists all of the blobs in the given container.
1148
     *
1149
     * @param string                  $container The container name.
1150
     * @param Models\ListBlobsOptions $options   The optional parameters.
1151
     *
1152
     * @return Models\ListBlobsResult
1153
     *
1154
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
1155
     */
1156
    public function listBlobs($container, Models\ListBlobsOptions $options = null)
1157
    {
1158
        return $this->listBlobsAsync($container, $options)->wait();
1159
    }
1160
1161
    /**
1162
     * Creates promise to list all of the blobs in the given container.
1163
     *
1164
     * @param string                  $container The container name.
1165
     * @param Models\ListBlobsOptions $options   The optional parameters.
1166
     *
1167
     * @return \GuzzleHttp\Promise\PromiseInterface
1168
     *
1169
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx
1170
     */
1171
    public function listBlobsAsync(
1172
        $container,
1173
        Models\ListBlobsOptions $options = null
1174
    ) {
1175
        Validate::isString($container, 'container');
1176
        
1177
        $method      = Resources::HTTP_GET;
1178
        $headers     = array();
1179
        $postParams  = array();
1180
        $queryParams = array();
1181
        $path        = $this->_createPath($container);
1182
        
1183
        if (is_null($options)) {
1184
            $options = new ListBlobsOptions();
1185
        }
1186
        
1187
        $this->addOptionalQueryParam(
1188
            $queryParams,
1189
            Resources::QP_REST_TYPE,
1190
            'container'
1191
        );
1192
        $this->addOptionalQueryParam(
1193
            $queryParams,
1194
            Resources::QP_COMP,
1195
            'list'
1196
        );
1197
        $this->addOptionalQueryParam(
1198
            $queryParams,
1199
            Resources::QP_PREFIX,
1200
            str_replace('\\', '/', $options->getPrefix())
1201
        );
1202
        $this->addOptionalQueryParam(
1203
            $queryParams,
1204
            Resources::QP_MARKER,
1205
            $options->getNextMarker()
1206
        );
1207
        $this->addOptionalQueryParam(
1208
            $queryParams,
1209
            Resources::QP_DELIMITER,
1210
            $options->getDelimiter()
1211
        );
1212
        $this->addOptionalQueryParam(
1213
            $queryParams,
1214
            Resources::QP_MAX_RESULTS,
1215
            $options->getMaxResults()
1216
        );
1217
        
1218
        $includeMetadata         = $options->getIncludeMetadata();
1219
        $includeSnapshots        = $options->getIncludeSnapshots();
1220
        $includeUncommittedBlobs = $options->getIncludeUncommittedBlobs();
1221
        $includecopy             = $options->getIncludeCopy();
1222
        
1223
        $includeValue = static::groupQueryValues(
1224
            array(
1225
                $includeMetadata ? 'metadata' : null,
1226
                $includeSnapshots ? 'snapshots' : null,
1227
                $includeUncommittedBlobs ? 'uncommittedblobs' : null,
1228
                $includecopy ? 'copy' : null
1229
            )
1230
        );
1231
        
1232
        $this->addOptionalQueryParam(
1233
            $queryParams,
1234
            Resources::QP_INCLUDE,
1235
            $includeValue
1236
        );
1237
1238
        $dataSerializer = $this->dataSerializer;
1239
1240
        return $this->sendAsync(
1241
            $method,
1242
            $headers,
1243
            $queryParams,
1244
            $postParams,
1245
            $path,
1246
            Resources::STATUS_OK,
1247
            Resources::EMPTY_STRING,
1248
            $options
1249 View Code Duplication
        )->then(function ($response) use ($dataSerializer) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1250
            $parsed = $dataSerializer->unserialize($response->getBody());
1251
            return ListBlobsResult::create(
1252
                $parsed,
1253
                Utilities::getLocationFromHeaders($response->getHeaders())
1254
            );
1255
        }, null);
1256
    }
1257
    
1258
    /**
1259
     * Creates a new page blob. Note that calling createPageBlob to create a page
1260
     * blob only initializes the blob.
1261
     * To add content to a page blob, call createBlobPages method.
1262
     *
1263
     * @param string                   $container The container name.
1264
     * @param string                   $blob      The blob name.
1265
     * @param integer                  $length    Specifies the maximum size
1266
     *                                            for the page blob, up to 1 TB.
1267
     *                                            The page blob size must be
1268
     *                                            aligned to a 512-byte
1269
     *                                            boundary.
1270
     * @param Models\CreateBlobOptions $options   The optional parameters.
1271
     *
1272
     * @return Models\PutBlobResult
1273
     *
1274
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1275
     */
1276
    public function createPageBlob(
1277
        $container,
1278
        $blob,
1279
        $length,
1280
        Models\CreateBlobOptions $options = null
1281
    ) {
1282
        return $this->createPageBlobAsync(
1283
            $container,
1284
            $blob,
1285
            $length,
1286
            $options
1287
        )->wait();
1288
    }
1289
1290
    /**
1291
     * Creates promise to create a new page blob. Note that calling
1292
     * createPageBlob to create a page blob only initializes the blob.
1293
     * To add content to a page blob, call createBlobPages method.
1294
     *
1295
     * @param string                   $container The container name.
1296
     * @param string                   $blob      The blob name.
1297
     * @param integer                  $length    Specifies the maximum size
1298
     *                                            for the page blob, up to 1 TB.
1299
     *                                            The page blob size must be
1300
     *                                            aligned to a 512-byte
1301
     *                                            boundary.
1302
     * @param Models\CreateBlobOptions $options   The optional parameters.
1303
     *
1304
     * @return \GuzzleHttp\Promise\PromiseInterface
1305
     *
1306
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1307
     */
1308
    public function createPageBlobAsync(
1309
        $container,
1310
        $blob,
1311
        $length,
1312
        Models\CreateBlobOptions $options = null
1313
    ) {
1314
        Validate::isString($container, 'container');
1315
        Validate::isString($blob, 'blob');
1316
        Validate::notNullOrEmpty($blob, 'blob');
1317
        Validate::isInteger($length, 'length');
1318
        Validate::notNull($length, 'length');
1319
        
1320
        $method      = Resources::HTTP_PUT;
1321
        $headers     = array();
1322
        $postParams  = array();
1323
        $queryParams = array();
1324
        $path        = $this->_createPath($container, $blob);
1325
        $statusCode  = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
$statusCode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1326
        
1327
        if (is_null($options)) {
1328
            $options = new CreateBlobOptions();
1329
        }
1330
        
1331
        $this->addOptionalHeader(
1332
            $headers,
1333
            Resources::X_MS_BLOB_TYPE,
1334
            BlobType::PAGE_BLOB
1335
        );
1336
        $this->addOptionalHeader(
1337
            $headers,
1338
            Resources::X_MS_BLOB_CONTENT_LENGTH,
1339
            $length
1340
        );
1341
        $this->addOptionalHeader(
1342
            $headers,
1343
            Resources::X_MS_BLOB_SEQUENCE_NUMBER,
1344
            $options->getSequenceNumber()
1345
        );
1346
        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1347
        
1348
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1349
1350
        return $this->sendAsync(
1351
            $method,
1352
            $headers,
1353
            $queryParams,
1354
            $postParams,
1355
            $path,
1356
            Resources::STATUS_CREATED,
1357
            Resources::EMPTY_STRING,
1358
            $options
1359
        )->then(function ($response) {
1360
            return PutBlobResult::create(
1361
                HttpFormatter::formatHeaders($response->getHeaders())
1362
            );
1363
        }, null);
1364
    }
1365
    
1366
    /**
1367
     * Create a new append blob.
1368
     * If the blob already exists on the service, it will be overwritten.
1369
     *
1370
     * @param string                   $container The container name.
1371
     * @param string                   $blob      The blob name.
1372
     * @param Models\CreateBlobOptions $options   The optional parameters.
1373
     *
1374
     * @return Models\PutBlobResult
1375
     *
1376
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1377
     */
1378
    public function createAppendBlob(
1379
        $container,
1380
        $blob,
1381
        Models\CreateBlobOptions $options = null
1382
    ) {
1383
        return $this->createAppendBlobAsync(
1384
            $container,
1385
            $blob,
1386
            $options
1387
        )->wait();
1388
    }
1389
1390
    /**
1391
     * Creates promise to create a new append blob.
1392
     * If the blob already exists on the service, it will be overwritten.
1393
     *
1394
     * @param string                   $container The container name.
1395
     * @param string                   $blob      The blob name.
1396
     * @param Models\CreateBlobOptions $options   The optional parameters.
1397
     *
1398
     * @return \GuzzleHttp\Promise\PromiseInterface
1399
     *
1400
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1401
     */
1402
    public function createAppendBlobAsync(
1403
        $container,
1404
        $blob,
1405
        Models\CreateBlobOptions $options = null
1406
    ) {
1407
        Validate::isString($container, 'container');
1408
        Validate::notNullOrEmpty($container, 'container');
1409
        Validate::isString($blob, 'blob');
1410
        Validate::notNullOrEmpty($blob, 'blob');
1411
1412
        $method      = Resources::HTTP_PUT;
1413
        $headers     = array();
1414
        $postParams  = array();
1415
        $queryParams = array();
1416
        $path        = $this->_createPath($container, $blob);
1417
        $statusCode  = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
$statusCode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1418
1419
        if (is_null($options)) {
1420
            $options = new CreateBlobOptions();
1421
        }
1422
        
1423
        $this->addOptionalHeader(
1424
            $headers,
1425
            Resources::X_MS_BLOB_TYPE,
1426
            BlobType::APPEND_BLOB
1427
        );
1428
        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1429
1430
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1431
1432
        return $this->sendAsync(
1433
            $method,
1434
            $headers,
1435
            $queryParams,
1436
            $postParams,
1437
            $path,
1438
            Resources::STATUS_CREATED,
1439
            Resources::EMPTY_STRING,
1440
            $options
1441
        )->then(function ($response) {
1442
            return PutBlobResult::create(
1443
                HttpFormatter::formatHeaders($response->getHeaders())
1444
            );
1445
        }, null);
1446
    }
1447
    
1448
    /**
1449
     * Creates a new block blob or updates the content of an existing block blob.
1450
     *
1451
     * Updating an existing block blob overwrites any existing metadata on the blob.
1452
     * Partial updates are not supported with createBlockBlob the content of the
1453
     * existing blob is overwritten with the content of the new blob. To perform a
1454
     * partial update of the content of a block blob, use the createBlockList
1455
     * method.
1456
     * Note that the default content type is application/octet-stream.
1457
     *
1458
     * @param string                          $container The name of the container.
1459
     * @param string                          $blob      The name of the blob.
1460
     * @param string|resource|StreamInterface $content   The content of the blob.
1461
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1462
     *
1463
     * @return Models\PutBlobResult
1464
     *
1465
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1466
     */
1467
    public function createBlockBlob(
1468
        $container,
1469
        $blob,
1470
        $content,
1471
        Models\CreateBlobOptions $options = null
1472
    ) {
1473
        return $this->createBlockBlobAsync(
1474
            $container,
1475
            $blob,
1476
            $content,
1477
            $options
1478
        )->wait();
1479
    }
1480
1481
    /**
1482
     * Creates a promise to create a new block blob or updates the content of
1483
     * an existing block blob.
1484
     *
1485
     * Updating an existing block blob overwrites any existing metadata on the blob.
1486
     * Partial updates are not supported with createBlockBlob the content of the
1487
     * existing blob is overwritten with the content of the new blob. To perform a
1488
     * partial update of the content of a block blob, use the createBlockList
1489
     * method.
1490
     *
1491
     * @param string                          $container The name of the container.
1492
     * @param string                          $blob      The name of the blob.
1493
     * @param string|resource|StreamInterface $content   The content of the blob.
1494
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1495
     *
1496
     * @return Models\PutBlobResult
1497
     *
1498
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1499
     */
1500
    public function createBlockBlobAsync(
1501
        $container,
1502
        $blob,
1503
        $content,
1504
        Models\CreateBlobOptions $options = null
1505
    ) {
1506
        $body = Psr7\stream_for($content);
1507
1508
        //If the size of the stream is not seekable or larger than the single
1509
        //upload threashold then call concurrent upload. Otherwise call putBlob.
1510
        $promise = null;
0 ignored issues
show
Unused Code introduced by
$promise is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1511
        if (!Utilities::isStreamLargerThanSizeOrNotSeekable(
1512
            $body,
1513
            $this->_SingleBlobUploadThresholdInBytes
1514
        )) {
1515
            $promise = $this->createBlockBlobBySingleUploadAsync(
1516
                $container,
1517
                $blob,
1518
                $body,
1519
                $options
1520
            );
1521
        } else {
1522
            // This is for large or failsafe upload
1523
            $promise = $this->createBlockBlobByMultipleUploadAsync(
1524
                $container,
1525
                $blob,
1526
                $body,
1527
                $options
1528
            );
1529
        }
1530
1531
        //return the parsed result, instead of the raw response.
1532
        return $promise;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $promise; (GuzzleHttp\Promise\PromiseInterface) is incompatible with the return type declared by the interface MicrosoftAzure\Storage\B...b::createBlockBlobAsync of type MicrosoftAzure\Storage\Blob\Models\PutBlobResult.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
1533
    }
1534
1535
    /**
1536
     * Create a new page blob and upload the content to the page blob.
1537
     *
1538
     * @param string                          $container The name of the container.
1539
     * @param string                          $blob      The name of the blob.
1540
     * @param int                             $length    The length of the blob.
1541
     * @param string|resource|StreamInterface $content   The content of the blob.
1542
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1543
     *
1544
     * @return Models\GetBlobPropertiesResult
1545
     *
1546
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties
1547
     */
1548
    public function createPageBlobFromContent(
1549
        $container,
1550
        $blob,
1551
        $length,
1552
        $content,
1553
        Models\CreateBlobOptions $options = null
1554
    ) {
1555
        return $this->createPageBlobFromContentAsync(
1556
            $container,
1557
            $blob,
1558
            $length,
1559
            $content,
1560
            $options
1561
        )->wait();
1562
    }
1563
1564
    /**
1565
     * Creates a promise to create a new page blob and upload the content
1566
     * to the page blob.
1567
     *
1568
     * @param string                          $container The name of the container.
1569
     * @param string                          $blob      The name of the blob.
1570
     * @param int                             $length    The length of the blob.
1571
     * @param string|resource|StreamInterface $content   The content of the blob.
1572
     * @param Models\CreateBlobOptions        $options   The optional parameters.
1573
     *
1574
     * @return \GuzzleHttp\Promise\PromiseInterface
1575
     *
1576
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/get-blob-properties
1577
     */
1578
    public function createPageBlobFromContentAsync(
1579
        $container,
1580
        $blob,
1581
        $length,
1582
        $content,
1583
        Models\CreateBlobOptions $options = null
1584
    ) {
1585
        $body = Psr7\stream_for($content);
1586
        $self = $this;
1587
1588
        $createBlobPromise = $this->createPageBlobAsync(
1589
            $container,
1590
            $blob,
1591
            $length,
1592
            $options
1593
        );
1594
1595
        $uploadBlobPromise = $createBlobPromise->then(
1596
            function ($value) use (
1597
                $self,
1598
                $container,
1599
                $blob,
1600
                $body,
1601
                $options
1602
            ) {
1603
                $result = $value;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1604
                return $self->uploadPageBlobAsync(
1605
                    $container,
1606
                    $blob,
1607
                    $body,
1608
                    $options
1609
                );
1610
            },
1611
            null
1612
        );
1613
1614
        return $uploadBlobPromise->then(
1615
            function ($value) use (
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1616
                $self,
1617
                $container,
1618
                $blob,
1619
                $options
1620
            ) {
1621
                $getBlobPropertiesOptions = new GetBlobPropertiesOptions();
1622
                $getBlobPropertiesOptions->setLeaseId($options->getLeaseId());
0 ignored issues
show
Bug introduced by
It seems like $options is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
1623
1624
                return $self->getBlobPropertiesAsync(
1625
                    $container,
1626
                    $blob,
1627
                    $getBlobPropertiesOptions
1628
                );
1629
            },
1630
            null
1631
        );
1632
    }
1633
1634
    /**
1635
     * Creates promise to create a new block blob or updates the content of an
1636
     * existing block blob. This only supports contents smaller than single
1637
     * upload threashold.
1638
     *
1639
     * Updating an existing block blob overwrites any existing metadata on
1640
     * the blob.
1641
     *
1642
     * @param string                   $container The name of the container.
1643
     * @param string                   $blob      The name of the blob.
1644
     * @param StreamInterface          $content   The content of the blob.
1645
     * @param Models\CreateBlobOptions $options   The optional parameters.
1646
     *
1647
     * @return \GuzzleHttp\Promise\PromiseInterface
1648
     *
1649
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx
1650
     */
1651
    protected function createBlockBlobBySingleUploadAsync(
1652
        $container,
1653
        $blob,
1654
        $content,
1655
        Models\CreateBlobOptions $options = null
1656
    ) {
1657
        Validate::isString($container, 'container');
1658
        Validate::isString($blob, 'blob');
1659
        Validate::notNullOrEmpty($blob, 'blob');
1660
        Validate::isTrue(
1661
            $options == null ||
1662
            $options instanceof CreateBlobOptions,
1663
            sprintf(
1664
                Resources::INVALID_PARAM_MSG,
1665
                'options',
1666
                get_class(new CreateBlobOptions())
1667
            )
1668
        );
1669
        
1670
        $method      = Resources::HTTP_PUT;
1671
        $headers     = array();
1672
        $postParams  = array();
1673
        $queryParams = array();
1674
        $path        = $this->_createPath($container, $blob);
1675
1676
        if (is_null($options)) {
1677
            $options = new CreateBlobOptions();
1678
        }
1679
        
1680
        
1681
        $headers = $this->_addCreateBlobOptionalHeaders($options, $headers);
1682
        
1683
        $this->addOptionalHeader(
1684
            $headers,
1685
            Resources::X_MS_BLOB_TYPE,
1686
            BlobType::BLOCK_BLOB
1687
        );
1688
1689
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
1690
1691
        return $this->sendAsync(
1692
            $method,
1693
            $headers,
1694
            $queryParams,
1695
            $postParams,
1696
            $path,
1697
            Resources::STATUS_CREATED,
1698
            $content,
1699
            $options
1700
        )->then(
1701
            function ($response) {
1702
                return PutBlobResult::create(
1703
                    HttpFormatter::formatHeaders($response->getHeaders())
1704
                );
1705
            },
1706
            null
1707
        );
1708
    }
1709
1710
    /**
1711
     * This method creates the blob blocks. This method will send the request
1712
     * concurrently for better performance.
1713
     *
1714
     * @param  string                   $container  Name of the container
1715
     * @param  string                   $blob       Name of the blob
1716
     * @param  StreamInterface          $content    Content's stream
1717
     * @param  Models\CreateBlobOptions $options    Array that contains
1718
     *                                                     all the option
1719
     *
1720
     * @return \GuzzleHttp\Promise\PromiseInterface
1721
     */
1722
    protected function createBlockBlobByMultipleUploadAsync(
1723
        $container,
1724
        $blob,
1725
        $content,
1726
        Models\CreateBlobOptions $options = null
1727
    ) {
1728
        Validate::isString($container, 'container');
1729
        Validate::isString($blob, 'blob');
1730
1731
        if (is_null($options)) {
1732
            $options = new CreateBlobOptions();
1733
        }
1734
1735
        $createBlobBlockOptions = CreateBlobBlockOptions::create($options);
1736
        $selfInstance = $this;
1737
1738
        $method      = Resources::HTTP_PUT;
1739
        $headers     = $this->createBlobBlockHeader($createBlobBlockOptions);
1740
        $postParams  = array();
1741
        $path        = $this->_createPath($container, $blob);
1742
1743
        $blockIds = array();
1744
        // if threshold is lower than 4mb, honor threshold, else use 4mb
1745
        $blockSize = (
1746
            $this->_SingleBlobUploadThresholdInBytes
1747
                < Resources::MB_IN_BYTES_4) ?
1748
            $this->_SingleBlobUploadThresholdInBytes : Resources::MB_IN_BYTES_4;
1749
        $counter = 0;
1750
        //create the generator for requests.
1751
        //this generator also constructs the blockId array on the fly.
1752
        $generator = function () use (
1753
            $content,
1754
            &$blockIds,
1755
            $blockSize,
1756
            $createBlobBlockOptions,
1757
            $method,
1758
            $headers,
1759
            $postParams,
1760
            $path,
1761
            &$counter,
1762
            $selfInstance
1763
        ) {
1764
            //read the content.
1765
            $blockContent = $content->read($blockSize);
1766
            //construct the blockId
1767
            $blockId = base64_encode(
1768
                str_pad($counter++, 6, '0', STR_PAD_LEFT)
1769
            );
1770
            $size = strlen($blockContent);
1771
            if ($size == 0) {
1772
                return null;
1773
            }
1774
            //add the id to array.
1775
            array_push($blockIds, new Block($blockId, 'Uncommitted'));
1776
            $queryParams = $selfInstance->createBlobBlockQueryParams(
1777
                $createBlobBlockOptions,
1778
                $blockId,
1779
                true
1780
            );
1781
            //return the array of requests.
1782
            return $selfInstance->createRequest(
1783
                $method,
1784
                $headers,
1785
                $queryParams,
1786
                $postParams,
1787
                $path,
1788
                LocationMode::PRIMARY_ONLY,
1789
                $blockContent
1790
            );
1791
        };
1792
1793
        //Send the request concurrently.
1794
        //Does not need to evaluate the results. If operation not successful,
1795
        //exception will be thrown.
1796
        $putBlobPromise = $this->sendConcurrentAsync(
1797
            $generator,
1798
            Resources::STATUS_CREATED,
1799
            $options
1800
        );
1801
1802
        $commitBlobPromise = $putBlobPromise->then(
1803
            function ($value) use (
0 ignored issues
show
Unused Code introduced by
The parameter $value is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1804
                $selfInstance,
1805
                $container,
1806
                $blob,
1807
                &$blockIds,
1808
                $putBlobPromise,
1809
                $options
1810
            ) {
1811
                return $selfInstance->commitBlobBlocksAsync(
1812
                    $container,
1813
                    $blob,
1814
                    $blockIds,
1815
                    CommitBlobBlocksOptions::create($options)
1816
                );
1817
            },
1818
            null
1819
        );
1820
1821
        return $commitBlobPromise;
1822
    }
1823
1824
1825
    /**
1826
     * This method upload the page blob pages. This method will send the request
1827
     * concurrently for better performance.
1828
     *
1829
     * @param  string                   $container  Name of the container
1830
     * @param  string                   $blob       Name of the blob
1831
     * @param  StreamInterface          $content    Content's stream
1832
     * @param  Models\CreateBlobOptions $options    Array that contains
1833
     *                                                     all the option
1834
     *
1835
     * @return \GuzzleHttp\Promise\PromiseInterface
1836
     */
1837
    private function uploadPageBlobAsync(
1838
        $container,
1839
        $blob,
1840
        $content,
1841
        Models\CreateBlobOptions $options = null
1842
    ) {
1843
        Validate::isString($container, 'container');
1844
        Validate::notNullOrEmpty($container, 'container');
1845
1846
        Validate::isString($blob, 'blob');
1847
        Validate::notNullOrEmpty($blob, 'blob');
1848
1849
        if (is_null($options)) {
1850
            $options = new CreateBlobOptions();
1851
        }
1852
        
1853
        $method      = Resources::HTTP_PUT;
1854
        $postParams  = array();
1855
        $queryParams = array();
1856
        $path        = $this->_createPath($container, $blob);
1857
1858
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page');
1859
        $this->addOptionalQueryParam(
1860
            $queryParams,
1861
            Resources::QP_TIMEOUT,
1862
            $options->getTimeout()
1863
        );
1864
1865
        $pageSize = Resources::MB_IN_BYTES_4;
1866
        $start = 0;
1867
        $end = -1;
1868
1869
        //create the generator for requests.
1870
        $generator = function () use (
1871
            $content,
1872
            $pageSize,
1873
            $method,
1874
            $postParams,
1875
            $queryParams,
1876
            $path,
1877
            &$start,
1878
            &$end,
1879
            $options
1880
        ) {
1881
            //read the content.
1882
            $pageContent;
0 ignored issues
show
Bug introduced by
The variable $pageContent seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1883
            $size;
0 ignored issues
show
Bug introduced by
The variable $size seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
1884
            
1885
            do {
1886
                $pageContent = $content->read($pageSize);
1887
                $size = strlen($pageContent);
1888
1889
                if ($size == 0) {
1890
                    return null;
1891
                }
1892
                
1893
                $end += $size;
1894
                $start = ($end - $size + 1);
1895
                
1896
                // If all Zero, skip this range
1897
            } while (Utilities::allZero($pageContent));
1898
1899
            $headers = array();
1900
            $headers = $this->_addOptionalRangeHeader(
1901
                $headers,
1902
                $start,
1903
                $end
1904
            );
1905
            $headers = $this->addOptionalAccessConditionHeader(
1906
                $headers,
1907
                $options->getAccessConditions()
1908
            );
1909
            $this->addOptionalHeader(
1910
                $headers,
1911
                Resources::X_MS_LEASE_ID,
1912
                $options->getLeaseId()
1913
            );
1914
            $this->addOptionalHeader(
1915
                $headers,
1916
                Resources::X_MS_PAGE_WRITE,
1917
                PageWriteOption::UPDATE_OPTION
1918
            );
1919
1920
            //return the array of requests.
1921
            return $this->createRequest(
1922
                $method,
1923
                $headers,
1924
                $queryParams,
1925
                $postParams,
1926
                $path,
1927
                LocationMode::PRIMARY_ONLY,
1928
                $pageContent
1929
            );
1930
        };
1931
1932
        //Send the request concurrently.
1933
        //Does not need to evaluate the results. If operation is not successful,
1934
        //exception will be thrown.
1935
        return $this->sendConcurrentAsync(
1936
            $generator,
1937
            Resources::STATUS_CREATED,
1938
            $options->getRequestOptions()
0 ignored issues
show
Bug introduced by
The method getRequestOptions() does not seem to exist on object<MicrosoftAzure\St...dels\CreateBlobOptions>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
1939
        );
1940
    }
1941
    
1942
    /**
1943
     * Clears a range of pages from the blob.
1944
     *
1945
     * @param string                        $container name of the container
1946
     * @param string                        $blob      name of the blob
1947
     * @param Range                         $range     Can be up to the value of
1948
     *                                                 the blob's full size.
1949
     *                                                 Note that ranges must be
1950
     *                                                 aligned to 512 (0-511,
1951
     *                                                 512-1023)
1952
     * @param Models\CreateBlobPagesOptions $options   optional parameters
1953
     *
1954
     * @return Models\CreateBlobPagesResult
1955
     *
1956
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
1957
     */
1958
    public function clearBlobPages(
1959
        $container,
1960
        $blob,
1961
        Range $range,
1962
        Models\CreateBlobPagesOptions $options = null
1963
    ) {
1964
        return $this->clearBlobPagesAsync(
1965
            $container,
1966
            $blob,
1967
            $range,
1968
            $options
1969
        )->wait();
1970
    }
1971
1972
    /**
1973
     * Creates promise to clear a range of pages from the blob.
1974
     *
1975
     * @param string                        $container name of the container
1976
     * @param string                        $blob      name of the blob
1977
     * @param Range                         $range     Can be up to the value of
1978
     *                                                 the blob's full size.
1979
     *                                                 Note that ranges must be
1980
     *                                                 aligned to 512 (0-511,
1981
     *                                                 512-1023)
1982
     * @param Models\CreateBlobPagesOptions $options   optional parameters
1983
     *
1984
     * @return \GuzzleHttp\Promise\PromiseInterface
1985
     *
1986
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
1987
     */
1988
    public function clearBlobPagesAsync(
1989
        $container,
1990
        $blob,
1991
        Range $range,
1992
        Models\CreateBlobPagesOptions $options = null
1993
    ) {
1994
        return $this->_updatePageBlobPagesAsyncImpl(
1995
            PageWriteOption::CLEAR_OPTION,
1996
            $container,
1997
            $blob,
1998
            $range,
1999
            Resources::EMPTY_STRING,
2000
            $options
2001
        );
2002
    }
2003
    
2004
    /**
2005
     * Creates a range of pages to a page blob.
2006
     *
2007
     * @param string                          $container name of the container
2008
     * @param string                          $blob      name of the blob
2009
     * @param Range                           $range     Can be up to 4 MB in
2010
     *                                                   size. Note that ranges
2011
     *                                                   must be aligned to 512
2012
     *                                                   (0-511, 512-1023)
2013
     * @param string|resource|StreamInterface $content   the blob contents.
2014
     * @param Models\CreateBlobPagesOptions   $options   optional parameters
2015
     *
2016
     * @return Models\CreateBlobPagesResult
2017
     *
2018
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
2019
     */
2020
    public function createBlobPages(
2021
        $container,
2022
        $blob,
2023
        Range $range,
2024
        $content,
2025
        Models\CreateBlobPagesOptions $options = null
2026
    ) {
2027
        return $this->createBlobPagesAsync(
2028
            $container,
2029
            $blob,
2030
            $range,
2031
            $content,
2032
            $options
2033
        )->wait();
2034
    }
2035
2036
    /**
2037
     * Creates promise to create a range of pages to a page blob.
2038
     *
2039
     * @param string                          $container name of the container
2040
     * @param string                          $blob      name of the blob
2041
     * @param Range                           $range     Can be up to 4 MB in
2042
     *                                                   size. Note that ranges
2043
     *                                                   must be aligned to 512
2044
     *                                                   (0-511, 512-1023)
2045
     * @param string|resource|StreamInterface $content   the blob contents.
2046
     * @param Models\CreateBlobPagesOptions   $options   optional parameters
2047
     *
2048
     * @return \GuzzleHttp\Promise\PromiseInterface
2049
     *
2050
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx
2051
     */
2052
    public function createBlobPagesAsync(
2053
        $container,
2054
        $blob,
2055
        Range $range,
2056
        $content,
2057
        Models\CreateBlobPagesOptions $options = null
2058
    ) {
2059
        $contentStream = Psr7\stream_for($content);
2060
        //because the content is at most 4MB long, can retrieve all the data
2061
        //here at once.
2062
        $body = $contentStream->getContents();
2063
2064
        //if the range is not align to 512, throw exception.
2065
        $chunks = (int)($range->getLength() / 512);
2066
        if ($chunks * 512 != $range->getLength()) {
2067
            throw new \RuntimeException(Resources::ERROR_RANGE_NOT_ALIGN_TO_512);
2068
        }
2069
2070
        return $this->_updatePageBlobPagesAsyncImpl(
2071
            PageWriteOption::UPDATE_OPTION,
2072
            $container,
2073
            $blob,
2074
            $range,
2075
            $body,
2076
            $options
2077
        );
2078
    }
2079
    
2080
    /**
2081
     * Creates a new block to be committed as part of a block blob.
2082
     *
2083
     * @param string                          $container name of the container
2084
     * @param string                          $blob      name of the blob
2085
     * @param string                          $blockId   must be less than or
2086
     *                                                   equal to 64 bytes in
2087
     *                                                   size. For a given blob,
2088
     *                                                   the length of the value
2089
     *                                                   specified for the
2090
     *                                                   blockid parameter must
2091
     *                                                   be the same size for
2092
     *                                                   each block.
2093
     * @param resource|string|StreamInterface $content   the blob block contents
2094
     * @param Models\CreateBlobBlockOptions   $options   optional parameters
2095
     *
2096
     * @return Models\PutBlockResult
2097
     *
2098
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx
2099
     */
2100
    public function createBlobBlock(
2101
        $container,
2102
        $blob,
2103
        $blockId,
2104
        $content,
2105
        Models\CreateBlobBlockOptions $options = null
2106
    ) {
2107
        return $this->createBlobBlockAsync(
2108
            $container,
2109
            $blob,
2110
            $blockId,
2111
            $content,
2112
            $options
2113
        )->wait();
2114
    }
2115
2116
    /**
2117
     * Creates a new block to be committed as part of a block blob.
2118
     *
2119
     * @param string                          $container name of the container
2120
     * @param string                          $blob      name of the blob
2121
     * @param string                          $blockId   must be less than or
2122
     *                                                   equal to 64 bytes in
2123
     *                                                   size. For a given blob,
2124
     *                                                   the length of the value
2125
     *                                                   specified for the
2126
     *                                                   blockid parameter must
2127
     *                                                   be the same size for
2128
     *                                                   each block.
2129
     * @param resource|string|StreamInterface $content   the blob block contents
2130
     * @param Models\CreateBlobBlockOptions   $options   optional parameters
2131
     *
2132
     * @return \GuzzleHttp\Promise\PromiseInterface
2133
     *
2134
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx
2135
     */
2136
    public function createBlobBlockAsync(
2137
        $container,
2138
        $blob,
2139
        $blockId,
2140
        $content,
2141
        Models\CreateBlobBlockOptions $options = null
2142
    ) {
2143
        Validate::isString($container, 'container');
2144
        Validate::isString($blob, 'blob');
2145
        Validate::notNullOrEmpty($blob, 'blob');
2146
        Validate::isString($blockId, 'blockId');
2147
        Validate::notNullOrEmpty($blockId, 'blockId');
2148
2149
        if (is_null($options)) {
2150
            $options = new CreateBlobBlockOptions();
2151
        }
2152
        
2153
        $method         = Resources::HTTP_PUT;
2154
        $headers        = $this->createBlobBlockHeader($options);
2155
        $postParams     = array();
2156
        $queryParams    = $this->createBlobBlockQueryParams($options, $blockId);
2157
        $path           = $this->_createPath($container, $blob);
2158
        $statusCode     = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
$statusCode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2159
        $contentStream  = Psr7\stream_for($content);
2160
        $body           = $contentStream->getContents();
2161
        
2162
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
2163
2164
        return $this->sendAsync(
2165
            $method,
2166
            $headers,
2167
            $queryParams,
2168
            $postParams,
2169
            $path,
2170
            Resources::STATUS_CREATED,
2171
            $body,
2172
            $options
2173
        )->then(function ($response) {
2174
            return PutBlockResult::create(
2175
                HttpFormatter::formatHeaders($response->getHeaders())
2176
            );
2177
        });
2178
    }
2179
    
2180
    /**
2181
     * Commits a new block of data to the end of an existing append blob.
2182
     *
2183
     * @param string                          $container name of the container
2184
     * @param string                          $blob      name of the blob
2185
     * @param resource|string|StreamInterface $content   the blob block contents
2186
     * @param Models\AppendBlockOptions       $options   optional parameters
2187
     *
2188
     * @return Models\AppendBlockResult
2189
     *
2190
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block
2191
     */
2192
    public function appendBlock(
2193
        $container,
2194
        $blob,
2195
        $content,
2196
        Models\AppendBlockOptions $options = null
2197
    ) {
2198
        return $this->appendBlockAsync(
2199
            $container,
2200
            $blob,
2201
            $content,
2202
            $options
2203
        )->wait();
2204
    }
2205
2206
2207
    /**
2208
     * Creates promise to commit a new block of data to the end of an existing append blob.
2209
     *
2210
     * @param string                          $container name of the container
2211
     * @param string                          $blob      name of the blob
2212
     * @param resource|string|StreamInterface $content   the blob block contents
2213
     * @param Models\AppendBlockOptions       $options   optional parameters
2214
     *
2215
     * @return \GuzzleHttp\Promise\PromiseInterface
2216
     *
2217
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/append-block
2218
     */
2219
    public function appendBlockAsync(
2220
        $container,
2221
        $blob,
2222
        $content,
2223
        Models\AppendBlockOptions $options = null
2224
    ) {
2225
        Validate::isString($container, 'container');
2226
        Validate::notNullOrEmpty($container, 'container');
2227
        Validate::isString($blob, 'blob');
2228
        Validate::notNullOrEmpty($blob, 'blob');
2229
2230
        if (is_null($options)) {
2231
            $options = new AppendBlockOptions();
2232
        }
2233
        
2234
        $method         = Resources::HTTP_PUT;
2235
        $headers        = array();
2236
        $postParams     = array();
2237
        $queryParams    = array();
2238
        $path           = $this->_createPath($container, $blob);
2239
        $statusCode     = Resources::STATUS_CREATED;
0 ignored issues
show
Unused Code introduced by
$statusCode is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2240
2241
        $contentStream  = Psr7\stream_for($content);
2242
        $length         = $contentStream->getSize();
2243
        $body           = $contentStream->getContents();
2244
2245
        $this->addOptionalQueryParam(
2246
            $queryParams,
2247
            Resources::QP_COMP,
2248
            'appendblock'
2249
        );
2250
        
2251
        $headers  = $this->addOptionalAccessConditionHeader(
2252
            $headers,
2253
            $options->getAccessConditions()
2254
        );
2255
2256
        $this->addOptionalHeader(
2257
            $headers,
2258
            Resources::CONTENT_LENGTH,
2259
            $length
2260
        );
2261
        $this->addOptionalHeader(
2262
            $headers,
2263
            Resources::CONTENT_MD5,
2264
            $options->getContentMD5()
2265
        );
2266
        $this->addOptionalHeader(
2267
            $headers,
2268
            Resources::X_MS_BLOB_CONDITION_MAXSIZE,
2269
            $options->getMaxBlobSize()
2270
        );
2271
        $this->addOptionalHeader(
2272
            $headers,
2273
            Resources::X_MS_BLOB_CONDITION_APPENDPOS,
2274
            $options->getAppendPosition()
2275
        );
2276
        $this->addOptionalHeader(
2277
            $headers,
2278
            Resources::X_MS_LEASE_ID,
2279
            $options->getLeaseId()
2280
        );
2281
        
2282
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
2283
2284
        return $this->sendAsync(
2285
            $method,
2286
            $headers,
2287
            $queryParams,
2288
            $postParams,
2289
            $path,
2290
            Resources::STATUS_CREATED,
2291
            $body,
2292
            $options
2293
        )->then(function ($response) {
2294
            return AppendBlockResult::create(
2295
                HttpFormatter::formatHeaders($response->getHeaders())
2296
            );
2297
        });
2298
    }
2299
2300
    /**
2301
     * create the header for createBlobBlock(s)
2302
     * @param  Models\CreateBlobBlockOptions $options the option of the request
2303
     *
2304
     * @return array
2305
     */
2306
    protected function createBlobBlockHeader(Models\CreateBlobBlockOptions $options = null)
2307
    {
2308
        $headers = array();
2309
        $this->addOptionalHeader(
2310
            $headers,
2311
            Resources::X_MS_LEASE_ID,
2312
            $options->getLeaseId()
0 ignored issues
show
Bug introduced by
It seems like $options is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
2313
        );
2314
        $this->addOptionalHeader(
2315
            $headers,
2316
            Resources::CONTENT_MD5,
2317
            $options->getContentMD5()
2318
        );
2319
        $this->addOptionalHeader(
2320
            $headers,
2321
            Resources::CONTENT_TYPE,
2322
            Resources::URL_ENCODED_CONTENT_TYPE
2323
        );
2324
2325
        return $headers;
2326
    }
2327
2328
    /**
2329
     * create the query params for createBlobBlock(s)
2330
     * @param  Models\CreateBlobBlockOptions $options      the option of the
2331
     *                                                     request
2332
     * @param  string                        $blockId      the block id of the
2333
     *                                                     block.
2334
     * @param  bool                          $isConcurrent if the query
2335
     *                                                     parameter is for
2336
     *                                                     concurrent upload.
2337
     *
2338
     * @return array  the constructed query parameters.
2339
     */
2340
    protected function createBlobBlockQueryParams(
2341
        Models\CreateBlobBlockOptions $options,
2342
        $blockId,
2343
        $isConcurrent = false
2344
    ) {
2345
        $queryParams = array();
2346
        $this->addOptionalQueryParam(
2347
            $queryParams,
2348
            Resources::QP_COMP,
2349
            'block'
2350
        );
2351
        $this->addOptionalQueryParam(
2352
            $queryParams,
2353
            Resources::QP_BLOCKID,
2354
            $blockId
2355
        );
2356
        if ($isConcurrent) {
2357
            $this->addOptionalQueryParam(
2358
                $queryParams,
2359
                Resources::QP_TIMEOUT,
2360
                $options->getTimeout()
2361
            );
2362
        }
2363
        
2364
        return $queryParams;
2365
    }
2366
2367
    /**
2368
     * This method writes a blob by specifying the list of block IDs that make up the
2369
     * blob. In order to be written as part of a blob, a block must have been
2370
     * successfully written to the server in a prior createBlobBlock method.
2371
     *
2372
     * You can call Put Block List to update a blob by uploading only those blocks
2373
     * that have changed, then committing the new and existing blocks together.
2374
     * You can do this by specifying whether to commit a block from the committed
2375
     * block list or from the uncommitted block list, or to commit the most recently
2376
     * uploaded version of the block, whichever list it may belong to.
2377
     *
2378
     * @param string                         $container The container name.
2379
     * @param string                         $blob      The blob name.
2380
     * @param Models\BlockList|array         $blockList The block entries.
2381
     * @param Models\CommitBlobBlocksOptions $options   The optional parameters.
2382
     *
2383
     * @return Models\PutBlobResult
2384
     *
2385
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx
2386
     */
2387
    public function commitBlobBlocks(
2388
        $container,
2389
        $blob,
2390
        $blockList,
2391
        Models\CommitBlobBlocksOptions $options = null
2392
    ) {
2393
        return $this->commitBlobBlocksAsync(
2394
            $container,
2395
            $blob,
2396
            $blockList,
2397
            $options
2398
        )->wait();
2399
    }
2400
2401
    /**
2402
     * This method writes a blob by specifying the list of block IDs that make up the
2403
     * blob. In order to be written as part of a blob, a block must have been
2404
     * successfully written to the server in a prior createBlobBlock method.
2405
     *
2406
     * You can call Put Block List to update a blob by uploading only those blocks
2407
     * that have changed, then committing the new and existing blocks together.
2408
     * You can do this by specifying whether to commit a block from the committed
2409
     * block list or from the uncommitted block list, or to commit the most recently
2410
     * uploaded version of the block, whichever list it may belong to.
2411
     *
2412
     * @param string                         $container The container name.
2413
     * @param string                         $blob      The blob name.
2414
     * @param Models\BlockList|array         $blockList The block entries.
2415
     * @param Models\CommitBlobBlocksOptions $options   The optional parameters.
2416
     *
2417
     * @return \GuzzleHttp\Promise\PromiseInterface
2418
     *
2419
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx
2420
     */
2421
    public function commitBlobBlocksAsync(
2422
        $container,
2423
        $blob,
2424
        $blockList,
2425
        Models\CommitBlobBlocksOptions $options = null
2426
    ) {
2427
        Validate::isString($container, 'container');
2428
        Validate::isString($blob, 'blob');
2429
        Validate::notNullOrEmpty($blob, 'blob');
2430
        Validate::isTrue(
2431
            $blockList instanceof BlockList || is_array($blockList),
2432
            sprintf(
2433
                Resources::INVALID_PARAM_MSG,
2434
                'blockList',
2435
                get_class(new BlockList())
2436
            )
2437
        );
2438
        
2439
        $method      = Resources::HTTP_PUT;
2440
        $headers     = array();
0 ignored issues
show
Unused Code introduced by
$headers is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2441
        $postParams  = array();
2442
        $queryParams = array();
2443
        $path        = $this->_createPath($container, $blob);
2444
        $isArray     = is_array($blockList);
2445
        $blockList   = $isArray ? BlockList::create($blockList) : $blockList;
2446
        $body        = $blockList->toXml($this->dataSerializer);
0 ignored issues
show
Compatibility introduced by
$this->dataSerializer of type object<MicrosoftAzure\St...ialization\ISerializer> is not a sub-type of object<MicrosoftAzure\St...lization\XmlSerializer>. It seems like you assume a concrete implementation of the interface MicrosoftAzure\Storage\C...rialization\ISerializer to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
2447
        
2448
        if (is_null($options)) {
2449
            $options = new CommitBlobBlocksOptions();
2450
        }
2451
        
2452
        $blobContentType            = $options->getContentType();
2453
        $blobContentEncoding        = $options->getContentEncoding();
2454
        $blobContentLanguage        = $options->getContentLanguage();
2455
        $blobContentMD5             = $options->getContentMD5();
2456
        $blobCacheControl           = $options->getCacheControl();
2457
        $blobCcontentDisposition    = $options->getContentDisposition();
2458
        $leaseId                    = $options->getLeaseId();
2459
        $contentType                = Resources::URL_ENCODED_CONTENT_TYPE;
2460
        
2461
        $metadata = $options->getMetadata();
2462
        $headers  = $this->generateMetadataHeaders($metadata);
2463
        $headers  = $this->addOptionalAccessConditionHeader(
2464
            $headers,
2465
            $options->getAccessConditions()
2466
        );
2467
        
2468
        $this->addOptionalHeader(
2469
            $headers,
2470
            Resources::X_MS_LEASE_ID,
2471
            $leaseId
2472
        );
2473
        $this->addOptionalHeader(
2474
            $headers,
2475
            Resources::X_MS_BLOB_CACHE_CONTROL,
2476
            $blobCacheControl
2477
        );
2478
        $this->addOptionalHeader(
2479
            $headers,
2480
            Resources::X_MS_BLOB_CONTENT_DISPOSITION,
2481
            $blobCcontentDisposition
2482
        );
2483
        $this->addOptionalHeader(
2484
            $headers,
2485
            Resources::X_MS_BLOB_CONTENT_TYPE,
2486
            $blobContentType
2487
        );
2488
        $this->addOptionalHeader(
2489
            $headers,
2490
            Resources::X_MS_BLOB_CONTENT_ENCODING,
2491
            $blobContentEncoding
2492
        );
2493
        $this->addOptionalHeader(
2494
            $headers,
2495
            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
2496
            $blobContentLanguage
2497
        );
2498
        $this->addOptionalHeader(
2499
            $headers,
2500
            Resources::X_MS_BLOB_CONTENT_MD5,
2501
            $blobContentMD5
2502
        );
2503
        $this->addOptionalHeader(
2504
            $headers,
2505
            Resources::CONTENT_TYPE,
2506
            $contentType
2507
        );
2508
        
2509
        $this->addOptionalQueryParam(
2510
            $queryParams,
2511
            Resources::QP_COMP,
2512
            'blocklist'
2513
        );
2514
        
2515
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
2516
2517
        return $this->sendAsync(
2518
            $method,
2519
            $headers,
2520
            $queryParams,
2521
            $postParams,
2522
            $path,
2523
            Resources::STATUS_CREATED,
2524
            $body,
0 ignored issues
show
Security Bug introduced by
It seems like $body defined by $blockList->toXml($this->dataSerializer) on line 2446 can also be of type false; however, MicrosoftAzure\Storage\C...eRestProxy::sendAsync() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
2525
            $options
2526
        )->then(function ($response) {
2527
            return PutBlobResult::create(
2528
                HttpFormatter::formatHeaders($response->getHeaders())
2529
            );
2530
        }, null);
2531
    }
2532
    
2533
    /**
2534
     * Retrieves the list of blocks that have been uploaded as part of a block blob.
2535
     *
2536
     * There are two block lists maintained for a blob:
2537
     * 1) Committed Block List: The list of blocks that have been successfully
2538
     *    committed to a given blob with commitBlobBlocks.
2539
     * 2) Uncommitted Block List: The list of blocks that have been uploaded for a
2540
     *    blob using Put Block (REST API), but that have not yet been committed.
2541
     *    These blocks are stored in Windows Azure in association with a blob, but do
2542
     *    not yet form part of the blob.
2543
     *
2544
     * @param string                       $container name of the container
2545
     * @param string                       $blob      name of the blob
2546
     * @param Models\ListBlobBlocksOptions $options   optional parameters
2547
     *
2548
     * @return Models\ListBlobBlocksResult
2549
     *
2550
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx
2551
     */
2552
    public function listBlobBlocks(
2553
        $container,
2554
        $blob,
2555
        Models\ListBlobBlocksOptions $options = null
2556
    ) {
2557
        return $this->listBlobBlocksAsync($container, $blob, $options)->wait();
2558
    }
2559
2560
    /**
2561
     * Creates promise to retrieve the list of blocks that have been uploaded as
2562
     * part of a block blob.
2563
     *
2564
     * There are two block lists maintained for a blob:
2565
     * 1) Committed Block List: The list of blocks that have been successfully
2566
     *    committed to a given blob with commitBlobBlocks.
2567
     * 2) Uncommitted Block List: The list of blocks that have been uploaded for a
2568
     *    blob using Put Block (REST API), but that have not yet been committed.
2569
     *    These blocks are stored in Windows Azure in association with a blob, but do
2570
     *    not yet form part of the blob.
2571
     *
2572
     * @param string                       $container name of the container
2573
     * @param string                       $blob      name of the blob
2574
     * @param Models\ListBlobBlocksOptions $options   optional parameters
2575
     *
2576
     * @return \GuzzleHttp\Promise\PromiseInterface
2577
     *
2578
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx
2579
     */
2580
    public function listBlobBlocksAsync(
2581
        $container,
2582
        $blob,
2583
        Models\ListBlobBlocksOptions $options = null
2584
    ) {
2585
        Validate::isString($container, 'container');
2586
        Validate::isString($blob, 'blob');
2587
        Validate::notNullOrEmpty($blob, 'blob');
2588
        
2589
        $method      = Resources::HTTP_GET;
2590
        $headers     = array();
2591
        $postParams  = array();
2592
        $queryParams = array();
2593
        $path        = $this->_createPath($container, $blob);
2594
        
2595
        if (is_null($options)) {
2596
            $options = new ListBlobBlocksOptions();
2597
        }
2598
        
2599
        $this->addOptionalHeader(
2600
            $headers,
2601
            Resources::X_MS_LEASE_ID,
2602
            $options->getLeaseId()
2603
        );
2604
        
2605
        $this->addOptionalQueryParam(
2606
            $queryParams,
2607
            Resources::QP_BLOCK_LIST_TYPE,
2608
            $options->getBlockListType()
2609
        );
2610
        $this->addOptionalQueryParam(
2611
            $queryParams,
2612
            Resources::QP_SNAPSHOT,
2613
            $options->getSnapshot()
2614
        );
2615
        $this->addOptionalQueryParam(
2616
            $queryParams,
2617
            Resources::QP_COMP,
2618
            'blocklist'
2619
        );
2620
        
2621
        return $this->sendAsync(
2622
            $method,
2623
            $headers,
2624
            $queryParams,
2625
            $postParams,
2626
            $path,
2627
            Resources::STATUS_OK,
2628
            Resources::EMPTY_STRING,
2629
            $options
2630
        )->then(function ($response) {
2631
            $parsed = $this->dataSerializer->unserialize($response->getBody());
2632
        
2633
            return ListBlobBlocksResult::create(
2634
                HttpFormatter::formatHeaders($response->getHeaders()),
2635
                $parsed
2636
            );
2637
        }, null);
2638
    }
2639
    
2640
    /**
2641
     * Returns all properties and metadata on the blob.
2642
     *
2643
     * @param string                          $container name of the container
2644
     * @param string                          $blob      name of the blob
2645
     * @param Models\GetBlobPropertiesOptions $options   optional parameters
2646
     *
2647
     * @return Models\GetBlobPropertiesResult
2648
     *
2649
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx
2650
     */
2651
    public function getBlobProperties(
2652
        $container,
2653
        $blob,
2654
        Models\GetBlobPropertiesOptions $options = null
2655
    ) {
2656
        return $this->getBlobPropertiesAsync(
2657
            $container,
2658
            $blob,
2659
            $options
2660
        )->wait();
2661
    }
2662
    
2663
    /**
2664
     * Creates promise to return all properties and metadata on the blob.
2665
     *
2666
     * @param string                          $container name of the container
2667
     * @param string                          $blob      name of the blob
2668
     * @param Models\GetBlobPropertiesOptions $options   optional parameters
2669
     *
2670
     * @return \GuzzleHttp\Promise\PromiseInterface
2671
     *
2672
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx
2673
     */
2674
    public function getBlobPropertiesAsync(
2675
        $container,
2676
        $blob,
2677
        Models\GetBlobPropertiesOptions $options = null
2678
    ) {
2679
        Validate::isString($container, 'container');
2680
        Validate::isString($blob, 'blob');
2681
        Validate::notNullOrEmpty($blob, 'blob');
2682
        
2683
        $method      = Resources::HTTP_HEAD;
2684
        $headers     = array();
2685
        $postParams  = array();
2686
        $queryParams = array();
2687
        $path        = $this->_createPath($container, $blob);
2688
        
2689
        if (is_null($options)) {
2690
            $options = new GetBlobPropertiesOptions();
2691
        }
2692
        
2693
        $headers = $this->addOptionalAccessConditionHeader(
2694
            $headers,
2695
            $options->getAccessConditions()
2696
        );
2697
        
2698
        $this->addOptionalHeader(
2699
            $headers,
2700
            Resources::X_MS_LEASE_ID,
2701
            $options->getLeaseId()
2702
        );
2703
        $this->addOptionalQueryParam(
2704
            $queryParams,
2705
            Resources::QP_SNAPSHOT,
2706
            $options->getSnapshot()
2707
        );
2708
        
2709
        return $this->sendAsync(
2710
            $method,
2711
            $headers,
2712
            $queryParams,
2713
            $postParams,
2714
            $path,
2715
            Resources::STATUS_OK,
2716
            Resources::EMPTY_STRING,
2717
            $options
2718
        )->then(function ($response) {
2719
            $formattedHeaders = HttpFormatter::formatHeaders($response->getHeaders());
2720
            return GetBlobPropertiesResult::create($formattedHeaders);
2721
        }, null);
2722
    }
2723
2724
    /**
2725
     * Returns all properties and metadata on the blob.
2726
     *
2727
     * @param string                        $container name of the container
2728
     * @param string                        $blob      name of the blob
2729
     * @param Models\GetBlobMetadataOptions $options   optional parameters
2730
     *
2731
     * @return Models\GetBlobMetadataResult
2732
     *
2733
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx
2734
     */
2735
    public function getBlobMetadata(
2736
        $container,
2737
        $blob,
2738
        Models\GetBlobMetadataOptions $options = null
2739
    ) {
2740
        return $this->getBlobMetadataAsync($container, $blob, $options)->wait();
2741
    }
2742
2743
    /**
2744
     * Creates promise to return all properties and metadata on the blob.
2745
     *
2746
     * @param string                        $container name of the container
2747
     * @param string                        $blob      name of the blob
2748
     * @param Models\GetBlobMetadataOptions $options   optional parameters
2749
     *
2750
     * @return \GuzzleHttp\Promise\PromiseInterface
2751
     *
2752
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx
2753
     */
2754 View Code Duplication
    public function getBlobMetadataAsync(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2755
        $container,
2756
        $blob,
2757
        Models\GetBlobMetadataOptions $options = null
2758
    ) {
2759
        Validate::isString($container, 'container');
2760
        Validate::isString($blob, 'blob');
2761
        Validate::notNullOrEmpty($blob, 'blob');
2762
        
2763
        $method      = Resources::HTTP_HEAD;
2764
        $headers     = array();
2765
        $postParams  = array();
2766
        $queryParams = array();
2767
        $path        = $this->_createPath($container, $blob);
2768
        
2769
        if (is_null($options)) {
2770
            $options = new GetBlobMetadataOptions();
2771
        }
2772
        
2773
        $headers = $this->addOptionalAccessConditionHeader(
2774
            $headers,
2775
            $options->getAccessConditions()
2776
        );
2777
        
2778
        $this->addOptionalHeader(
2779
            $headers,
2780
            Resources::X_MS_LEASE_ID,
2781
            $options->getLeaseId()
2782
        );
2783
        $this->addOptionalQueryParam(
2784
            $queryParams,
2785
            Resources::QP_SNAPSHOT,
2786
            $options->getSnapshot()
2787
        );
2788
2789
        $this->addOptionalQueryParam(
2790
            $queryParams,
2791
            Resources::QP_COMP,
2792
            'metadata'
2793
        );
2794
        
2795
        return $this->sendAsync(
2796
            $method,
2797
            $headers,
2798
            $queryParams,
2799
            $postParams,
2800
            $path,
2801
            Resources::STATUS_OK,
2802
            Resources::EMPTY_STRING,
2803
            $options
2804
        )->then(function ($response) {
2805
            $responseHeaders = HttpFormatter::formatHeaders($response->getHeaders());
2806
            return GetBlobMetadataResult::create($responseHeaders);
2807
        });
2808
    }
2809
    
2810
    /**
2811
     * Returns a list of active page ranges for a page blob. Active page ranges are
2812
     * those that have been populated with data.
2813
     *
2814
     * @param string                           $container name of the container
2815
     * @param string                           $blob      name of the blob
2816
     * @param Models\ListPageBlobRangesOptions $options   optional parameters
2817
     *
2818
     * @return Models\ListPageBlobRangesResult
2819
     *
2820
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx
2821
     */
2822
    public function listPageBlobRanges(
2823
        $container,
2824
        $blob,
2825
        Models\ListPageBlobRangesOptions $options = null
2826
    ) {
2827
        return $this->listPageBlobRangesAsync(
2828
            $container,
2829
            $blob,
2830
            $options
2831
        )->wait();
2832
    }
2833
2834
    /**
2835
     * Creates promise to return a list of active page ranges for a page blob.
2836
     * Active page ranges are those that have been populated with data.
2837
     *
2838
     * @param string                           $container name of the container
2839
     * @param string                           $blob      name of the blob
2840
     * @param Models\ListPageBlobRangesOptions $options   optional parameters
2841
     *
2842
     * @return \GuzzleHttp\Promise\PromiseInterface
2843
     *
2844
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx
2845
     */
2846
    public function listPageBlobRangesAsync(
2847
        $container,
2848
        $blob,
2849
        Models\ListPageBlobRangesOptions $options = null
2850
    ) {
2851
        Validate::isString($container, 'container');
2852
        Validate::isString($blob, 'blob');
2853
        Validate::notNullOrEmpty($blob, 'blob');
2854
        
2855
        $method      = Resources::HTTP_GET;
2856
        $headers     = array();
2857
        $queryParams = array();
2858
        $postParams  = array();
2859
        $path        = $this->_createPath($container, $blob);
2860
        
2861
        if (is_null($options)) {
2862
            $options = new ListPageBlobRangesOptions();
2863
        }
2864
        
2865
        $headers = $this->addOptionalAccessConditionHeader(
2866
            $headers,
2867
            $options->getAccessConditions()
2868
        );
2869
        
2870
        $headers = $this->_addOptionalRangeHeader(
2871
            $headers,
2872
            $options->getRangeStart(),
2873
            $options->getRangeEnd()
2874
        );
2875
        
2876
        $this->addOptionalHeader(
2877
            $headers,
2878
            Resources::X_MS_LEASE_ID,
2879
            $options->getLeaseId()
2880
        );
2881
        $this->addOptionalQueryParam(
2882
            $queryParams,
2883
            Resources::QP_SNAPSHOT,
2884
            $options->getSnapshot()
2885
        );
2886
        $this->addOptionalQueryParam(
2887
            $queryParams,
2888
            Resources::QP_COMP,
2889
            'pagelist'
2890
        );
2891
        
2892
        $dataSerializer = $this->dataSerializer;
2893
2894
        return $this->sendAsync(
2895
            $method,
2896
            $headers,
2897
            $queryParams,
2898
            $postParams,
2899
            $path,
2900
            Resources::STATUS_OK,
2901
            Resources::EMPTY_STRING,
2902
            $options
2903 View Code Duplication
        )->then(function ($response) use ($dataSerializer) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
2904
            $parsed = $dataSerializer->unserialize($response->getBody());
2905
            return ListPageBlobRangesResult::create(
2906
                HttpFormatter::formatHeaders($response->getHeaders()),
2907
                $parsed
2908
            );
2909
        }, null);
2910
    }
2911
    
2912
    /**
2913
     * Sets system properties defined for a blob.
2914
     *
2915
     * @param string                          $container name of the container
2916
     * @param string                          $blob      name of the blob
2917
     * @param Models\SetBlobPropertiesOptions $options   optional parameters
2918
     *
2919
     * @return Models\SetBlobPropertiesResult
2920
     *
2921
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx
2922
     */
2923
    public function setBlobProperties(
2924
        $container,
2925
        $blob,
2926
        Models\SetBlobPropertiesOptions $options = null
2927
    ) {
2928
        return $this->setBlobPropertiesAsync(
2929
            $container,
2930
            $blob,
2931
            $options
2932
        )->wait();
2933
    }
2934
2935
    /**
2936
     * Creates promise to set system properties defined for a blob.
2937
     *
2938
     * @param string                          $container name of the container
2939
     * @param string                          $blob      name of the blob
2940
     * @param Models\SetBlobPropertiesOptions $options   optional parameters
2941
     *
2942
     * @return \GuzzleHttp\Promise\PromiseInterface
2943
     *
2944
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx
2945
     */
2946
    public function setBlobPropertiesAsync(
2947
        $container,
2948
        $blob,
2949
        Models\SetBlobPropertiesOptions $options = null
2950
    ) {
2951
        Validate::isString($container, 'container');
2952
        Validate::isString($blob, 'blob');
2953
        Validate::notNullOrEmpty($blob, 'blob');
2954
        
2955
        $method      = Resources::HTTP_PUT;
2956
        $headers     = array();
2957
        $postParams  = array();
2958
        $queryParams = array();
2959
        $path        = $this->_createPath($container, $blob);
2960
        
2961
        if (is_null($options)) {
2962
            $options = new SetBlobPropertiesOptions();
2963
        }
2964
        
2965
        $blobContentType            = $options->getContentType();
2966
        $blobContentEncoding        = $options->getContentEncoding();
2967
        $blobContentLanguage        = $options->getContentLanguage();
2968
        $blobContentLength          = $options->getContentLength();
2969
        $blobContentMD5             = $options->getContentMD5();
2970
        $blobCacheControl           = $options->getCacheControl();
2971
        $blobContentDisposition    = $options->getContentDisposition();
2972
        $leaseId             = $options->getLeaseId();
2973
        $sNumberAction       = $options->getSequenceNumberAction();
2974
        $sNumber             = $options->getSequenceNumber();
2975
        
2976
        $headers = $this->addOptionalAccessConditionHeader(
2977
            $headers,
2978
            $options->getAccessConditions()
2979
        );
2980
        
2981
        $this->addOptionalHeader(
2982
            $headers,
2983
            Resources::X_MS_LEASE_ID,
2984
            $leaseId
2985
        );
2986
        $this->addOptionalHeader(
2987
            $headers,
2988
            Resources::X_MS_BLOB_CACHE_CONTROL,
2989
            $blobCacheControl
2990
        );
2991
        $this->addOptionalHeader(
2992
            $headers,
2993
            Resources::X_MS_BLOB_CONTENT_DISPOSITION,
2994
            $blobContentDisposition
2995
        );
2996
        $this->addOptionalHeader(
2997
            $headers,
2998
            Resources::X_MS_BLOB_CONTENT_TYPE,
2999
            $blobContentType
3000
        );
3001
        $this->addOptionalHeader(
3002
            $headers,
3003
            Resources::X_MS_BLOB_CONTENT_ENCODING,
3004
            $blobContentEncoding
3005
        );
3006
        $this->addOptionalHeader(
3007
            $headers,
3008
            Resources::X_MS_BLOB_CONTENT_LANGUAGE,
3009
            $blobContentLanguage
3010
        );
3011
        $this->addOptionalHeader(
3012
            $headers,
3013
            Resources::X_MS_BLOB_CONTENT_LENGTH,
3014
            $blobContentLength
3015
        );
3016
        $this->addOptionalHeader(
3017
            $headers,
3018
            Resources::X_MS_BLOB_CONTENT_MD5,
3019
            $blobContentMD5
3020
        );
3021
        $this->addOptionalHeader(
3022
            $headers,
3023
            Resources::X_MS_BLOB_SEQUENCE_NUMBER_ACTION,
3024
            $sNumberAction
3025
        );
3026
        $this->addOptionalHeader(
3027
            $headers,
3028
            Resources::X_MS_BLOB_SEQUENCE_NUMBER,
3029
            $sNumber
3030
        );
3031
3032
        $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'properties');
3033
        
3034
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3035
3036
        return $this->sendAsync(
3037
            $method,
3038
            $headers,
3039
            $queryParams,
3040
            $postParams,
3041
            $path,
3042
            Resources::STATUS_OK,
3043
            Resources::EMPTY_STRING,
3044
            $options
3045
        )->then(function ($response) {
3046
            return SetBlobPropertiesResult::create(
3047
                HttpFormatter::formatHeaders($response->getHeaders())
3048
            );
3049
        }, null);
3050
    }
3051
    
3052
    /**
3053
     * Sets metadata headers on the blob.
3054
     *
3055
     * @param string                        $container name of the container
3056
     * @param string                        $blob      name of the blob
3057
     * @param array                         $metadata  key/value pair representation
3058
     * @param Models\BlobServiceOptions     $options   optional parameters
3059
     *
3060
     * @return Models\SetBlobMetadataResult
3061
     *
3062
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx
3063
     */
3064
    public function setBlobMetadata(
3065
        $container,
3066
        $blob,
3067
        array $metadata,
3068
        Models\BlobServiceOptions $options = null
3069
    ) {
3070
        return $this->setBlobMetadataAsync(
3071
            $container,
3072
            $blob,
3073
            $metadata,
3074
            $options
3075
        )->wait();
3076
    }
3077
3078
    /**
3079
     * Creates promise to set metadata headers on the blob.
3080
     *
3081
     * @param string                        $container name of the container
3082
     * @param string                        $blob      name of the blob
3083
     * @param array                         $metadata  key/value pair representation
3084
     * @param Models\BlobServiceOptions     $options   optional parameters
3085
     *
3086
     * @return \GuzzleHttp\Promise\PromiseInterface
3087
     *
3088
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx
3089
     */
3090 View Code Duplication
    public function setBlobMetadataAsync(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3091
        $container,
3092
        $blob,
3093
        array $metadata,
3094
        Models\BlobServiceOptions $options = null
3095
    ) {
3096
        Validate::isString($container, 'container');
3097
        Validate::isString($blob, 'blob');
3098
        Validate::notNullOrEmpty($blob, 'blob');
3099
        Utilities::validateMetadata($metadata);
3100
        
3101
        $method      = Resources::HTTP_PUT;
3102
        $headers     = array();
3103
        $postParams  = array();
3104
        $queryParams = array();
3105
        $path        = $this->_createPath($container, $blob);
3106
        
3107
        if (is_null($options)) {
3108
            $options = new BlobServiceOptions();
3109
        }
3110
        
3111
        $headers = $this->addOptionalAccessConditionHeader(
3112
            $headers,
3113
            $options->getAccessConditions()
3114
        );
3115
        $headers = $this->addMetadataHeaders($headers, $metadata);
3116
        
3117
        $this->addOptionalHeader(
3118
            $headers,
3119
            Resources::X_MS_LEASE_ID,
3120
            $options->getLeaseId()
3121
        );
3122
        $this->addOptionalQueryParam(
3123
            $queryParams,
3124
            Resources::QP_COMP,
3125
            'metadata'
3126
        );
3127
        
3128
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3129
3130
        return $this->sendAsync(
3131
            $method,
3132
            $headers,
3133
            $queryParams,
3134
            $postParams,
3135
            $path,
3136
            Resources::STATUS_OK,
3137
            Resources::EMPTY_STRING,
3138
            $options
3139
        )->then(function ($response) {
3140
            return SetBlobMetadataResult::create(
3141
                HttpFormatter::formatHeaders($response->getHeaders())
3142
            );
3143
        }, null);
3144
    }
3145
3146
    /**
3147
     * Downloads a blob to a file, the result contains its metadata and
3148
     * properties. The result will not contain a stream pointing to the
3149
     * content of the file.
3150
     *
3151
     * @param string                $path      The path and name of the file
3152
     * @param string                $container name of the container
3153
     * @param string                $blob      name of the blob
3154
     * @param Models\GetBlobOptions $options   optional parameters
3155
     *
3156
     * @return Models\GetBlobResult
3157
     *
3158
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3159
     */
3160
    public function saveBlobToFile(
3161
        $path,
3162
        $container,
3163
        $blob,
3164
        Models\GetBlobOptions $options = null
3165
    ) {
3166
        return $this->saveBlobToFileAsync(
3167
            $path,
3168
            $container,
3169
            $blob,
3170
            $options
3171
        )->wait();
3172
    }
3173
3174
    /**
3175
     * Creates promise to download a blob to a file, the result contains its
3176
     * metadata and properties. The result will not contain a stream pointing
3177
     * to the content of the file.
3178
     *
3179
     * @param string                $path      The path and name of the file
3180
     * @param string                $container name of the container
3181
     * @param string                $blob      name of the blob
3182
     * @param Models\GetBlobOptions $options   optional parameters
3183
     *
3184
     * @return \GuzzleHttp\Promise\PromiseInterface
3185
     *
3186
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3187
     */
3188
    public function saveBlobToFileAsync(
3189
        $path,
3190
        $container,
3191
        $blob,
3192
        Models\GetBlobOptions $options = null
3193
    ) {
3194
        $resource = fopen($path, 'w+');
3195
        if ($resource == null) {
3196
            throw new \Exception(Resources::ERROR_FILE_COULD_NOT_BE_OPENED);
3197
        }
3198
        return $this->getBlobAsync($container, $blob, $options)->then(
3199
            function ($result) use ($path, $resource) {
3200
                $content = $result->getContentStream();
3201
                while (!feof($content)) {
3202
                    fwrite(
3203
                        $resource,
3204
                        stream_get_contents($content, Resources::MB_IN_BYTES_4)
3205
                    );
3206
                }
3207
                
3208
                $content = null;
0 ignored issues
show
Unused Code introduced by
$content is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
3209
                fclose($resource);
3210
        
3211
                return $result;
3212
            },
3213
            null
3214
        );
3215
    }
3216
    
3217
    /**
3218
     * Reads or downloads a blob from the system, including its metadata and
3219
     * properties.
3220
     *
3221
     * @param string                $container name of the container
3222
     * @param string                $blob      name of the blob
3223
     * @param Models\GetBlobOptions $options   optional parameters
3224
     *
3225
     * @return Models\GetBlobResult
3226
     *
3227
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3228
     */
3229
    public function getBlob(
3230
        $container,
3231
        $blob,
3232
        Models\GetBlobOptions $options = null
3233
    ) {
3234
        return $this->getBlobAsync($container, $blob, $options)->wait();
3235
    }
3236
3237
    /**
3238
     * Creates promise to read or download a blob from the system, including its
3239
     * metadata and properties.
3240
     *
3241
     * @param string                $container name of the container
3242
     * @param string                $blob      name of the blob
3243
     * @param Models\GetBlobOptions $options   optional parameters
3244
     *
3245
     * @return \GuzzleHttp\Promise\PromiseInterface
3246
     *
3247
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx
3248
     */
3249
    public function getBlobAsync(
3250
        $container,
3251
        $blob,
3252
        Models\GetBlobOptions $options = null
3253
    ) {
3254
        Validate::isString($container, 'container');
3255
        Validate::isString($blob, 'blob');
3256
        
3257
        $method      = Resources::HTTP_GET;
3258
        $headers     = array();
3259
        $postParams  = array();
3260
        $queryParams = array();
3261
        $path        = $this->_createPath($container, $blob);
3262
        
3263
        if (is_null($options)) {
3264
            $options = new GetBlobOptions();
3265
        }
3266
        
3267
        $getMD5  = $options->getComputeRangeMD5();
3268
        $headers = $this->addOptionalAccessConditionHeader(
3269
            $headers,
3270
            $options->getAccessConditions()
3271
        );
3272
        $headers = $this->_addOptionalRangeHeader(
3273
            $headers,
3274
            $options->getRangeStart(),
3275
            $options->getRangeEnd()
3276
        );
3277
        
3278
        $this->addOptionalHeader(
3279
            $headers,
3280
            Resources::X_MS_LEASE_ID,
3281
            $options->getLeaseId()
3282
        );
3283
        $this->addOptionalHeader(
3284
            $headers,
3285
            Resources::X_MS_RANGE_GET_CONTENT_MD5,
3286
            $getMD5 ? 'true' : null
3287
        );
3288
        $this->addOptionalQueryParam(
3289
            $queryParams,
3290
            Resources::QP_SNAPSHOT,
3291
            $options->getSnapshot()
3292
        );
3293
3294
        $options->setIsStreaming(true);
3295
        
3296
        return $this->sendAsync(
3297
            $method,
3298
            $headers,
3299
            $queryParams,
3300
            $postParams,
3301
            $path,
3302
            array(Resources::STATUS_OK, Resources::STATUS_PARTIAL_CONTENT),
3303
            Resources::EMPTY_STRING,
3304
            $options
3305 View Code Duplication
        )->then(function ($response) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3306
            $metadata = Utilities::getMetadataArray(
3307
                HttpFormatter::formatHeaders($response->getHeaders())
3308
            );
3309
        
3310
            return GetBlobResult::create(
3311
                HttpFormatter::formatHeaders($response->getHeaders()),
3312
                $response->getBody(),
3313
                $metadata
3314
            );
3315
        });
3316
    }
3317
    
3318
    /**
3319
     * Deletes a blob or blob snapshot.
3320
     *
3321
     * Note that if the snapshot entry is specified in the $options then only this
3322
     * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot
3323
     * and just set getDeleteSnaphotsOnly to true.
3324
     *
3325
     * @param string                   $container name of the container
3326
     * @param string                   $blob      name of the blob
3327
     * @param Models\DeleteBlobOptions $options   optional parameters
3328
     *
3329
     * @return void
3330
     *
3331
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx
3332
     */
3333
    public function deleteBlob(
3334
        $container,
3335
        $blob,
3336
        Models\DeleteBlobOptions $options = null
3337
    ) {
3338
        $this->deleteBlobAsync($container, $blob, $options)->wait();
3339
    }
3340
3341
    /**
3342
     * Creates promise to delete a blob or blob snapshot.
3343
     *
3344
     * Note that if the snapshot entry is specified in the $options then only this
3345
     * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot
3346
     * and just set getDeleteSnaphotsOnly to true.
3347
     *
3348
     * @param string                   $container name of the container
3349
     * @param string                   $blob      name of the blob
3350
     * @param Models\DeleteBlobOptions $options   optional parameters
3351
     *
3352
     * @return \GuzzleHttp\Promise\PromiseInterface
3353
     *
3354
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx
3355
     */
3356
    public function deleteBlobAsync(
3357
        $container,
3358
        $blob,
3359
        Models\DeleteBlobOptions $options = null
3360
    ) {
3361
        Validate::isString($container, 'container');
3362
        Validate::isString($blob, 'blob');
3363
        Validate::notNullOrEmpty($blob, 'blob');
3364
        
3365
        $method      = Resources::HTTP_DELETE;
3366
        $headers     = array();
3367
        $postParams  = array();
3368
        $queryParams = array();
3369
        $path        = $this->_createPath($container, $blob);
3370
        
3371
        if (is_null($options)) {
3372
            $options = new DeleteBlobOptions();
3373
        }
3374
        
3375
        if (is_null($options->getSnapshot())) {
3376
            $delSnapshots = $options->getDeleteSnaphotsOnly() ? 'only' : 'include';
3377
            $this->addOptionalHeader(
3378
                $headers,
3379
                Resources::X_MS_DELETE_SNAPSHOTS,
3380
                $delSnapshots
3381
            );
3382
        } else {
3383
            $this->addOptionalQueryParam(
3384
                $queryParams,
3385
                Resources::QP_SNAPSHOT,
3386
                $options->getSnapshot()
3387
            );
3388
        }
3389
        
3390
        $headers = $this->addOptionalAccessConditionHeader(
3391
            $headers,
3392
            $options->getAccessConditions()
3393
        );
3394
        
3395
        $this->addOptionalHeader(
3396
            $headers,
3397
            Resources::X_MS_LEASE_ID,
3398
            $options->getLeaseId()
3399
        );
3400
        
3401
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3402
3403
        return $this->sendAsync(
3404
            $method,
3405
            $headers,
3406
            $queryParams,
3407
            $postParams,
3408
            $path,
3409
            Resources::STATUS_ACCEPTED,
3410
            Resources::EMPTY_STRING,
3411
            $options
3412
        );
3413
    }
3414
    
3415
    /**
3416
     * Creates a snapshot of a blob.
3417
     *
3418
     * @param string                           $container The name of the container.
3419
     * @param string                           $blob      The name of the blob.
3420
     * @param Models\CreateBlobSnapshotOptions $options   The optional parameters.
3421
     *
3422
     * @return Models\CreateBlobSnapshotResult
3423
     *
3424
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx
3425
     */
3426
    public function createBlobSnapshot(
3427
        $container,
3428
        $blob,
3429
        Models\CreateBlobSnapshotOptions $options = null
3430
    ) {
3431
        return $this->createBlobSnapshotAsync(
3432
            $container,
3433
            $blob,
3434
            $options
3435
        )->wait();
3436
    }
3437
3438
    /**
3439
     * Creates promise to create a snapshot of a blob.
3440
     *
3441
     * @param string                           $container The name of the container.
3442
     * @param string                           $blob      The name of the blob.
3443
     * @param Models\CreateBlobSnapshotOptions $options   The optional parameters.
3444
     *
3445
     * @return \GuzzleHttp\Promise\PromiseInterface
3446
     *
3447
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx
3448
     */
3449 View Code Duplication
    public function createBlobSnapshotAsync(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3450
        $container,
3451
        $blob,
3452
        Models\CreateBlobSnapshotOptions $options = null
3453
    ) {
3454
        Validate::isString($container, 'container');
3455
        Validate::isString($blob, 'blob');
3456
        Validate::notNullOrEmpty($blob, 'blob');
3457
        
3458
        $method             = Resources::HTTP_PUT;
3459
        $headers            = array();
3460
        $postParams         = array();
3461
        $queryParams        = array();
3462
        $path               = $this->_createPath($container, $blob);
3463
        
3464
        if (is_null($options)) {
3465
            $options = new CreateBlobSnapshotOptions();
3466
        }
3467
        
3468
        $queryParams[Resources::QP_COMP] = 'snapshot';
3469
3470
        $headers = $this->addOptionalAccessConditionHeader(
3471
            $headers,
3472
            $options->getAccessConditions()
3473
        );
3474
        $headers = $this->addMetadataHeaders($headers, $options->getMetadata());
3475
        $this->addOptionalHeader(
3476
            $headers,
3477
            Resources::X_MS_LEASE_ID,
3478
            $options->getLeaseId()
3479
        );
3480
        
3481
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3482
3483
        return $this->sendAsync(
3484
            $method,
3485
            $headers,
3486
            $queryParams,
3487
            $postParams,
3488
            $path,
3489
            Resources::STATUS_CREATED,
3490
            Resources::EMPTY_STRING,
3491
            $options
3492
        )->then(function ($response) {
3493
            return CreateBlobSnapshotResult::create(
3494
                HttpFormatter::formatHeaders($response->getHeaders())
3495
            );
3496
        }, null);
3497
    }
3498
    
3499
    /**
3500
     * Copies a source blob to a destination blob within the same storage account.
3501
     *
3502
     * @param string                 $destinationContainer name of the destination
3503
     * container
3504
     * @param string                 $destinationBlob      name of the destination
3505
     * blob
3506
     * @param string                 $sourceContainer      name of the source
3507
     * container
3508
     * @param string                 $sourceBlob           name of the source
3509
     * blob
3510
     * @param Models\CopyBlobOptions $options              optional parameters
3511
     *
3512
     * @return Models\CopyBlobResult
3513
     *
3514
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx
3515
     */
3516
    public function copyBlob(
3517
        $destinationContainer,
3518
        $destinationBlob,
3519
        $sourceContainer,
3520
        $sourceBlob,
3521
        Models\CopyBlobOptions $options = null
3522
    ) {
3523
        return $this->copyBlobAsync(
3524
            $destinationContainer,
3525
            $destinationBlob,
3526
            $sourceContainer,
3527
            $sourceBlob,
3528
            $options
3529
        )->wait();
3530
    }
3531
3532
    /**
3533
     * Creates promise to copy a source blob to a destination blob within the
3534
     * same storage account.
3535
     *
3536
     * @param string                 $destinationContainer name of the destination
3537
     * container
3538
     * @param string                 $destinationBlob      name of the destination
3539
     * blob
3540
     * @param string                 $sourceContainer      name of the source
3541
     * container
3542
     * @param string                 $sourceBlob           name of the source
3543
     * blob
3544
     * @param Models\CopyBlobOptions $options              optional parameters
3545
     *
3546
     * @return \GuzzleHttp\Promise\PromiseInterface
3547
     *
3548
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx
3549
     */
3550
    public function copyBlobAsync(
3551
        $destinationContainer,
3552
        $destinationBlob,
3553
        $sourceContainer,
3554
        $sourceBlob,
3555
        Models\CopyBlobOptions $options = null
3556
    ) {
3557
        $method              = Resources::HTTP_PUT;
3558
        $headers             = array();
3559
        $postParams          = array();
3560
        $queryParams         = array();
3561
        $destinationBlobPath = $this->_createPath(
3562
            $destinationContainer,
3563
            $destinationBlob
3564
        );
3565
        
3566
        if (is_null($options)) {
3567
            $options = new CopyBlobOptions();
3568
        }
3569
        
3570
        $sourceBlobPath = $this->_getCopyBlobSourceName(
3571
            $sourceContainer,
3572
            $sourceBlob,
3573
            $options
3574
        );
3575
        
3576
        $headers = $this->addOptionalAccessConditionHeader(
3577
            $headers,
3578
            $options->getAccessConditions()
3579
        );
3580
        
3581
        $headers = $this->addOptionalSourceAccessConditionHeader(
3582
            $headers,
3583
            $options->getSourceAccessConditions()
3584
        );
3585
        
3586
        $this->addOptionalHeader(
3587
            $headers,
3588
            Resources::X_MS_COPY_SOURCE,
3589
            $sourceBlobPath
3590
        );
3591
        
3592
        $headers = $this->addMetadataHeaders($headers, $options->getMetadata());
3593
        
3594
        $this->addOptionalHeader(
3595
            $headers,
3596
            Resources::X_MS_LEASE_ID,
3597
            $options->getLeaseId()
3598
        );
3599
        
3600
        $this->addOptionalHeader(
3601
            $headers,
3602
            Resources::X_MS_SOURCE_LEASE_ID,
3603
            $options->getSourceLeaseId()
3604
        );
3605
        
3606
        $options->setLocationMode(LocationMode::PRIMARY_ONLY);
3607
        
3608
        return $this->sendAsync(
3609
            $method,
3610
            $headers,
3611
            $queryParams,
3612
            $postParams,
3613
            $destinationBlobPath,
3614
            Resources::STATUS_ACCEPTED,
3615
            Resources::EMPTY_STRING,
3616
            $options
3617
        )->then(function ($response) {
3618
            return CopyBlobResult::create(
3619
                HttpFormatter::formatHeaders($response->getHeaders())
3620
            );
3621
        }, null);
3622
    }
3623
    
3624
    /**
3625
     * Abort a blob copy operation
3626
     *
3627
     * @param string                        $container            name of the container
3628
     * @param string                        $blob                 name of the blob
3629
     * @param string                        $copyId               copy operation identifier.
3630
     * @param Models\BlobServiceOptions     $options              optional parameters
3631
     *
3632
     * @return void
3633
     *
3634
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/abort-copy-blob
3635
     */
3636
    public function abortCopy(
3637
        $container,
3638
        $blob,
3639
        $copyId,
3640
        Models\BlobServiceOptions $options = null
3641
    ) {
3642
        return $this->abortCopyAsync(
3643
            $container,
3644
            $blob,
3645
            $copyId,
3646
            $options
3647
        )->wait();
3648
    }
3649
3650
    /**
3651
     * Creates promise to abort a blob copy operation
3652
     *
3653
     * @param string                        $container            name of the container
3654
     * @param string                        $blob                 name of the blob
3655
     * @param string                        $copyId               copy operation identifier.
3656
     * @param Models\BlobServiceOptions     $options              optional parameters
3657
     *
3658
     * @return \GuzzleHttp\Promise\PromiseInterface
3659
     *
3660
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/abort-copy-blob
3661
     */
3662
    public function abortCopyAsync(
3663
        $container,
3664
        $blob,
3665
        $copyId,
3666
        Models\BlobServiceOptions $options = null
3667
    ) {
3668
        Validate::isString($container, 'container');
3669
        Validate::isString($blob, 'blob');
3670
        Validate::isString($copyId, 'copyId');
3671
        Validate::notNullOrEmpty($container, 'container');
3672
        Validate::notNullOrEmpty($blob, 'blob');
3673
        Validate::notNullOrEmpty($copyId, 'copyId');
3674
        
3675
        $method              = Resources::HTTP_PUT;
3676
        $headers             = array();
3677
        $postParams          = array();
3678
        $queryParams         = array();
3679
        $destinationBlobPath = $this->_createPath(
3680
            $container,
3681
            $blob
3682
        );
3683
        
3684
        if (is_null($options)) {
3685
            $options = new BlobServiceOptions();
3686
        }
3687
        
3688
        $this->addOptionalQueryParam(
3689
            $queryParams,
3690
            Resources::QP_TIMEOUT,
3691
            $options->getTimeout()
3692
        );
3693
3694
        $this->addOptionalQueryParam(
3695
            $queryParams,
3696
            Resources::QP_COMP,
3697
            'copy'
3698
        );
3699
3700
        $this->addOptionalQueryParam(
3701
            $queryParams,
3702
            Resources::QP_COPY_ID,
3703
            $copyId
3704
        );
3705
        
3706
        $this->addOptionalHeader(
3707
            $headers,
3708
            Resources::X_MS_LEASE_ID,
3709
            $options->getLeaseId()
3710
        );
3711
        
3712
        $this->addOptionalHeader(
3713
            $headers,
3714
            Resources::X_MS_COPY_ACTION,
3715
            'abort'
3716
        );
3717
        
3718
        return $this->sendAsync(
3719
            $method,
3720
            $headers,
3721
            $queryParams,
3722
            $postParams,
3723
            $destinationBlobPath,
3724
            Resources::STATUS_NO_CONTENT,
3725
            Resources::EMPTY_STRING,
3726
            $options
3727
        );
3728
    }
3729
        
3730
    /**
3731
     * Establishes an exclusive write lock on a blob. To write to a locked
3732
     * blob, a client must provide a lease ID.
3733
     *
3734
     * @param string                     $container         name of the container
3735
     * @param string                     $blob              name of the blob
3736
     * @param string                     $proposedLeaseId   lease id when acquiring
3737
     * @param int                        $leaseDuration     the lease duration. A non-infinite
3738
     *                                                      lease can be between 15 and 60 seconds.
3739
     *                                                      Default is never to expire.
3740
     * @param Models\BlobServiceOptions  $options           optional parameters
3741
     *
3742
     * @return Models\LeaseResult
3743
     *
3744
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
3745
     */
3746
    public function acquireLease(
3747
        $container,
3748
        $blob,
3749
        $proposedLeaseId = null,
3750
        $leaseDuration = null,
3751
        Models\BlobServiceOptions $options = null
3752
    ) {
3753
        return $this->acquireLeaseAsync(
3754
            $container,
3755
            $blob,
3756
            $proposedLeaseId,
3757
            $leaseDuration,
3758
            $options
3759
        )->wait();
3760
    }
3761
3762
    /**
3763
     * Creates promise to establish an exclusive one-minute write lock on a blob.
3764
     * To write to a locked blob, a client must provide a lease ID.
3765
     *
3766
     * @param string                     $container         name of the container
3767
     * @param string                     $blob              name of the blob
3768
     * @param string                     $proposedLeaseId   lease id when acquiring
3769
     * @param int                        $leaseDuration     the lease duration. A non-infinite
3770
     *                                                      lease can be between 15 and 60 seconds.
3771
     *                                                      Default is never to expire.
3772
     * @param Models\BlobServiceOptions  $options           optional parameters
3773
     *
3774
     * @return \GuzzleHttp\Promise\PromiseInterface
3775
     *
3776
     * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx
3777
     */
3778
    public function acquireLeaseAsync(
3779
        $container,
3780
        $blob,
3781
        $proposedLeaseId = null,
3782
        $leaseDuration = null,
3783
        Models\BlobServiceOptions $options = null
3784
    ) {
3785
        if ($options === null) {
3786
            $options = new BlobServiceOptions();
3787
        }
3788
3789
        if ($leaseDuration === null) {
3790
            $leaseDuration = -1;
3791
        }
3792
3793
        return $this->_putLeaseAsyncImpl(
3794
            LeaseMode::ACQUIRE_ACTION,
3795
            $container,
3796
            $blob,
3797
            $proposedLeaseId,
3798
            $leaseDuration,
3799
            null /* leaseId */,
3800
            null /* breakPeriod */,
3801
            self::getStatusCodeOfLeaseAction(LeaseMode::ACQUIRE_ACTION),
3802
            $options,
3803
            $options->getAccessConditions()
0 ignored issues
show
Documentation introduced by
$options->getAccessConditions() is of type array<integer,object<Mic...odels\AccessCondition>>, but the function expects a null|object<MicrosoftAzu...Models\AccessCondition>.

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...
3804
        )->then(function ($response) {
3805
            return LeaseResult::create(
3806
                HttpFormatter::formatHeaders($response->getHeaders())
3807
            );
3808
        }, null);
3809
    }
3810
    
3811
    /**
3812
     * change an existing lease
3813
     *
3814
     * @param string                    $container         name of the container
3815
     * @param string                    $blob              name of the blob
3816
     * @param string                    $leaseId           lease id when acquiring
3817
     * @param string                    $proposedLeaseId   lease id when acquiring
3818
     * @param Models\BlobServiceOptions $options           optional parameters
3819
     *
3820
     * @return Models\LeaseResult
3821
     *
3822
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3823
     */
3824
    public function changeLease(
3825
        $container,
3826
        $blob,
3827
        $leaseId,
3828
        $proposedLeaseId,
3829
        Models\BlobServiceOptions $options = null
3830
    ) {
3831
        return $this->changeLeaseAsync(
3832
            $container,
3833
            $blob,
3834
            $leaseId,
3835
            $proposedLeaseId,
3836
            $options
3837
        )->wait();
3838
    }
3839
3840
    /**
3841
     * Creates promise to change an existing lease
3842
     *
3843
     * @param string                    $container         name of the container
3844
     * @param string                    $blob              name of the blob
3845
     * @param string                    $leaseId           lease id when acquiring
3846
     * @param string                    $proposedLeaseId   the proposed lease id
3847
     * @param Models\BlobServiceOptions $options           optional parameters
3848
     *
3849
     * @return \GuzzleHttp\Promise\PromiseInterface
3850
     *
3851
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3852
     */
3853 View Code Duplication
    public function changeLeaseAsync(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3854
        $container,
3855
        $blob,
3856
        $leaseId,
3857
        $proposedLeaseId,
3858
        Models\BlobServiceOptions $options = null
3859
    ) {
3860
        return $this->_putLeaseAsyncImpl(
3861
            LeaseMode::CHANGE_ACTION,
3862
            $container,
3863
            $blob,
3864
            $proposedLeaseId,
3865
            null /* leaseDuration */,
3866
            $leaseId,
3867
            null /* breakPeriod */,
3868
            self::getStatusCodeOfLeaseAction(LeaseMode::RENEW_ACTION),
3869
            is_null($options) ? new BlobServiceOptions() : $options
3870
        )->then(function ($response) {
3871
            return LeaseResult::create(
3872
                HttpFormatter::formatHeaders($response->getHeaders())
3873
            );
3874
        }, null);
3875
    }
3876
    
3877
    /**
3878
     * Renews an existing lease
3879
     *
3880
     * @param string                    $container name of the container
3881
     * @param string                    $blob      name of the blob
3882
     * @param string                    $leaseId   lease id when acquiring
3883
     * @param Models\BlobServiceOptions $options   optional parameters
3884
     *
3885
     * @return Models\LeaseResult
3886
     *
3887
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3888
     */
3889
    public function renewLease(
3890
        $container,
3891
        $blob,
3892
        $leaseId,
3893
        Models\BlobServiceOptions $options = null
3894
    ) {
3895
        return $this->renewLeaseAsync(
3896
            $container,
3897
            $blob,
3898
            $leaseId,
3899
            $options
3900
        )->wait();
3901
    }
3902
3903
    /**
3904
     * Creates promise to renew an existing lease
3905
     *
3906
     * @param string                    $container name of the container
3907
     * @param string                    $blob      name of the blob
3908
     * @param string                    $leaseId   lease id when acquiring
3909
     * @param Models\BlobServiceOptions $options   optional parameters
3910
     *
3911
     * @return \GuzzleHttp\Promise\PromiseInterface
3912
     *
3913
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3914
     */
3915 View Code Duplication
    public function renewLeaseAsync(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
3916
        $container,
3917
        $blob,
3918
        $leaseId,
3919
        Models\BlobServiceOptions $options = null
3920
    ) {
3921
        return $this->_putLeaseAsyncImpl(
3922
            LeaseMode::RENEW_ACTION,
3923
            $container,
3924
            $blob,
3925
            null /* proposedLeaseId */,
3926
            null /* leaseDuration */,
3927
            $leaseId,
3928
            null /* breakPeriod */,
3929
            self::getStatusCodeOfLeaseAction(LeaseMode::RENEW_ACTION),
3930
            is_null($options) ? new BlobServiceOptions() : $options
3931
        )->then(function ($response) {
3932
            return LeaseResult::create(
3933
                HttpFormatter::formatHeaders($response->getHeaders())
3934
            );
3935
        }, null);
3936
    }
3937
3938
    /**
3939
     * Frees the lease if it is no longer needed so that another client may
3940
     * immediately acquire a lease against the blob.
3941
     *
3942
     * @param string                    $container name of the container
3943
     * @param string                    $blob      name of the blob
3944
     * @param string                    $leaseId   lease id when acquiring
3945
     * @param Models\BlobServiceOptions $options   optional parameters
3946
     *
3947
     * @return void
3948
     *
3949
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3950
     */
3951
    public function releaseLease(
3952
        $container,
3953
        $blob,
3954
        $leaseId,
3955
        Models\BlobServiceOptions $options = null
3956
    ) {
3957
        $this->releaseLeaseAsync($container, $blob, $leaseId, $options)->wait();
3958
    }
3959
    
3960
    /**
3961
     * Creates promise to free the lease if it is no longer needed so that
3962
     * another client may immediately acquire a lease against the blob.
3963
     *
3964
     * @param string                    $container name of the container
3965
     * @param string                    $blob      name of the blob
3966
     * @param string                    $leaseId   lease id when acquiring
3967
     * @param Models\BlobServiceOptions $options   optional parameters
3968
     *
3969
     * @return \GuzzleHttp\Promise\PromiseInterface
3970
     *
3971
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
3972
     */
3973
    public function releaseLeaseAsync(
3974
        $container,
3975
        $blob,
3976
        $leaseId,
3977
        Models\BlobServiceOptions $options = null
3978
    ) {
3979
        return $this->_putLeaseAsyncImpl(
3980
            LeaseMode::RELEASE_ACTION,
3981
            $container,
3982
            $blob,
3983
            null /* proposedLeaseId */,
3984
            null /* leaseDuration */,
3985
            $leaseId,
3986
            null /* breakPeriod */,
3987
            self::getStatusCodeOfLeaseAction(LeaseMode::RELEASE_ACTION),
3988
            is_null($options) ? new BlobServiceOptions() : $options
3989
        );
3990
    }
3991
    
3992
    /**
3993
     * Ends the lease but ensure that another client cannot acquire a new lease until
3994
     * the current lease period has expired.
3995
     *
3996
     * @param string                    $container     name of the container
3997
     * @param string                    $blob          name of the blob
3998
     * @param int                       $breakPeriod   the proposed duration of seconds that
3999
     *                                                 lease should continue before it it broken,
4000
     *                                                 between 0 and 60 seconds.
4001
     * @param Models\BlobServiceOptions $options   optional parameters
4002
     *
4003
     * @return BreakLeaseResult
4004
     *
4005
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
4006
     */
4007
    public function breakLease(
4008
        $container,
4009
        $blob,
4010
        $breakPeriod = null,
4011
        Models\BlobServiceOptions $options = null
4012
    ) {
4013
        return $this->breakLeaseAsync(
4014
            $container,
4015
            $blob,
4016
            $options
4017
        )->wait();
4018
    }
4019
4020
    /**
4021
     * Creates promise to end the lease but ensure that another client cannot
4022
     * acquire a new lease until the current lease period has expired.
4023
     *
4024
     * @param string                    $container name of the container
4025
     * @param string                    $blob      name of the blob
4026
     * @param Models\BlobServiceOptions $options   optional parameters
4027
     *
4028
     * @return \GuzzleHttp\Promise\PromiseInterface
4029
     *
4030
     * @see https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/lease-blob
4031
     */
4032 View Code Duplication
    public function breakLeaseAsync(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
4033
        $container,
4034
        $blob,
4035
        $breakPeriod = null,
4036
        Models\BlobServiceOptions $options = null
4037
    ) {
4038
        return $this->_putLeaseAsyncImpl(
4039
            LeaseMode::BREAK_ACTION,
4040
            $container,
4041
            $blob,
4042
            null /* proposedLeaseId */,
4043
            null /* leaseDuration */,
4044
            null /* leaseId */,
4045
            $breakPeriod,
4046
            self::getStatusCodeOfLeaseAction(LeaseMode::BREAK_ACTION),
4047
            is_null($options) ? new BlobServiceOptions() : $options
4048
        )->then(function ($response) {
4049
            return BreakLeaseResult::create(
4050
                HttpFormatter::formatHeaders($response->getHeaders())
4051
            );
4052
        }, null);
4053
    }
4054
4055
    /**
4056
     * Adds optional header to headers if set
4057
     *
4058
     * @param array                  $headers         The array of request headers.
4059
     * @param Models\AccessCondition $accessCondition The access condition object.
0 ignored issues
show
Documentation introduced by
There is no parameter named $accessCondition. Did you maybe mean $accessConditions?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
4060
     *
4061
     * @return array
4062
     */
4063
    public function addOptionalAccessConditionHeader(
4064
        array $headers,
4065
        array $accessConditions = null
4066
    ) {
4067
        if (!empty($accessConditions)) {
4068
            foreach ($accessConditions as $accessCondition) {
4069
                if (!is_null($accessCondition)) {
4070
                    $header = $accessCondition->getHeader();
4071
4072
                    if ($header != Resources::EMPTY_STRING) {
4073
                        $value = $accessCondition->getValue();
4074
                        if ($value instanceof \DateTime) {
4075
                            $value = gmdate(
4076
                                Resources::AZURE_DATE_FORMAT,
4077
                                $value->getTimestamp()
4078
                            );
4079
                        }
4080
                        $headers[$header] = $value;
4081
                    }
4082
                }
4083
            }
4084
        }
4085
4086
        return $headers;
4087
    }
4088
4089
    /**
4090
     * Adds optional header to headers if set
4091
     *
4092
     * @param array                  $headers         The array of request headers.
4093
     * @param array                  $accessCondition The access condition object.
0 ignored issues
show
Documentation introduced by
There is no parameter named $accessCondition. Did you maybe mean $accessConditions?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
4094
     *
4095
     * @return array
4096
     */
4097
    public function addOptionalSourceAccessConditionHeader(
4098
        array $headers,
4099
        array $accessConditions = null
4100
    ) {
4101
        if (!empty($accessConditions)) {
4102
            foreach ($accessConditions as $accessCondition) {
4103
                if (!is_null($accessCondition)) {
4104
                    $header     = $accessCondition->getHeader();
4105
                    $headerName = null;
4106
                    if (!empty($header)) {
4107 View Code Duplication
                        switch ($header) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
4108
                            case Resources::IF_MATCH:
4109
                                $headerName = Resources::X_MS_SOURCE_IF_MATCH;
4110
                                break;
4111
                            case Resources::IF_UNMODIFIED_SINCE:
4112
                                $headerName = Resources::X_MS_SOURCE_IF_UNMODIFIED_SINCE;
4113
                                break;
4114
                            case Resources::IF_MODIFIED_SINCE:
4115
                                $headerName = Resources::X_MS_SOURCE_IF_MODIFIED_SINCE;
4116
                                break;
4117
                            case Resources::IF_NONE_MATCH:
4118
                                $headerName = Resources::X_MS_SOURCE_IF_NONE_MATCH;
4119
                                break;
4120
                            default:
4121
                                throw new \Exception(Resources::INVALID_ACH_MSG);
4122
                                break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
4123
                        }
4124
                    }
4125
                    $value = $accessCondition->getValue();
4126
                    if ($value instanceof \DateTime) {
4127
                        $value = gmdate(
4128
                            Resources::AZURE_DATE_FORMAT,
4129
                            $value->getTimestamp()
4130
                        );
4131
                    }
4132
4133
                    $this->addOptionalHeader($headers, $headerName, $value);
4134
                }
4135
            }
4136
        }
4137
4138
        return $headers;
4139
    }
4140
}
4141