1 | <?php |
||
2 | /** |
||
3 | * This file is part of the Simple S3 package. |
||
4 | * |
||
5 | * (c) Mauro Cassani<https://github.com/mauretto78> |
||
6 | * |
||
7 | * For the full copyright and license information, please view the LICENSE |
||
8 | * file that was distributed with this source code. |
||
9 | * |
||
10 | */ |
||
11 | |||
12 | namespace Matecat\SimpleS3\Commands\Handlers; |
||
13 | |||
14 | use Aws\S3\Exception\S3Exception; |
||
15 | use Matecat\SimpleS3\Commands\CommandHandler; |
||
16 | use Matecat\SimpleS3\Helpers\File; |
||
17 | |||
18 | class GetItemsInABucket extends CommandHandler |
||
19 | { |
||
20 | /** |
||
21 | * Get the list of keys in a bucket. |
||
22 | * If 'hydrate' parameter is set to true, an array of hydrated Aws\Result is returned instead. |
||
23 | * |
||
24 | * @param array $params |
||
25 | * |
||
26 | * @return array|mixed |
||
27 | * @throws \Exception |
||
28 | */ |
||
29 | public function handle($params = []) |
||
30 | { |
||
31 | $bucketName = $params['bucket']; |
||
32 | |||
33 | try { |
||
34 | $config = [ |
||
35 | 'Bucket' => $bucketName, |
||
36 | ]; |
||
37 | |||
38 | if (isset($params['prefix'])) { |
||
39 | |||
40 | // add a final slash to prefix |
||
41 | if (false === File::endsWith($params['prefix'], $this->client->getPrefixSeparator())) { |
||
42 | $params['prefix'] .= $this->client->getPrefixSeparator(); |
||
43 | } |
||
44 | |||
45 | $config['Delimiter'] = (isset($params['delimiter'])) ? $params['delimiter'] : $this->client->getPrefixSeparator(); |
||
46 | $config['Prefix'] = $params['prefix']; |
||
47 | } |
||
48 | |||
49 | // 1. If 'exclude-cache' is set, return records always from S3 |
||
50 | if (isset($params['exclude-cache']) and true === $params['exclude-cache']) { |
||
51 | return $this->returnItemsFromS3($bucketName, $config, (isset($params['hydrate'])) ? $params['hydrate'] : null); |
||
52 | } |
||
53 | |||
54 | // 2. If the cache is set and there is a prefix, return records from cache |
||
55 | if ($this->client->hasCache() and isset($config['Prefix'])) { |
||
56 | return $this->returnItemsFromCache($bucketName, $config, (isset($params['hydrate'])) ? $params['hydrate'] : null); |
||
57 | } |
||
58 | |||
59 | // 3. Otherwise, return records from S3 |
||
60 | return $this->returnItemsFromS3($bucketName, $config, (isset($params['hydrate'])) ? $params['hydrate'] : null); |
||
61 | } catch (S3Exception $e) { |
||
62 | if (null !== $this->commandHandlerLogger) { |
||
63 | $this->commandHandlerLogger->logExceptionAndReturnFalse($e); |
||
64 | } |
||
65 | |||
66 | throw $e; |
||
67 | } |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * @param array $params |
||
72 | * |
||
73 | * @return bool |
||
74 | */ |
||
75 | public function validateParams($params = []) |
||
76 | { |
||
77 | return (isset($params['bucket'])); |
||
78 | } |
||
79 | |||
80 | /** |
||
81 | * @param string $bucketName |
||
82 | * @param array $config |
||
83 | * @param null $hydrate |
||
0 ignored issues
–
show
Documentation
Bug
introduced
by
![]() |
|||
84 | * |
||
85 | * @return array |
||
86 | */ |
||
87 | protected function returnItemsFromCache($bucketName, $config, $hydrate = null) |
||
88 | { |
||
89 | $itemsFromCache = $this->client->getCache()->search($bucketName, $config['Prefix']); |
||
90 | |||
91 | // no data was found, try to retrieve data from S3 |
||
92 | if (count($itemsFromCache) == 0) { |
||
93 | return $this->returnItemsFromS3($bucketName, $config, $hydrate); |
||
94 | } |
||
95 | |||
96 | // no hydrate, simply return the array of keys stored in redis |
||
97 | if (null == $hydrate) { |
||
0 ignored issues
–
show
|
|||
98 | if (null !== $this->commandHandlerLogger) { |
||
99 | $this->commandHandlerLogger->log($this, sprintf('Files of \'%s\' bucket were successfully obtained from CACHE', $bucketName)); |
||
100 | } |
||
101 | |||
102 | return $itemsFromCache; |
||
103 | } |
||
104 | |||
105 | // hydrate the key with the entire AWS\Result Object |
||
106 | $items = []; |
||
107 | foreach ($itemsFromCache as $key) { |
||
108 | $version = null; |
||
109 | $originalKey = $key; |
||
110 | |||
111 | if (strpos($key, '<VERSION_ID:') !== false) { |
||
112 | $v = explode('<VERSION_ID:', $key); |
||
113 | $version = str_replace('>', '', $v[1]); |
||
114 | $key = $v[0]; |
||
115 | } |
||
116 | |||
117 | if ($this->client->hasEncoder()) { |
||
118 | $key = $this->client->getEncoder()->decode($key); |
||
119 | } |
||
120 | |||
121 | $items[$originalKey] = $this->client->getItem(['bucket' => $bucketName, 'key' => $key, 'version' => $version]); |
||
122 | } |
||
123 | |||
124 | if (null !== $this->commandHandlerLogger) { |
||
125 | $this->commandHandlerLogger->log($this, sprintf('Files of \'%s\' bucket were successfully obtained from CACHE', $bucketName)); |
||
126 | } |
||
127 | |||
128 | return $items; |
||
129 | } |
||
130 | |||
131 | /** |
||
132 | * @param string $bucketName |
||
133 | * @param array $config |
||
134 | * |
||
135 | * @return array |
||
136 | */ |
||
137 | protected function returnItemsFromS3($bucketName, $config, $hydrate = null) |
||
138 | { |
||
139 | if ($this->client->isBucketVersioned(['bucket' => $bucketName])) { |
||
140 | return $this->returnVersionedItemsFromS3($bucketName, $config, $hydrate); |
||
141 | } |
||
142 | |||
143 | $resultPaginator = $this->client->getConn()->getPaginator('ListObjects', $config); |
||
144 | $items = []; |
||
145 | |||
146 | foreach ($resultPaginator as $result) { |
||
147 | if (is_array($contents = $result->get('Contents'))) { |
||
148 | for ($i = 0; $i < count($contents); $i++) { |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
149 | $key = $contents[$i]['Key']; |
||
150 | |||
151 | if (false === File::endsWith($key, $this->client->getPrefixSeparator())) { |
||
152 | if ($this->client->hasEncoder()) { |
||
153 | $key = $this->client->getEncoder()->decode($key); |
||
154 | } |
||
155 | |||
156 | if (null != $hydrate and true === $hydrate) { |
||
157 | $items[$key] = $this->client->getItem(['bucket' => $bucketName, 'key' => $key]); |
||
158 | } else { |
||
159 | $items[] = $key; |
||
160 | } |
||
161 | |||
162 | // send to cache, just to be sure that S3 is syncronized with cache |
||
163 | if ($this->client->hasCache()) { |
||
164 | $this->client->getCache()->set($bucketName, $contents[$i]['Key'], $this->client->getItem(['bucket' => $bucketName, 'key' => $key])); |
||
165 | } |
||
166 | } |
||
167 | } |
||
168 | } |
||
169 | } |
||
170 | |||
171 | if (null !== $this->commandHandlerLogger) { |
||
172 | $this->commandHandlerLogger->log($this, sprintf('Files were successfully obtained from \'%s\' bucket', $bucketName)); |
||
173 | } |
||
174 | |||
175 | return $items; |
||
176 | } |
||
177 | |||
178 | /** |
||
179 | * @param string $bucketName |
||
180 | * @param array $config |
||
181 | * @param null $hydrate |
||
0 ignored issues
–
show
|
|||
182 | * |
||
183 | * @return array |
||
184 | */ |
||
185 | protected function returnVersionedItemsFromS3($bucketName, $config, $hydrate = null) |
||
186 | { |
||
187 | $results = $this->client->getConn()->listObjectVersions($config); |
||
188 | $items = []; |
||
189 | |||
190 | if (false === isset($results['Versions'])) { |
||
191 | return $items; |
||
192 | } |
||
193 | |||
194 | foreach ($results['Versions'] as $result) { |
||
195 | $key = $result['Key']; |
||
196 | $version = $result['VersionId']; |
||
197 | |||
198 | if (false === File::endsWith($key, $this->client->getPrefixSeparator())) { |
||
199 | if ($this->client->hasEncoder()) { |
||
200 | $key = $this->client->getEncoder()->decode($key); |
||
201 | } |
||
202 | |||
203 | $index = $key.'<VERSION_ID:'.$version.'>'; |
||
204 | |||
205 | if (null != $hydrate and true === $hydrate) { |
||
206 | $items[$index] = $this->client->getItem(['bucket' => $bucketName, 'key' => $key, 'version' => $version]); |
||
207 | } else { |
||
208 | $items[] = $index; |
||
209 | } |
||
210 | |||
211 | // send to cache, just to be sure that S3 is syncronized with cache |
||
212 | if ($this->client->hasCache()) { |
||
213 | $this->client->getCache()->set($bucketName, $result['Key'], $this->client->getItem(['bucket' => $bucketName, 'key' => $key, 'version' => $version]), $version); |
||
214 | } |
||
215 | } |
||
216 | } |
||
217 | |||
218 | if (null !== $this->commandHandlerLogger) { |
||
219 | $this->commandHandlerLogger->log($this, sprintf('Files (versioned) were successfully obtained from \'%s\' bucket', $bucketName)); |
||
220 | } |
||
221 | |||
222 | return $items; |
||
223 | } |
||
224 | } |
||
225 |