From f4c6c24ee236be121a173341350c7f77081bcb35 Mon Sep 17 00:00:00 2001
From: Vishwaraj Anand <vishwaraj.anand00@gmail.com>
Date: Thu, 14 Mar 2024 17:42:38 +0530
Subject: [PATCH] feat(Storage): implement touch on streams (#7144)

---
 Storage/src/StreamWrapper.php                 | 35 ++++++++++++++++++-
 .../tests/System/StreamWrapper/WriteTest.php  |  9 +++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/Storage/src/StreamWrapper.php b/Storage/src/StreamWrapper.php
index 7cc028e14d37..93d2eab0aace 100644
--- a/Storage/src/StreamWrapper.php
+++ b/Storage/src/StreamWrapper.php
@@ -127,6 +127,39 @@ public function stream_set_option()
         return false;
     }
 
+    /**
+     * This is called when touch is used on a stream. See:
+     * https://www.php.net/manual/en/streamwrapper.stream-metadata.php
+     */
+    public function stream_metadata($path, $option, $value)
+    {
+        if ($option == STREAM_META_TOUCH) {
+            $this->openPath($path);
+            return $this->touch();
+        }
+
+        return false;
+    }
+
+    /**
+     * Creates an empty file if it does not exist.
+     * @return bool Returns true if file exists or has been created, false otherwise.
+     */
+    private function touch()
+    {
+        $object = $this->bucket->object($this->file);
+        try {
+            if (!$object->exists()) {
+                $this->bucket->upload('', [
+                    'name' => $this->file
+                ]);
+            }
+            return true;
+        } catch (NotFoundException $e) {
+        }
+        return false;
+    }
+
     /**
      * Register a StreamWrapper for reading and writing to Google Storage
      *
@@ -186,7 +219,7 @@ public static function getClient($protocol = null)
      */
     public function stream_open($path, $mode, $flags, &$openedPath)
     {
-        $client = $this->openPath($path);
+        $this->openPath($path);
 
         // strip off 'b' or 't' from the mode
         $mode = rtrim($mode, 'bt');
diff --git a/Storage/tests/System/StreamWrapper/WriteTest.php b/Storage/tests/System/StreamWrapper/WriteTest.php
index e7910fa4dea9..a7f0d93f80ae 100644
--- a/Storage/tests/System/StreamWrapper/WriteTest.php
+++ b/Storage/tests/System/StreamWrapper/WriteTest.php
@@ -59,6 +59,15 @@ public function testFwrite()
         $this->assertFileExists($this->fileUrl);
     }
 
+    public function testTouch()
+    {
+        $this->assertFileDoesNotExist($this->fileUrl);
+
+        $this->assertTrue(touch($this->fileUrl));
+
+        $this->assertFileExists($this->fileUrl);
+    }
+
     public function testStreamingWrite()
     {
         $this->assertFileDoesNotExist($this->fileUrl);