← All changes
|
includes/sdk/google/google/cloud-storage/src/StreamWrapper.php
+57
-32
1.2.0
→
1.4.1
View file →
| @@ -14,14 +14,13 @@ | ||
| 14 | 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 15 | 15 | * See the License for the specific language governing permissions and |
| 16 | 16 | * limitations under the License. |
| 17 | 17 | */ |
| 18 | -namespace Dudlewebs\WPMCS\Google\Cloud\Storage; | |
| 18 | +namespace Dudlewebs\WPMCS\GCP\Google\Cloud\Storage; | |
| 19 | 19 | |
| 20 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Exception\NotFoundException; | |
| 21 | -use Dudlewebs\WPMCS\Google\Cloud\Core\Exception\ServiceException; | |
| 22 | -use Dudlewebs\WPMCS\Google\Cloud\Storage\Bucket; | |
| 23 | -use Dudlewebs\WPMCS\GuzzleHttp\Psr7\CachingStream; | |
| 20 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Exception\NotFoundException; | |
| 21 | +use Dudlewebs\WPMCS\GCP\Google\Cloud\Core\Exception\ServiceException; | |
| 22 | +use Dudlewebs\WPMCS\GCP\GuzzleHttp\Psr7\CachingStream; | |
| 24 | 23 | /** |
| 25 | 24 | * A streamWrapper implementation for handling `gs://bucket/path/to/file.jpg`. |
| 26 | 25 | * Note that you can only open a file with mode 'r', 'rb', 'rt', 'w', 'wb', 'wt', 'a', 'ab', or 'at'. |
| 27 | 26 | * |
| @@ -105,11 +104,9 @@ | ||
| 105 | 104 | { |
| 106 | 105 | $this->stream_close(); |
| 107 | 106 | } |
| 108 | 107 | /** |
| 109 | - * Starting PHP 7.4, this is called when include/require is used on a stream. | |
| 110 | - * Absence of this method presents a warning. | |
| 111 | - * https://www.php.net/manual/en/migration74.incompatible.php | |
| 108 | + * This is called when include/require is used on a stream. | |
| 112 | 109 | */ |
| 113 | 110 | public function stream_set_option() |
| 114 | 111 | { |
| 115 | 112 | return \false; |
| @@ -114,8 +111,36 @@ | ||
| 114 | 111 | { |
| 115 | 112 | return \false; |
| 116 | 113 | } |
| 117 | 114 | /** |
| 115 | + * This is called when touch is used on a stream. See: | |
| 116 | + * https://www.php.net/manual/en/streamwrapper.stream-metadata.php | |
| 117 | + */ | |
| 118 | + public function stream_metadata($path, $option, $value) | |
| 119 | + { | |
| 120 | + if ($option == \STREAM_META_TOUCH) { | |
| 121 | + $this->openPath($path); | |
| 122 | + return $this->touch(); | |
| 123 | + } | |
| 124 | + return \false; | |
| 125 | + } | |
| 126 | + /** | |
| 127 | + * Creates an empty file if it does not exist. | |
| 128 | + * @return bool Returns true if file exists or has been created, false otherwise. | |
| 129 | + */ | |
| 130 | + private function touch() | |
| 131 | + { | |
| 132 | + $object = $this->bucket->object($this->file); | |
| 133 | + try { | |
| 134 | + if (!$object->exists()) { | |
| 135 | + $this->bucket->upload('', ['name' => $this->file]); | |
| 136 | + } | |
| 137 | + return \true; | |
| 138 | + } catch (NotFoundException $e) { | |
| 139 | + } | |
| 140 | + return \false; | |
| 141 | + } | |
| 142 | + /** | |
| 118 | 143 | * Register a StreamWrapper for reading and writing to Google Storage |
| 119 | 144 | * |
| 120 | 145 | * @param StorageClient $client The StorageClient configuration to use. |
| 121 | 146 | * @param string $protocol The name of the protocol to use. **Defaults to** |
| @@ -124,10 +149,10 @@ | ||
| 124 | 149 | */ |
| 125 | 150 | public static function register(StorageClient $client, $protocol = null) |
| 126 | 151 | { |
| 127 | 152 | $protocol = $protocol ?: self::DEFAULT_PROTOCOL; |
| 128 | - if (!in_array($protocol, stream_get_wrappers())) { | |
| 129 | - if (!stream_wrapper_register($protocol, StreamWrapper::class, \STREAM_IS_URL)) { | |
| 153 | + if (!\in_array($protocol, \stream_get_wrappers())) { | |
| 154 | + if (!\stream_wrapper_register($protocol, StreamWrapper::class, \STREAM_IS_URL)) { | |
| 130 | 155 | throw new \RuntimeException("Failed to register '{$protocol}://' protocol"); |
| 131 | 156 | } |
| 132 | 157 | self::$clients[$protocol] = $client; |
| 133 | 158 | return \true; |
| @@ -142,9 +167,9 @@ | ||
| 142 | 167 | */ |
| 143 | 168 | public static function unregister($protocol = null) |
| 144 | 169 | { |
| 145 | 170 | $protocol = $protocol ?: self::DEFAULT_PROTOCOL; |
| 146 | - stream_wrapper_unregister($protocol); | |
| 171 | + \stream_wrapper_unregister($protocol); | |
| 147 | 172 | unset(self::$clients[$protocol]); |
| 148 | 173 | } |
| 149 | 174 | /** |
| 150 | 175 | * Get the default client to use for streams. |
| @@ -169,15 +194,15 @@ | ||
| 169 | 194 | * @return bool |
| 170 | 195 | */ |
| 171 | 196 | public function stream_open($path, $mode, $flags, &$openedPath) |
| 172 | 197 | { |
| 173 | - $client = $this->openPath($path); | |
| 198 | + $this->openPath($path); | |
| 174 | 199 | // strip off 'b' or 't' from the mode |
| 175 | - $mode = rtrim($mode, 'bt'); | |
| 200 | + $mode = \rtrim($mode, 'bt'); | |
| 176 | 201 | $options = []; |
| 177 | 202 | if ($this->context) { |
| 178 | - $contextOptions = stream_context_get_options($this->context); | |
| 179 | - if (array_key_exists($this->protocol, $contextOptions)) { | |
| 203 | + $contextOptions = \stream_context_get_options($this->context); | |
| 204 | + if (\array_key_exists($this->protocol, $contextOptions)) { | |
| 180 | 205 | $options = $contextOptions[$this->protocol] ?: []; |
| 181 | 206 | } |
| 182 | 207 | if (isset($options['flush'])) { |
| 183 | 208 | $this->flushing = (bool) $options['flush']; |
| @@ -355,22 +380,22 @@ | ||
| 355 | 380 | // The delimiter options do not give us what we need, so instead we |
| 356 | 381 | // list all results matching the given prefix, enumerate the |
| 357 | 382 | // iterator, filter and transform results, and yield a fresh |
| 358 | 383 | // generator containing only the directory listing. |
| 359 | - $this->directoryIterator = call_user_func(function () use ($iterator) { | |
| 384 | + $this->directoryIterator = \call_user_func(function () use($iterator) { | |
| 360 | 385 | $yielded = []; |
| 361 | - $pathLen = strlen($this->makeDirectory($this->file)); | |
| 386 | + $pathLen = \strlen($this->makeDirectory($this->file)); | |
| 362 | 387 | foreach ($iterator as $object) { |
| 363 | - $name = substr($object->name(), $pathLen); | |
| 364 | - $parts = explode('/', $name); | |
| 388 | + $name = \substr($object->name(), $pathLen); | |
| 389 | + $parts = \explode('/', $name); | |
| 365 | 390 | // since the service call returns nested results and we only |
| 366 | 391 | // want to yield results directly within the requested directory, |
| 367 | 392 | // check if we've already yielded this value. |
| 368 | - if ($parts[0] === "" || in_array($parts[0], $yielded)) { | |
| 393 | + if ($parts[0] === '' || \in_array($parts[0], $yielded)) { | |
| 369 | 394 | continue; |
| 370 | 395 | } |
| 371 | 396 | $yielded[] = $parts[0]; |
| 372 | - yield $name => $parts[0]; | |
| 397 | + (yield $name => $parts[0]); | |
| 373 | 398 | } |
| 374 | 399 | }); |
| 375 | 400 | } catch (ServiceException $e) { |
| 376 | 401 | return \false; |
| @@ -424,16 +449,16 @@ | ||
| 424 | 449 | */ |
| 425 | 450 | public function rename($from, $to) |
| 426 | 451 | { |
| 427 | 452 | $this->openPath($from); |
| 428 | - $destination = (array) parse_url($to) + ['path' => '', 'host' => '']; | |
| 453 | + $destination = (array) \parse_url($to) + ['path' => '', 'host' => '']; | |
| 429 | 454 | $destinationBucket = $destination['host']; |
| 430 | - $destinationPath = substr($destination['path'], 1); | |
| 455 | + $destinationPath = \substr($destination['path'], 1); | |
| 431 | 456 | // loop through to rename file and children, if given path is a directory. |
| 432 | 457 | $objects = $this->bucket->objects(['prefix' => $this->file]); |
| 433 | 458 | foreach ($objects as $obj) { |
| 434 | 459 | $oldName = $obj->name(); |
| 435 | - $newPath = str_replace($this->file, $destinationPath, $oldName); | |
| 460 | + $newPath = \str_replace($this->file, $destinationPath, $oldName); | |
| 436 | 461 | try { |
| 437 | 462 | $obj->rename($newPath, ['destinationBucket' => $destinationBucket]); |
| 438 | 463 | } catch (ServiceException $e) { |
| 439 | 464 | return \false; |
| @@ -545,11 +570,11 @@ | ||
| 545 | 570 | * @return StorageClient |
| 546 | 571 | */ |
| 547 | 572 | private function openPath($path) |
| 548 | 573 | { |
| 549 | - $url = (array) parse_url($path) + ['scheme' => '', 'path' => '', 'host' => '']; | |
| 574 | + $url = (array) \parse_url($path) + ['scheme' => '', 'path' => '', 'host' => '']; | |
| 550 | 575 | $this->protocol = $url['scheme']; |
| 551 | - $this->file = ltrim($url['path'], '/'); | |
| 576 | + $this->file = \ltrim($url['path'], '/'); | |
| 552 | 577 | $client = self::getClient($this->protocol); |
| 553 | 578 | $this->bucket = $client->bucket($url['host']); |
| 554 | 579 | return $client; |
| 555 | 580 | } |
| @@ -563,9 +588,9 @@ | ||
| 563 | 588 | { |
| 564 | 589 | if ($path == '' or $path == '/') { |
| 565 | 590 | return ''; |
| 566 | 591 | } |
| 567 | - if (substr($path, -1) == '/') { | |
| 592 | + if (\substr($path, -1) == '/') { | |
| 568 | 593 | return $path; |
| 569 | 594 | } |
| 570 | 595 | return $path . '/'; |
| 571 | 596 | } |
| @@ -597,9 +622,9 @@ | ||
| 597 | 622 | // couldn't stat file |
| 598 | 623 | return \false; |
| 599 | 624 | } |
| 600 | 625 | // equivalent to 100666 and 100444 in octal |
| 601 | - $stats = array('mode' => $this->bucket->isWritable() ? self::FILE_WRITABLE_MODE : self::FILE_READABLE_MODE); | |
| 626 | + $stats = ['mode' => $this->bucket->isWritable() ? self::FILE_WRITABLE_MODE : self::FILE_READABLE_MODE]; | |
| 602 | 627 | $this->statsFromFileInfo($info, $stats); |
| 603 | 628 | return $this->makeStatArray($stats); |
| 604 | 629 | } |
| 605 | 630 | /** |
| @@ -611,10 +636,10 @@ | ||
| 611 | 636 | */ |
| 612 | 637 | private function statsFromFileInfo(array &$info, array &$stats) |
| 613 | 638 | { |
| 614 | 639 | $stats['size'] = isset($info['size']) ? (int) $info['size'] : null; |
| 615 | - $stats['mtime'] = isset($info['updated']) ? strtotime($info['updated']) : null; | |
| 616 | - $stats['ctime'] = isset($info['timeCreated']) ? strtotime($info['timeCreated']) : null; | |
| 640 | + $stats['mtime'] = isset($info['updated']) ? \strtotime($info['updated']) : null; | |
| 641 | + $stats['ctime'] = isset($info['timeCreated']) ? \strtotime($info['timeCreated']) : null; | |
| 617 | 642 | } |
| 618 | 643 | /** |
| 619 | 644 | * Get the given path as a directory. |
| 620 | 645 | * |
| @@ -640,9 +665,9 @@ | ||
| 640 | 665 | * @return array |
| 641 | 666 | */ |
| 642 | 667 | private function makeStatArray($stats) |
| 643 | 668 | { |
| 644 | - return array_merge(array_fill_keys(['dev', 'ino', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'size', 'atime', 'mtime', 'ctime', 'blksize', 'blocks'], 0), $stats); | |
| 669 | + return \array_merge(\array_fill_keys(['dev', 'ino', 'mode', 'nlink', 'uid', 'gid', 'rdev', 'size', 'atime', 'mtime', 'ctime', 'blksize', 'blocks'], 0), $stats); | |
| 645 | 670 | } |
| 646 | 671 | /** |
| 647 | 672 | * Helper for whether or not to trigger an error or just return false on an error. |
| 648 | 673 | * |
| @@ -652,9 +677,9 @@ | ||
| 652 | 677 | */ |
| 653 | 678 | private function returnError($message, $flags) |
| 654 | 679 | { |
| 655 | 680 | if ($flags & \STREAM_REPORT_ERRORS) { |
| 656 | - trigger_error($message, \E_USER_WARNING); | |
| 681 | + \trigger_error($message, \E_USER_WARNING); | |
| 657 | 682 | } |
| 658 | 683 | return \false; |
| 659 | 684 | } |
| 660 | 685 | /** |