AliOssAdapter::getVisibility()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 3
eloc 11
c 1
b 0
f 1
nc 3
nop 1
dl 0
loc 17
rs 9.9
1
<?php
2
/**
3
 * Created by jacob.
4
 * Date: 2016/5/19 0019
5
 * Time: 下午 17:07
6
 */
7
8
namespace Jacobcyl\AliOSS;
9
10
use Illuminate\Support\Arr;
0 ignored issues
show
Bug introduced by
The type Illuminate\Support\Arr was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
11
use League\Flysystem\Adapter\AbstractAdapter;
0 ignored issues
show
Bug introduced by
The type League\Flysystem\Adapter\AbstractAdapter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
12
use League\Flysystem\AdapterInterface;
0 ignored issues
show
Bug introduced by
The type League\Flysystem\AdapterInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use League\Flysystem\Config;
0 ignored issues
show
Bug introduced by
The type League\Flysystem\Config was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use League\Flysystem\Util;
0 ignored issues
show
Bug introduced by
The type League\Flysystem\Util was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use OSS\Core\OssException;
16
use OSS\OssClient;
17
use Log;
18
use Illuminate\Contracts\Filesystem\FileNotFoundException;
0 ignored issues
show
Bug introduced by
The type Illuminate\Contracts\Fil...m\FileNotFoundException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
20
class AliOssAdapter extends AbstractAdapter
21
{
22
    /**
23
     * @var Log debug Mode true|false
24
     */
25
    protected $debug;
26
    /**
27
     * @var array
28
     */
29
    protected static $resultMap = [
30
        'Body'           => 'raw_contents',
31
        'Content-Length' => 'size',
32
        'ContentType'    => 'mimetype',
33
        'Size'           => 'size',
34
        'StorageClass'   => 'storage_class',
35
    ];
36
37
    /**
38
     * @var array
39
     */
40
    protected static $metaOptions = [
41
        'CacheControl',
42
        'Expires',
43
        'ServerSideEncryption',
44
        'Metadata',
45
        'ACL',
46
        'ContentType',
47
        'ContentDisposition',
48
        'ContentLanguage',
49
        'ContentEncoding',
50
    ];
51
52
    protected static $metaMap = [
53
        'CacheControl'         => 'Cache-Control',
54
        'Expires'              => 'Expires',
55
        'ServerSideEncryption' => 'x-oss-server-side-encryption',
56
        'Metadata'             => 'x-oss-metadata-directive',
57
        'ACL'                  => 'x-oss-object-acl',
58
        'ContentType'          => 'Content-Type',
59
        'ContentDisposition'   => 'Content-Disposition',
60
        'ContentLanguage'      => 'response-content-language',
61
        'ContentEncoding'      => 'Content-Encoding',
62
    ];
63
64
    //Aliyun OSS Client OssClient
65
    protected $client;
66
    //bucket name
67
    protected $bucket;
68
69
    protected $endPoint;
70
71
    protected $cdnDomain;
72
73
    protected $ssl;
74
75
    protected $isCname;
76
77
    //配置
78
    protected $options = [
79
        'Multipart'   => 128
80
    ];
81
82
83
    /**
84
     * AliOssAdapter constructor.
85
     *
86
     * @param OssClient $client
87
     * @param string    $bucket
88
     * @param string    $endPoint
89
     * @param bool      $ssl
90
     * @param bool      $isCname
91
     * @param bool      $debug
92
     * @param null      $prefix
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $prefix is correct as it would always require null to be passed?
Loading history...
93
     * @param array     $options
94
     */
95
    public function __construct(
96
        OssClient $client,
97
        $bucket,
98
        $endPoint,
99
        $ssl,
100
        $isCname = false,
101
        $debug = false,
102
        $cdnDomain,
103
        $prefix = null,
104
        array $options = []
105
    )
106
    {
107
        $this->debug = $debug;
0 ignored issues
show
Documentation Bug introduced by
It seems like $debug of type boolean is incompatible with the declared type Log of property $debug.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
108
        $this->client = $client;
109
        $this->bucket = $bucket;
110
        $this->setPathPrefix($prefix);
111
        $this->endPoint = $endPoint;
112
        $this->ssl = $ssl;
113
        $this->isCname = $isCname;
114
        $this->cdnDomain = $cdnDomain;
115
        $this->options = array_merge($this->options, $options);
116
    }
117
118
    /**
119
     * Get the OssClient bucket.
120
     *
121
     * @return string
122
     */
123
    public function getBucket()
124
    {
125
        return $this->bucket;
126
    }
127
128
    /**
129
     * Get the OSSClient instance.
130
     *
131
     * @return OssClient
132
     */
133
    public function getClient()
134
    {
135
        return $this->client;
136
    }
137
138
    /**
139
     * Write a new file.
140
     *
141
     * @param string $path
142
     * @param string $contents
143
     * @param Config $config Config object
144
     *
145
     * @return array|false false on failure file meta data on success
146
     */
147
    public function write($path, $contents, Config $config)
148
    {
149
        $object = $this->applyPathPrefix($path);
150
        $options = $this->getOptions($this->options, $config);
151
152
        if (! isset($options[OssClient::OSS_LENGTH])) {
153
            $options[OssClient::OSS_LENGTH] = Util::contentSize($contents);
154
        }
155
        if (! isset($options[OssClient::OSS_CONTENT_TYPE])) {
156
            $options[OssClient::OSS_CONTENT_TYPE] = Util::guessMimeType($path, $contents);
157
        }
158
        try {
159
            $this->client->putObject($this->bucket, $object, $contents, $options);
160
        } catch (OssException $e) {
161
            $this->logErr(__FUNCTION__, $e);
162
            return false;
163
        }
164
        return $this->normalizeResponse($options, $path);
165
    }
166
167
    /**
168
     * Write a new file using a stream.
169
     *
170
     * @param string $path
171
     * @param resource $resource
172
     * @param Config $config Config object
173
     *
174
     * @return array|false false on failure file meta data on success
175
     */
176
    public function writeStream($path, $resource, Config $config)
177
    {
178
        $options = $this->getOptions($this->options, $config);
0 ignored issues
show
Unused Code introduced by
The assignment to $options is dead and can be removed.
Loading history...
179
        $contents = stream_get_contents($resource);
180
181
        return $this->write($path, $contents, $config);
182
    }
183
184
    public function writeFile($path, $filePath, Config $config){
185
        $object = $this->applyPathPrefix($path);
186
        $options = $this->getOptions($this->options, $config);
187
188
        $options[OssClient::OSS_CHECK_MD5] = true;
189
190
        if (! isset($options[OssClient::OSS_CONTENT_TYPE])) {
191
            $options[OssClient::OSS_CONTENT_TYPE] = Util::guessMimeType($path, '');
192
        }
193
        try {
194
            $this->client->uploadFile($this->bucket, $object, $filePath, $options);
195
        } catch (OssException $e) {
196
            $this->logErr(__FUNCTION__, $e);
197
            return false;
198
        }
199
        return $this->normalizeResponse($options, $path);
200
    }
201
202
    /**
203
     * Update a file.
204
     *
205
     * @param string $path
206
     * @param string $contents
207
     * @param Config $config Config object
208
     *
209
     * @return array|false false on failure file meta data on success
210
     */
211
    public function update($path, $contents, Config $config)
212
    {
213
        if (! $config->has('visibility') && ! $config->has('ACL')) {
214
            $config->set(static::$metaMap['ACL'], $this->getObjectACL($path));
215
        }
216
        // $this->delete($path);
217
        return $this->write($path, $contents, $config);
218
    }
219
220
    /**
221
     * Update a file using a stream.
222
     *
223
     * @param string $path
224
     * @param resource $resource
225
     * @param Config $config Config object
226
     *
227
     * @return array|false false on failure file meta data on success
228
     */
229
    public function updateStream($path, $resource, Config $config)
230
    {
231
        $contents = stream_get_contents($resource);
232
        return $this->update($path, $contents, $config);
233
    }
234
235
    /**
236
     * {@inheritdoc}
237
     */
238
    public function rename($path, $newpath)
239
    {
240
        if (! $this->copy($path, $newpath)){
241
            return false;
242
        }
243
244
        return $this->delete($path);
245
    }
246
247
    /**
248
     * {@inheritdoc}
249
     */
250
    public function copy($path, $newpath)
251
    {
252
        $object = $this->applyPathPrefix($path);
253
        $newObject = $this->applyPathPrefix($newpath);
254
        try{
255
            $this->client->copyObject($this->bucket, $object, $this->bucket, $newObject);
256
        } catch (OssException $e) {
257
            $this->logErr(__FUNCTION__, $e);
258
            return false;
259
        }
260
261
        return true;
262
    }
263
264
    /**
265
     * {@inheritdoc}
266
     */
267
    public function delete($path)
268
    {
269
        $bucket = $this->bucket;
270
        $object = $this->applyPathPrefix($path);
271
272
        try{
273
            $this->client->deleteObject($bucket, $object);
274
        }catch (OssException $e) {
275
            $this->logErr(__FUNCTION__, $e);
276
            return false;
277
        }
278
279
        return ! $this->has($path);
280
    }
281
282
    /**
283
     * {@inheritdoc}
284
     */
285
    public function deleteDir($dirname)
286
    {
287
        $dirname = rtrim($this->applyPathPrefix($dirname), '/').'/';
288
        $dirObjects = $this->listDirObjects($dirname, true);
289
290
        if(count($dirObjects['objects']) > 0 ){
291
292
            foreach($dirObjects['objects'] as $object)
293
            {
294
                $objects[] = $object['Key'];
295
            }
296
297
            try {
298
                $this->client->deleteObjects($this->bucket, $objects);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $objects seems to be defined by a foreach iteration on line 292. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
299
            } catch (OssException $e) {
300
                $this->logErr(__FUNCTION__, $e);
301
                return false;
302
            }
303
304
        }
305
306
        try {
307
            $this->client->deleteObject($this->bucket, $dirname);
308
        } catch (OssException $e) {
309
            $this->logErr(__FUNCTION__, $e);
310
            return false;
311
        }
312
313
        return true;
314
    }
315
316
    /**
317
     * 列举文件夹内文件列表;可递归获取子文件夹;
318
     * @param string $dirname 目录
319
     * @param bool $recursive 是否递归
320
     * @return mixed
321
     * @throws OssException
322
     */
323
    public function listDirObjects($dirname = '', $recursive =  false)
324
    {
325
        $delimiter = '/';
326
        $nextMarker = '';
327
        $maxkeys = 1000;
328
329
        //存储结果
330
        $result = [];
331
332
        while(true){
333
            $options = [
334
                'delimiter' => $delimiter,
335
                'prefix'    => $dirname,
336
                'max-keys'  => $maxkeys,
337
                'marker'    => $nextMarker,
338
            ];
339
340
            try {
341
                $listObjectInfo = $this->client->listObjects($this->bucket, $options);
342
            } catch (OssException $e) {
343
                $this->logErr(__FUNCTION__, $e);
344
                // return false;
345
                throw $e;
346
            }
347
348
            $nextMarker = $listObjectInfo->getNextMarker(); // 得到nextMarker,从上一次listObjects读到的最后一个文件的下一个文件开始继续获取文件列表
349
            $objectList = $listObjectInfo->getObjectList(); // 文件列表
350
            $prefixList = $listObjectInfo->getPrefixList(); // 目录列表
351
352
            if (!empty($objectList)) {
353
                foreach ($objectList as $objectInfo) {
354
355
                    $object['Prefix']       = $dirname;
356
                    $object['Key']          = $objectInfo->getKey();
357
                    $object['LastModified'] = $objectInfo->getLastModified();
358
                    $object['eTag']         = $objectInfo->getETag();
359
                    $object['Type']         = $objectInfo->getType();
360
                    $object['Size']         = $objectInfo->getSize();
361
                    $object['StorageClass'] = $objectInfo->getStorageClass();
362
363
                    $result['objects'][] = $object;
364
                }
365
            }else{
366
                $result["objects"] = [];
367
            }
368
369
            if (!empty($prefixList)) {
370
                foreach ($prefixList as $prefixInfo) {
371
                    $result['prefix'][] = $prefixInfo->getPrefix();
372
                }
373
            }else{
374
                $result['prefix'] = [];
375
            }
376
377
            //递归查询子目录所有文件
378
            if($recursive){
379
                foreach( $result['prefix'] as $pfix){
380
                    $next  =  $this->listDirObjects($pfix , $recursive);
381
                    $result["objects"] = array_merge($result['objects'], $next["objects"]);
382
                }
383
            }
384
385
            //没有更多结果了
386
            if ($nextMarker === '') {
387
                break;
388
            }
389
        }
390
391
        return $result;
392
    }
393
394
    /**
395
     * {@inheritdoc}
396
     */
397
    public function createDir($dirname, Config $config)
398
    {
399
        $object = $this->applyPathPrefix($dirname);
400
        $options = $this->getOptionsFromConfig($config);
401
402
        try {
403
            $this->client->createObjectDir($this->bucket, $object, $options);
404
        } catch (OssException $e) {
405
            $this->logErr(__FUNCTION__, $e);
406
            return false;
407
        }
408
409
        return ['path' => $dirname, 'type' => 'dir'];
410
    }
411
412
    /**
413
     * {@inheritdoc}
414
     */
415
    public function setVisibility($path, $visibility)
416
    {
417
        $object = $this->applyPathPrefix($path);
418
        $acl = ( $visibility === AdapterInterface::VISIBILITY_PUBLIC ) ? OssClient::OSS_ACL_TYPE_PUBLIC_READ : OssClient::OSS_ACL_TYPE_PRIVATE;
419
420
        $this->client->putObjectAcl($this->bucket, $object, $acl);
421
422
        return compact('visibility');
423
    }
424
425
    /**
426
     * {@inheritdoc}
427
     */
428
    public function has($path)
429
    {
430
        $object = $this->applyPathPrefix($path);
431
432
        return $this->client->doesObjectExist($this->bucket, $object);
433
    }
434
435
    /**
436
     * {@inheritdoc}
437
     */
438
    public function read($path)
439
    {
440
        $result = $this->readObject($path);
441
        $result['contents'] = (string) $result['raw_contents'];
442
        unset($result['raw_contents']);
443
        return $result;
444
    }
445
446
    /**
447
     * {@inheritdoc}
448
     */
449
    public function readStream($path)
450
    {
451
        $result = $this->readObject($path);
452
        if (is_resource($result['raw_contents'])) {
453
            $result['stream'] = $result['raw_contents'];
454
            $result['raw_contents']->detachStream();
455
        } else {
456
            $result['stream'] = fopen('php://temp', 'r+');
457
            fwrite($result['stream'], $result['raw_contents']);
458
        }
459
        rewind($result['stream']);
460
        // Ensure the EntityBody object destruction doesn't close the stream
461
        unset($result['raw_contents']);
462
        return $result;
463
    }
464
465
    /**
466
     * Read an object from the OssClient.
467
     *
468
     * @param string $path
469
     *
470
     * @return array
471
     */
472
    protected function readObject($path)
473
    {
474
        $object = $this->applyPathPrefix($path);
475
476
        $result['Body'] = $this->client->getObject($this->bucket, $object);
0 ignored issues
show
Comprehensibility Best Practice introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = array(); before regardless.
Loading history...
477
        $result = array_merge($result, ['type' => 'file']);
478
        return $this->normalizeResponse($result, $path);
479
    }
480
481
    /**
482
     * {@inheritdoc}
483
     */
484
    public function listContents($directory = '', $recursive = false)
485
    {
486
        $dirObjects = $this->listDirObjects($directory, true);
487
        $contents = $dirObjects["objects"];
488
489
        $result = array_map([$this, 'normalizeResponse'], $contents);
490
        $result = array_filter($result, function ($value) {
491
            return $value['path'] !== false;
492
        });
493
494
        return Util::emulateDirectories($result);
495
    }
496
497
    /**
498
     * {@inheritdoc}
499
     */
500
    public function getMetadata($path)
501
    {
502
        $object = $this->applyPathPrefix($path);
503
504
        try {
505
            $objectMeta = $this->client->getObjectMeta($this->bucket, $object);
506
        } catch (OssException $e) {
507
            $this->logErr(__FUNCTION__, $e);
508
            return false;
509
        }
510
511
        return $objectMeta;
512
    }
513
514
    /**
515
     * {@inheritdoc}
516
     */
517
    public function getSize($path)
518
    {
519
        $object = $this->getMetadata($path);
520
        $object['size'] = $object['content-length'];
521
        return $object;
522
    }
523
524
    /**
525
     * {@inheritdoc}
526
     */
527
    public function getMimetype($path)
528
    {
529
        if( $object = $this->getMetadata($path))
530
            $object['mimetype'] = $object['content-type'];
531
        return $object;
532
    }
533
534
    /**
535
     * {@inheritdoc}
536
     */
537
    public function getTimestamp($path)
538
    {
539
        if( $object = $this->getMetadata($path))
540
            $object['timestamp'] = strtotime( $object['last-modified'] );
541
        return $object;
542
    }
543
544
    /**
545
     * {@inheritdoc}
546
     */
547
    public function getVisibility($path)
548
    {
549
        $object = $this->applyPathPrefix($path);
550
        try {
551
            $acl = $this->client->getObjectAcl($this->bucket, $object);
552
        } catch (OssException $e) {
553
            $this->logErr(__FUNCTION__, $e);
554
            return false;
555
        }
556
557
        if ($acl == OssClient::OSS_ACL_TYPE_PUBLIC_READ ){
558
            $res['visibility'] = AdapterInterface::VISIBILITY_PUBLIC;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$res was never initialized. Although not strictly required by PHP, it is generally a good practice to add $res = array(); before regardless.
Loading history...
559
        }else{
560
            $res['visibility'] = AdapterInterface::VISIBILITY_PRIVATE;
561
        }
562
563
        return $res;
564
    }
565
566
567
    /**
568
     * @param $path
569
     *
570
     * @return string
571
     */
572
    public function getUrl( $path )
573
    {
574
        if (!$this->has($path)) throw new FileNotFoundException($path.' not found');
575
        return ( $this->ssl ? 'https://' : 'http://' ) . ( $this->isCname ? ( $this->cdnDomain == '' ? $this->endPoint : $this->cdnDomain ) : $this->bucket . '.' . $this->endPoint ) . '/' . ltrim($path, '/');
576
    }
577
578
579
    /**
580
     * @param $path
581
     * @param $expire
582
     * @param $options
583
     * @return string
584
     * @throws FileNotFoundException
585
     * @throws OssException
586
     */
587
    public function getTemporaryUrl($path, $expire = 600, $options) {
588
        if (!$this->has($path))
589
            throw new FileNotFoundException($path.' not found');
590
        $method = OssClient::OSS_HTTP_GET;
591
        if (Arr::has($options, OssClient::OSS_METHOD)) {
592
            $method = $options['method'];
593
        }
594
        return $this->getClient()
595
            ->signUrl(
596
                $this->getBucket(),
597
                $path,
598
                $expire,
599
                $method,
600
                $options
601
            );
602
    }
603
604
605
    /**
606
     * The the ACL visibility.
607
     *
608
     * @param string $path
609
     *
610
     * @return string
611
     */
612
    protected function getObjectACL($path)
613
    {
614
        $metadata = $this->getVisibility($path);
615
616
        return $metadata['visibility'] === AdapterInterface::VISIBILITY_PUBLIC ? OssClient::OSS_ACL_TYPE_PUBLIC_READ : OssClient::OSS_ACL_TYPE_PRIVATE;
617
    }
618
619
    /**
620
     * Normalize a result from OSS.
621
     *
622
     * @param array  $object
623
     * @param string $path
624
     *
625
     * @return array file metadata
626
     */
627
    protected function normalizeResponse(array $object, $path = null)
628
    {
629
        $result = ['path' => $path ?: $this->removePathPrefix(isset($object['Key']) ? $object['Key'] : $object['Prefix'])];
630
        $result['dirname'] = Util::dirname($result['path']);
631
632
        if (isset($object['LastModified'])) {
633
            $result['timestamp'] = strtotime($object['LastModified']);
634
        }
635
636
        if (substr($result['path'], -1) === '/') {
637
            $result['type'] = 'dir';
638
            $result['path'] = rtrim($result['path'], '/');
639
640
            return $result;
641
        }
642
643
        $result = array_merge($result, Util::map($object, static::$resultMap), ['type' => 'file']);
644
645
        return $result;
646
    }
647
648
    /**
649
     * Get options for a OSS call. done
650
     *
651
     * @param array  $options
652
     *
653
     * @return array OSS options
654
     */
655
    protected function getOptions(array $options = [], Config $config = null)
656
    {
657
        $options = array_merge($this->options, $options);
658
659
        if ($config) {
660
            $options = array_merge($options, $this->getOptionsFromConfig($config));
661
        }
662
663
        return $options;
664
    }
665
666
    /**
667
     * Retrieve options from a Config instance. done
668
     *
669
     * @param Config $config
670
     *
671
     * @return array
672
     */
673
    protected function getOptionsFromConfig(Config $config)
674
    {
675
        $options = [];
676
677
        foreach (static::$metaOptions as $option) {
678
            if (! $config->has($option)) {
679
                continue;
680
            }
681
            $options[static::$metaMap[$option]] = $config->get($option);
682
        }
683
684
        if ($visibility = $config->get('visibility')) {
685
            // For local reference
686
            // $options['visibility'] = $visibility;
687
            // For external reference
688
            $options['x-oss-object-acl'] = $visibility === AdapterInterface::VISIBILITY_PUBLIC ? OssClient::OSS_ACL_TYPE_PUBLIC_READ : OssClient::OSS_ACL_TYPE_PRIVATE;
689
        }
690
691
        if ($mimetype = $config->get('mimetype')) {
692
            // For local reference
693
            // $options['mimetype'] = $mimetype;
694
            // For external reference
695
            $options['Content-Type'] = $mimetype;
696
        }
697
698
        return $options;
699
    }
700
701
    /**
702
     * @param $fun string function name : __FUNCTION__
703
     * @param $e
704
     */
705
    protected function logErr($fun, $e){
706
        if( $this->debug ){
707
            Log::error($fun . ": FAILED");
708
            Log::error($e->getMessage());
709
        }
710
    }
711
}
712