From bcd1df70e2db0257c5552591309418f1b315c13e Mon Sep 17 00:00:00 2001
From: Jorrit Schippers <jorrit@161217.no-reply.drupal.org>
Date: Fri, 4 May 2012 15:14:33 +0200
Subject: [PATCH] Issue #1561176 by Jorrit: Added work-around for PHP bug 40459, where in some cases the constructor of the stream wrapper class wasn't called

---
 AmazonS3StreamWrapper.inc |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/AmazonS3StreamWrapper.inc b/AmazonS3StreamWrapper.inc
index 3648bca..9ed1f3f 100644
--- a/AmazonS3StreamWrapper.inc
+++ b/AmazonS3StreamWrapper.inc
@@ -27,7 +27,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
   /**
    * @var string Domain we use to access files over http
    */
-  protected $domain;
+  protected $domain = NULL;
 
   /**
    * @var int Current read/write position
@@ -296,6 +296,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    *   Returns TRUE on success or FALSE on failure.
    */
   public function chmod($mode) {
+    $this->assertConstructorCalled();
   /**  $modes = str_split($mode);
     if($modes[0] == '0') {
       array_shift($modes);
@@ -587,6 +588,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    * @see http://php.net/manual/en/streamwrapper.unlink.php
    */
   public function unlink($uri) {
+    $this->assertConstructorCalled();
     $response = $this->getS3()->delete_object($this->bucket, $this->getLocalPath($uri));
     if($response->isOK()) {
       // Delete from cache
@@ -612,6 +614,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    * @see http://php.net/manual/en/streamwrapper.rename.php
    */
   public function rename($from_uri, $to_uri) {
+    $this->assertConstructorCalled();
     $from = $this->getLocalPath($from_uri);
     $to = $this->getLocalPath($to_uri);
 
@@ -668,7 +671,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    * @see http://php.net/manual/en/streamwrapper.mkdir.php
    */
   public function mkdir($uri, $mode, $options) {
-
+    $this->assertConstructorCalled();
     $recursive = (bool) ($options & STREAM_MKDIR_RECURSIVE);
     $localpath = $this->getLocalPath($uri);
 
@@ -695,6 +698,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    * @see http://php.net/manual/en/streamwrapper.rmdir.php
    */
   public function rmdir($uri, $options) {
+    $this->assertConstructorCalled();
     $localpath = $this->getLocalPath($uri);
     $s3 = $this->getS3();
 
@@ -732,6 +736,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    * @see http://php.net/manual/en/streamwrapper.url-stat.php
    */
   public function url_stat($uri, $flags) {
+    $this->assertConstructorCalled();
     return $this->_stat($uri);
   }
 
@@ -749,6 +754,7 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
    * @see http://php.net/manual/en/streamwrapper.dir-opendir.php
    */
   public function dir_opendir($uri, $options) {
+    $this->assertConstructorCalled();
     if ($uri == null) {
       return FALSE;
     }
@@ -1101,4 +1107,19 @@ class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {
     }
     return $metadata;
   }
+
+  /**
+   * Assert that the constructor has been called, call it if not.
+   *
+   * Due to PHP bug #40459, the constructor of this class isn't always called
+   * for some of the methods. This private method calls the constructor if
+   * it hasn't been called before.
+   *
+   * @see https://bugs.php.net/bug.php?id=40459
+   */
+  private function assertConstructorCalled() {
+    if ($this->domain === NULL) {
+      $this->__construct();
+    }
+  }
 }
-- 
1.7.4.1

