Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
92.86% covered (success)
92.86%
39 / 42
87.50% covered (success)
87.50%
7 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
S3
92.86% covered (success)
92.86%
39 / 42
87.50% covered (success)
87.50%
7 / 8
19.13
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 setClient
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getClient
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 uploadFile
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
7
 uploadFileStream
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 rmdir
66.67% covered (warning)
66.67%
6 / 9
0.00% covered (danger)
0.00%
0 / 1
3.33
 mkdir
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 md5File
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Storage;
15
16use Aws\S3\S3Client;
17use Pop\Http\Server\Upload;
18use RecursiveDirectoryIterator;
19use RecursiveIteratorIterator;
20
21/**
22 * AWS S3 storage adapter class
23 *
24 * @category   Pop
25 * @package    Pop\Storage
26 * @author     Nick Sagona, III <dev@nolainteractive.com>
27 * @copyright  Copyright (c) 2009-2023 NOLA Interactive, LLC. (http://www.nolainteractive.com)
28 * @license    http://www.popphp.org/license     New BSD License
29 * @version    1.0.1
30 */
31class S3 extends AbstractAdapter
32{
33
34    /**
35     * S3 client
36     * @var S3Client
37     */
38    protected $client = null;
39
40    /**
41     * Constructor
42     *
43     * @param string   $location
44     * @param S3Client $client
45     */
46    public function __construct($location, S3Client $client)
47    {
48        parent::__construct($location);
49        $this->setClient($client);
50    }
51
52    /**
53     * Set S3 client
54     *
55     * @param  S3Client $client
56     * @return S3
57     */
58    public function setClient(S3Client $client)
59    {
60        $this->client = $client;
61        $this->client->registerStreamWrapper();
62        return $this;
63    }
64
65    /**
66     * Get S3 client
67     *
68     * @return S3Client
69     */
70    public function getClient()
71    {
72        return $this->client;
73    }
74
75    /**
76     * Upload file
77     *
78     * @param  mixed   $file
79     * @param  string  $dest
80     * @param  Upload  $upload
81     * @return string|bool
82     */
83    public function uploadFile($file, $dest = null, Upload $upload = null)
84    {
85        if (is_array($file) && isset($file['name']) && isset($file['tmp_name']) && (null !== $upload) && ($upload->test($file))) {
86            $filename = $upload->checkFilename($file['name']);
87            $location = $this->location . $dest . '/' . $filename;
88            file_put_contents($location, file_get_contents($file['tmp_name']));
89            return $filename;
90        } else if (is_file($file)) {
91            $location = $this->location . $dest . '/' . basename($file);
92            file_put_contents($location, file_get_contents($file));
93            return $file;
94        } else {
95            return false;
96        }
97    }
98
99    /**
100     * Upload file stream
101     *
102     * @param  string  $fileStream
103     * @param  string  $filename
104     * @param  string  $folder
105     * @return string
106     */
107    public function uploadFileStream($fileStream, $filename, $folder = null)
108    {
109        $location = $this->location . $folder . '/' . $filename;
110        file_put_contents($location, $fileStream);
111        return $filename;
112    }
113
114    /**
115     * Remove a directory
116     *
117     * @param  string $dir
118     * @return void
119     */
120    public function rmdir($dir)
121    {
122        $iterator = new RecursiveIteratorIterator(
123            new RecursiveDirectoryIterator($this->location . $dir, RecursiveDirectoryIterator::SKIP_DOTS),
124            RecursiveIteratorIterator::CHILD_FIRST
125        );
126
127        foreach ($iterator as $fileInfo) {
128            if ($fileInfo->isDir()) {
129                rmdir((string)$fileInfo);
130            } else {
131                unlink((string)$fileInfo);
132            }
133        }
134
135        rmdir($this->location . $dir);
136    }
137
138    /**
139     * Make a directory
140     *
141     * @param  string $dir
142     * @return void
143     */
144    public function mkdir($dir)
145    {
146        if (substr($dir, 0, 1) == '/') {
147            $dir = substr($dir, 1);
148        }
149        $this->client->putObject([
150            'Bucket' => str_replace('s3://', '', $this->location),
151            'Key'    => $dir . '/',
152            'Body'   => ''
153        ]);
154    }
155
156    /**
157     * Create MD5 checksum of the file
158     *
159     * @param  string $filename
160     * @return string
161     */
162    public function md5File($filename)
163    {
164        if (substr($filename, 0, 1) == '/') {
165            $filename = substr($filename, 1);
166        }
167        $fileObject = $this->client->getObject([
168            'Bucket' => str_replace('s3://', '', $this->location),
169            'Key'    => $filename,
170        ]);
171
172        return (isset($fileObject['ETag'])) ? str_replace('"', '', $fileObject['ETag']) : false;
173    }
174
175}