ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:27.62 GB of 70.42 GB (39.22%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ http/ guitar/ modules/ amazons3/ - dr-xr-xr-x

Directory:
Viewing file:     AmazonS3StreamWrapper.inc (28.44 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php

/**
 * @file
 * Drupal stream wrapper implementation for Amazon S3
 *
 * Implements DrupalStreamWrapperInterface to provide an Amazon S3 wrapper with
 * the s3:// prefix
 */
class AmazonS3StreamWrapper implements DrupalStreamWrapperInterface {

  
/**
   * @var String Instance URI referenced as "s3://bucket/key"
   */
  
protected $uri;

  
/**
   * @var AmazonS3 S3 connection object
   */
  
protected $s3 null;

  
/**
   * @var string S3 bucket name
   */
  
protected $bucket;

  
/**
   * @var string Domain we use to access files over http
   */
  
protected $domain;

  
/**
   * @var int Current read/write position
   */
  
protected $position 0;

  
/**
   * @var int Total size of the object as returned by S3 (Content-length)
   */
  
protected $object_size 0;

  
/**
   * @var string Object read/write buffer, typically a file
   */
  
protected $buffer null;

  
/**
   * @var boolean Whether $buffer is active as a write buffer
   */
  
protected $buffer_write false;

  
/**
   * @var int Buffer length
   */
  
protected $buffer_length 0;

  
/**
   * @var array directory listing
   */
  
protected $dir = array();

  
/**
   * @var array Default map for determining file mime types
   */
  
protected static $mapping null;

  
/**
   * @var boolean Whether local file metadata caching is on
   */
  
protected $caching FALSE;

  
/**
   * @var array Map for files that should be delivered with a torrent URL.
   */
  
protected $torrents = array();

  
/**
   * @var array Map for files that should have their Content-disposition header
   * set to force "save as".
   */
  
protected $saveas = array();

  
/**
   * @var array Map for files that should have a URL will be created that times
   * out in a designated number of seconds.
   */
  
protected $presigned_urls = array();

  
/**
   * Object constructor
   *
   * Sets the bucket name
   */
  
public function __construct() {
    
$this->bucket $bucket variable_get('amazons3_bucket''');

    
// CNAME support for customising S3 URLs
    
if (variable_get('amazons3_cname'0)) {
      
$domain variable_get('amazons3_domain''');
      if(
strlen($domain) > 0) {
        
$this->domain 'http://' $domain;
      }
      else {
        
$this->domain 'http://' $this->bucket;
      }
    }
    else {
      
$this->domain 'http://' $this->bucket '.s3.amazonaws.com';
    }

    
// Check whether local file caching is turned on
    
if (variable_get('amazons3_cache'FALSE)) {
      
$this->caching TRUE;
    }

    
// Torrent list
    
$torrents explode("\n"variable_get('amazons3_torrents'''));
    
$torrents array_map('trim'$torrents);
    
$torrents array_filter($torrents'strlen');
    
$this->torrents $torrents;


    
// Presigned url-list
    
$presigned_urls explode("\n"variable_get('amazons3_presigned_urls'''));
    
$presigned_urls array_map('trim'$presigned_urls);
    
$presigned_urls array_filter($presigned_urls'strlen');
    
$this->presigned_urls = array();
    foreach (
$presigned_urls as $presigned_url) {
      
// Check for an explicit key.
      
$matches = array();
      if (
preg_match('/(.*)\|(.*)/'$presigned_url$matches)) {
        
$this->presigned_urls[$matches[2]] = $matches[1];
      }
      else {
        
$this->presigned_urls[$presigned_url] = 60;
      }
    }

    
// Force "save as" list
    
$saveas explode("\n"variable_get('amazons3_saveas'''));
    
$saveas array_map('trim'$saveas );
    
$saveas  array_filter($saveas 'strlen');
    
$this->saveas  $saveas;

  }


  
/**
   * Sets the stream resource URI.
   *
   * URIs are formatted as "s3://bucket/key"
   *
   * @return
   *   Returns the current URI of the instance.
   */
  
public function setUri($uri) {
    
$this->uri $uri;
  }

  
/**
   * Returns the stream resource URI.
   *
   * URIs are formatted as "s3://bucket/key"
   *
   * @return
   *   Returns the current URI of the instance.
   */
  
public function getUri() {
    return 
$this->uri;
  }

  
/**
   * Returns a web accessible URL for the resource.
   *
   * In the format http://mybucket.amazons3.com/myfile.jpg
   *
   * @return
   *   Returns a string containing a web accessible URL for the resource.
   */
  
public function getExternalUrl() {

    
// Image styles support
    // Delivers the first request to an image from the private file system
    // otherwise it returns an external URL to an image that has not been
    // created yet
    
$path explode('/'$this->getLocalPath());
    if (
$path[0] == 'styles') {
      if (!
$this->_amazons3_get_object($this->uri$this->caching)) {
        
array_shift($path);
        return 
url('system/files/styles/' implode('/'$path), array('absolute' => true));
      }
    }

    
$local_path $this->getLocalPath();

    
$info = array(
      
'download_type' => 'http',
      
'presigned_url' => FALSE,
      
'presigned_url_timeout' => 60,
      
'response' => array(),
    );

    
// Allow other modules to change the download link type.
    
$info array_merge($infomodule_invoke_all('amazons3_url_info'$local_path$info));

    
// UI overrides
    // Torrent URLs
    
if ($info['download_type'] != 'torrent') {
      foreach (
$this->torrents as $path) {
        if (
preg_match('#' strtr($path'#''\#') . '#'$local_path)) {
          
$info['download_type'] = 'torrent';
          break;
        }
      }
    }
    
// Presigned URLs
    
if (!$info['presigned_url']) {
      foreach (
$this->presigned_urls as $path => $timeout) {
        if (
preg_match('#' strtr($path'#''\#') . '#'$local_path)) {
          
$info['presigned_url'] = TRUE;
          
$info['presigned_url_timeout'] = $timeout;
          break;
        }
      }
    }
    
// Save as
    
if ($info['download_type'] != 'torrent') {
      foreach (
$this->saveas as $path) {
        if (
preg_match('#' strtr($path'#''\#') . '#'$local_path)) {
          
$info['response']['content-disposition'] = 'attachment; filename=' basename($local_path);
          break;
        }
      }
    }

    
$timeout = ($info['presigned_url']) ? time() + $info['presigned_url_timeout'] : 0;
    
$torrent = ($info['download_type'] == 'torrent') ? TRUE FALSE;
    
$response = ($info['presigned_url']) ? $info['response'] : array();
    if (
$info['presigned_url'] || $info['download_type'] != 'http' || !empty($info['response'])) {
      
$url $this->getS3()->get_object_url($this->bucket$local_path$timeout, array('torrent' => $torrent'response' => $response));
      return 
$url;
    }

    
$url $this->domain '/' $local_path;
    return 
$url;
  }

  
/**
   * Determine a file's media type
   *
   * Uses Drupal's mimetype mappings. Returns 'application/octet-stream' if
   * no match is found.
   *
   *  @return
   *   Returns a string representing the file's MIME type
   */
  
public static function getMimeType($uri$mapping NULL) {

    
// Load the default file map
    
if (!isset(self::$mapping)) {
      include_once 
DRUPAL_ROOT '/includes/file.mimetypes.inc';
      
self::$mapping file_mimetype_mapping();
    }

    
$extension '';
    
$file_parts explode('.'basename($uri));

    
// Remove the first part: a full filename should not match an extension.
    
array_shift($file_parts);

    
// Iterate over the file parts, trying to find a match.
    // For my.awesome.image.jpeg, we try:
    //   - jpeg
    //   - image.jpeg, and
    //   - awesome.image.jpeg
    
while ($additional_part array_pop($file_parts)) {
      
$extension strtolower($additional_part . ($extension '.' $extension ''));
      if (isset(
self::$mapping['extensions'][$extension])) {
        return 
self::$mapping['mimetypes'][self::$mapping['extensions'][$extension]];
      }
    }

    return 
'application/octet-stream';
  }

  
/**
   * Changes permissions of the resource.
   *
   * This doesn't do anything for the moment so just returns FALSE;
   *
   * @param $mode
   *   Integer value for the permissions. Consult PHP chmod() documentation
   *   for more information.
   *
   * @return
   *   Returns TRUE on success or FALSE on failure.
   */
  
public function chmod($mode) {
  
/**  $modes = str_split($mode);
    if($modes[0] == '0') {
      array_shift($modes);
    }
    if(count($modes) != 3) {
      return FALSE;
    }

    if(intval($modes[2]) >= 4) {
      $acl = AmazonS3::ACL_PUBLIC;
    }
    else {
      $acl = AmazonS3::ACL_PRIVATE;
    }

    $local_path = $this->getLocalPath();
    if($this->_is_dir() && (substr($local_path, -1) != '/')) {
      $local_path .= '/';
    }

    $response = $this->getS3()->set_object_acl($this->bucket, $local_path, $acl);
    return $response->isOK();**/
    
return TRUE;
  }

  
/**
   * Returns canonical, absolute path of the resource.
   *
   * @return
   *   Returns FALSE as this wrapper does not provide an implementation.
   */
  
public function realpath() {
    return 
FALSE;
  }

  
/**
   * Gets the name of the directory from a given path.
   *
   * This method is usually accessed through drupal_dirname(), which wraps
   * around the normal PHP dirname() function, which does not support stream
   * wrappers.
   *
   * @param $uri
   *   An optional URI.
   *
   * @return
   *   A string containing the directory name, or FALSE if not applicable.
   *
   * @see drupal_dirname()
   */
  
public function dirname($uri NULL) {
   list(
$scheme$target) = explode('://'$uri2);
   
$target  $this->getTarget($uri);
   
$dirname dirname($target);

   if (
$dirname == '.') {
     
$dirname '';
   }

   return 
$scheme '://' $dirname;
  }

  
/**
   * Support for fopen(), file_get_contents(), file_put_contents() etc.
   *
   * @param $uri
   *   A string containing the URI to the file to open.
   * @param $mode
   *   The file mode ("r", "wb" etc.).
   * @param $options
   *   A bit mask of STREAM_USE_PATH and STREAM_REPORT_ERRORS.
   * @param $opened_path
   *   A string containing the path actually opened.
   *
   * @return
   *   Returns TRUE if file was opened successfully.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-open.php
   */
  
public function stream_open($uri$mode$options, &$opened_path) {
    
$this->uri $uri;

    
// if this stream is being opened for writing, clear the object buffer
    // Return true as we'll create the object on fflush call
    
if (strpbrk($mode'wax')) {
      
$this->clearBuffer();
      
$this->write_buffer TRUE;
      return 
TRUE;
    }
    
$metadata $this->_amazons3_get_object($uri$this->caching);
    if (
$metadata) {
      
$this->clearBuffer();
      
$this->write_buffer false;
      
$this->object_size $metadata['filesize'];
      return 
TRUE;
    }

    return 
FALSE;
  }

  
/**
   * Support for fclose().
   *
   * Clears the object buffer and returns TRUE
   *
   * @return
   *   TRUE
   *
   * @see http://php.net/manual/en/streamwrapper.stream-close.php
   */
  
public function stream_close() {
    
$this->clearBuffer();
    return 
TRUE;
  }

  
/**
   * Support for flock().
   *
   * @param $operation
   *   One of the following:
   *   - LOCK_SH to acquire a shared lock (reader).
   *   - LOCK_EX to acquire an exclusive lock (writer).
   *   - LOCK_UN to release a lock (shared or exclusive).
   *   - LOCK_NB if you don't want flock() to block while locking (not
   *     supported on Windows).
   *
   * @return
   *   returns TRUE if lock was successful
   *
   * @see http://php.net/manual/en/streamwrapper.stream-lock.php
   */
  
public function stream_lock($operation) {
    return 
false;
  }

  
/**
   * Support for fread(), file_get_contents() etc.
   *
   * @param $count
   *   Maximum number of bytes to be read.
   *
   * @return
   *   The string that was read, or FALSE in case of an error.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-read.php
   */
  
public function stream_read($count) {
    
$opts = array(
      
'range' => $this->position '-' min($this->object_size$this->position $count 1)
    );
    
$response $this->getS3()->get_object($this->bucket$this->getLocalPath($this->uri), $opts);
    if (
$response->isOK()) {
      
$this->position += strlen($response->body);
      return 
$response->body;
    }
    return 
FALSE;
  }

  
/**
   * Support for fwrite(), file_put_contents() etc.
   *
   * @param $data
   *   The string to be written.
   *
   * @return
   *   The number of bytes written (integer).
   *
   * @see http://php.net/manual/en/streamwrapper.stream-write.php
   */
  
public function stream_write($data) {
    
$data_length strlen($data);
    
$this->buffer .= $data;
    
$this->buffer_length += $data_length;
    
$this->position += $data_length;

    return 
$data_length;
  }

  
/**
   * Support for feof().
   *
   * @return
   *   TRUE if end-of-file has been reached.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-eof.php
   */
  
public function stream_eof() {
    if (!
$this->uri) {
        return 
true;
    }

    return (
$this->position >= $this->object_size);
  }

  
/**
   * Support for fseek().
   *
   * @param $offset
   *   The byte offset to got to.
   * @param $whence
   *   SEEK_SET, SEEK_CUR, or SEEK_END.
   *
   * @return
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-seek.php
   */
  
public function stream_seek($offset$whence) {
    switch(
$whence) {
      case 
SEEK_CUR:
        
// Set position to current location plus $offset
        
$new_position $this->position $offset;
        break;
      case 
SEEK_END:
        
// Set position to eof plus $offset
        
$new_position $this->object_size $offset;
        break;
      case 
SEEK_SET:
      default:
        
// Set position equal to $offset
        
$new_position $offset;
        break;
    }

    
$ret = ($new_position >= && $new_position <= $this->object_size);
    if (
$ret) {
      
$this->position $new_position;
    }
    return 
$ret;
  }

  
/**
   * Support for fflush(). Flush current cached stream data to storage.
   *
   * @return
   *   TRUE if data was successfully stored (or there was no data to store).
   *
   * @see http://php.net/manual/en/streamwrapper.stream-flush.php
   */
  
public function stream_flush() {
    if(
$this->write_buffer) {
      
$response $this->getS3()->create_object($this->bucket$this->getLocalPath(), array(
        
'body' => $this->buffer,
        
'acl' => AmazonS3::ACL_PUBLIC,
        
'contentType' => AmazonS3StreamWrapper::getMimeType($this->uri),
      ));
      if(
$response->isOK()) {
        return 
TRUE;
      }
    }
    
$this->clearBuffer();
    return 
FALSE;
  }

  
/**
   * Support for ftell().
   *
   * @return
   *   The current offset in bytes from the beginning of file.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-tell.php
   */
  
public function stream_tell() {
    return 
$this->position;
  }

  
/**
   * Support for fstat().
   *
   * @return
   *   An array with file status, or FALSE in case of an error - see fstat()
   *   for a description of this array.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-stat.php
   */
  
public function stream_stat() {
    return 
$this->_stat();
  }

  
/**
   * Support for unlink().
   *
   * @param $uri
   *   A string containing the uri to the resource to delete.
   *
   * @return
   *   TRUE if resource was successfully deleted.
   *
   * @see http://php.net/manual/en/streamwrapper.unlink.php
   */
  
public function unlink($uri) {
    
$response $this->getS3()->delete_object($this->bucket$this->getLocalPath($uri));
    if(
$response->isOK()) {
      
// Delete from cache
      
db_delete('amazons3_file')
        ->
condition('uri'$uri)
        ->
execute();
      return 
TRUE;
    }
    return 
FALSE;
  }

  
/**
   * Support for rename().
   *
   * @param $from_uri,
   *   The uri to the file to rename.
   * @param $to_uri
   *   The new uri for file.
   *
   * @return
   *   TRUE if file was successfully renamed.
   *
   * @see http://php.net/manual/en/streamwrapper.rename.php
   */
  
public function rename($from_uri$to_uri) {
    
$from $this->getLocalPath($from_uri);
    
$to $this->getLocalPath($to_uri);

    
/**
     * @todo Finish this...
    if ($this->getS3()->if_object_exists($this->bucket, $from) && !$this->getS3()->if_object_exists($this->bucket, $to)) {
      // get a lock
    }
    **/

    
return FALSE;
  }

  
/**
   * Returns the local writable target of the resource within the stream.
   *
   * This function should be used in place of calls to realpath() or similar
   * functions when attempting to determine the location of a file. While
   * functions like realpath() may return the location of a read-only file, this
   * method may return a URI or path suitable for writing that is completely
   * separate from the URI used for reading.
   *
   * @param $uri
   *   Optional URI.
   *
   * @return
   *   Returns a string representing a location suitable for writing of a file,
   *   or FALSE if unable to write to the file such as with read-only streams.
   */
  
protected function getTarget($uri NULL) {
    if (!isset(
$uri)) {
      
$uri $this->uri;
    }

    list(
$scheme$target) = explode('://'$uri2);

    
// Remove erroneous leading or trailing forward-slashes and backslashes.
    
return trim($target'\/');
  }

  
/**
   * Support for mkdir().
   *
   * @param $uri
   *   A string containing the URI to the directory to create.
   * @param $mode
   *   Permission flags - see mkdir().
   * @param $options
   *   A bit mask of STREAM_REPORT_ERRORS and STREAM_MKDIR_RECURSIVE.
   *
   * @return
   *   TRUE if directory was successfully created.
   *
   * @see http://php.net/manual/en/streamwrapper.mkdir.php
   */
  
public function mkdir($uri$mode$options) {

    
$recursive = (bool) ($options STREAM_MKDIR_RECURSIVE);
    
$localpath $this->getLocalPath($uri);

    
// s3 has no concept of directories, but we emulate it by creating an
    // object of size 0 with a trailing "/"
    
$response $this->getS3()->create_object($this->bucket$localpath '/', array('body' => ''));
    if(
$response->isOk()) {
      return 
TRUE;
    }
    return 
FALSE;
  }

  
/**
   * Support for rmdir().
   *
   * @param $uri
   *   A string containing the URI to the directory to delete.
   * @param $options
   *   A bit mask of STREAM_REPORT_ERRORS.
   *
   * @return
   *   TRUE if directory was successfully removed.
   *
   * @see http://php.net/manual/en/streamwrapper.rmdir.php
   */
  
public function rmdir($uri$options) {
    
$localpath $this->getLocalPath($uri);
    
$s3 $this->getS3();

    
$objects $s3->get_object_list($this->bucket, array('prefix' => $localpath));
    if (
gettype($objects) === 'array') {
      
$or db_or();
      foreach(
$objects as $object) {
        
$s3->batch()->delete_object($this->bucket$object);
        
// Delete from cache
        
$object_uri 's3://' rtrim($object,'/');
        
$or->condition('uri'$object_uri'=');
      }
      
db_delete('amazons3_file')->condition($or)->execute();
      
$responses $s3->batch()->send();

      if(
$responses->areOK()) {
        return 
TRUE;
      }
    }
    return 
FALSE;
  }

  
/**
   * Support for stat().
   *
   * @param $uri
   *   A string containing the URI to get information about.
   * @param $flags
   *   A bit mask of STREAM_URL_STAT_LINK and STREAM_URL_STAT_QUIET.
   *
   * @return
   *   An array with file status, or FALSE in case of an error - see fstat()
   *   for a description of this array.
   *
   * @see http://php.net/manual/en/streamwrapper.url-stat.php
   */
  
public function url_stat($uri$flags) {
    return 
$this->_stat($uri);
  }

  
/**
   * Support for opendir().
   *
   * @param $uri
   *   A string containing the URI to the directory to open.
   * @param $options
   *   Unknown (parameter is not documented in PHP Manual).
   *
   * @return
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-opendir.php
   */
  
public function dir_opendir($uri$options) {
    if (
$uri == null) {
      return 
FALSE;
    }
    else if(!
$this->_is_dir($uri)) {
      return 
FALSE;
    }

    
$this->dir = array();
    
$path $this->getLocalPath($uri);
    
$truncated TRUE;
    
$marker '';
    if(
strlen($path) == 0) {
      
$prefix $path;
    }
    else {
      
$prefix $path '/';
    }
    
$prefix_length strlen($prefix);

    while(
$truncated) {
      
$response $this->getS3()->list_objects($this->bucket, array(
          
'delimiter' => '/',
          
'prefix' => $prefix,
          
'marker' => urlencode($marker),
      ));
      if (
$response->isOK()) {

        
$this->dir[] = '.';
        
$this->dir[] = '..';

        
// Folders
        
if (isset($response->body->CommonPrefixes)) {
          foreach(
$response->body->CommonPrefixes as $prefix) {
            
$marker substr($prefix->Prefix$prefix_lengthstrlen($prefix->Prefix) - $prefix_length 1);
            if(
strlen($marker) > 0) {
              
$this->dir[] = $marker;
            }
          }
        }

        
// Files
        
if(isset($response->body->Contents)) {
          
$contents $response->body->to_stdClass()->Contents;
          if (!
is_array($contents)) {
            
$contents = array($contents);
          }

          foreach(
$contents as $content) {
            
$key $content->Key;
            if(
substr_compare($key'/', -11) !== 0) {
              
$marker basename($key);
              
$this->dir[] = $marker;
            }
          }
        }

        if(!isset(
$response->body->IsTruncated) || $response->body->IsTruncated == 'false') {
          
$truncated FALSE;
        }
      }
      else {
        return 
FALSE;
      }
    }
    return 
TRUE;
  }

  
/**
   * Support for readdir().
   *
   * @return
   *   The next filename, or FALSE if there are no more files in the directory.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-readdir.php
   */
  
public function dir_readdir() {
    
$filename current($this->dir);
    if (
$filename !== false) {
        
next($this->dir);
    }
    return 
$filename;
  }

  
/**
   * Support for rewinddir().
   *
   * @return
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-rewinddir.php
   */
  
public function dir_rewinddir() {
    
reset($this->dir);
    return 
TRUE;
  }

  
/**
   * Support for closedir().
   *
   * @return
   *   TRUE on success.
   *
   * @see http://php.net/manual/en/streamwrapper.dir-closedir.php
   */
  
public function dir_closedir() {
    
$this->dir = array();
    return 
TRUE;
  }

  
/**
   * Return the local filesystem path.
   *
   * @param $uri
   *   Optional URI, supplied when doing a move or rename.
   */
  
protected function getLocalPath($uri NULL) {
    if (!isset(
$uri)) {
      
$uri $this->uri;
    }

    
$path  str_replace('s3://'''$uri);
    
$path trim($path'/');
    return 
$path;
  }

  
/**
   * Gets the path that the wrapper is responsible for.
   *
   * @return
   *   String specifying the path.
   */
  
public function getDirectoryPath() {
    return 
$this->domain;
  }

  
/**
   * Flush the object buffers
   */
  
protected function clearBuffer() {
    
$this->position 0;
    
$this->object_size 0;
    
$this->buffer null;
    
$this->buffer_write false;
    
$this->buffer_length 0;
  }

  
/**
   * Get the S3 connection object
   *
   * @return
   *   S3 connection object (AmazonS3)
   *
   * @see http://docs.amazonwebservices.com/AWSSDKforPHP/latest/#i=AmazonS3
   */
  
protected function getS3() {
    if(
$this->s3 == null) {
      
$bucket variable_get('amazons3_bucket''');

      if(!
libraries_load('awssdk') && !isset($bucket)) {
        
drupal_set_message('Unable to load the AWS SDK. Please check you have installed the library correctly and configured your S3 credentials.''error');
      }
      else if(!isset(
$bucket)) {
        
drupal_set_message('Bucket name not configured.''error');
      }
      else {
        try {
         
$this->s3 = new AmazonS3();
         
$this->bucket $bucket;
        }
        catch(
RequestCore_Exception $e){
          
drupal_set_message('There was a problem connecting to S3''error');
        }
        catch(
Exception $e) {
          
drupal_set_message('There was a problem using S3: ' $e->getMessage(), 'error');
        }
      }
    }
    return 
$this->s3;
  }

  
/**
   * Get file status
   *
   * @return
   *   An array with file status, or FALSE in case of an error - see fstat()
   *   for a description of this array.
   *
   * @see http://php.net/manual/en/streamwrapper.stream-stat.php
   */
  
protected function _stat($uri NULL) {
    if(!isset(
$uri)) {
      
$uri $this->uri;
    }
    
$metadata $this->_amazons3_get_object($uri$this->caching);
    if (
$metadata) {
      
$stat = array();
      
$stat[0] = $stat['dev'] = 0;
      
$stat[1] = $stat['ino'] = 0;
      
$stat[2] = $stat['mode'] = $metadata['mode'];
      
$stat[3] = $stat['nlink'] = 0;
      
$stat[4] = $stat['uid'] = 0;
      
$stat[5] = $stat['gid'] = 0;
      
$stat[6] = $stat['rdev'] = 0;
      
$stat[7] = $stat['size'] = 0;
      
$stat[8] = $stat['atime'] = 0;
      
$stat[9] = $stat['mtime'] = 0;
      
$stat[10] = $stat['ctime'] = 0;
      
$stat[11] = $stat['blksize'] = 0;
      
$stat[12] = $stat['blocks'] = 0;

      if (!
$metadata['dir']) {
        
$stat[4] = $stat['uid'] = $metadata['uid'];
        
$stat[7] = $stat['size'] = $metadata['filesize'];
        
$stat[8] = $stat['atime'] = $metadata['timestamp'];
        
$stat[9] = $stat['mtime'] = $metadata['timestamp'];
        
$stat[10] = $stat['ctime'] = $metadata['timestamp'];
      }
      return 
$stat;
    }
    return 
FALSE;
}


/**
 * Determine whether the $uri is a directory
 *
   * @param $uri
   *   A string containing the uri to the resource to check. If none is given
   *   defaults to $this->uri
   *
   * @return
   *   TRUE if the resource is a directory
   */
  
protected function _is_dir($uri null) {
    if(
$uri == null) {
      
$uri $this->uri;
    }
    if(
$uri != null) {
      
$path $this->getLocalPath($uri);
      
$response $this->getS3()->list_objects($this->bucket, array(
          
'prefix' => $path '/',
          
'max-keys' => 1,
      ));
      if(
$response && isset($response->body->Contents->Key)) {
        return 
TRUE;
      }
    }
    return 
FALSE;
  }

  
/**
   * CACHING FUNCTIONS
   */

  /**
   * Try to fetch an object from the metadata cache, otherwise fetch it's
   * info from S3 and populate the cache.
   *
   * @param uri
   *   A string containing the uri of the resource to check.
   * @param $cach
   *   A boolean representing whether to check the cache for file information.
   *
   *  @return
   *    An array if the $uri exists, otherwise FALSE.
   */
  
protected function _amazons3_get_object($uri$cache TRUE) {
    
$uri rtrim($uri,'/');

    if (
$cache) {
      
$metadata $this->_amazons3_get_cache($uri);
      if (
$metadata) {
        return 
$metadata;
      }
    }

    
$is_dir $this->_is_dir($uri);
    
$metadata NULL;
    if (
$is_dir) {
      
$mode 0040000// S_IFDIR indicating directory
      
$mode |= 0777;
      
$metadata = array(
        
'uri' => $uri,
        
'dir' => 1,
        
'mode' => $mode,
      );
    }
    else {
      
$response $this->getS3()->get_object_metadata($this->bucket$this->getLocalPath($uri));
      if (
$response) {
        
$metadata $this->_amazons3_format_response($uri$response);
        
$metadata['dir'] = 0;
        
$metadata['mode'] = 0100000// S_IFREG indicating file
        
$metadata['mode'] |= 0777// everything is writeable
      
}
    }
    if (
is_array($metadata)) {
      
// Save to the cache
      
db_merge('amazons3_file')
        ->
key(array('uri' => $metadata['uri']))
        ->
fields($metadata)
        ->
execute();
      return 
$metadata;
    }
    return 
FALSE;
  }

  
/**
   * Fetch an object from the local metadata cache
   *
   * @param uri
   *  A string containing the uri of the resource to check.
   *
   *  @return
   *    An array if the $uri is in the cache, otherwise FALSE
   */
  
protected function _amazons3_get_cache($uri) {
    
// Check cache for existing object.
    
$result db_query("SELECT * FROM {amazons3_file} WHERE uri = :uri", array(
      
':uri' => $uri,
    ));
    
$record $result->fetchAssoc();
    if (
$record) {
      return 
$record;
    }
    return 
FALSE;
  }

  
/**
   * Format returned file information from S3 into an array
   *
   * @param $uri
   *   A string containing the uri of the resource to check.
   * @param $response
   *   An array containing the collective metadata for the Amazon S3 object
   *
   * @return
   *   An array containing formatted metadata
   */
  
protected function _amazons3_format_response($uri$response) {
    
$metadata = array('uri' => $uri);
    if (isset(
$response['Size'])) {
      
$metadata['filesize'] = $response['Size'];
    }
    if (isset(
$response['LastModified'])) {
      
$metadata['timestamp'] = date('U'strtotime((string) $response['LastModified']));
    }
    if (isset(
$response['Owner']['ID'])) {
      
$metadata['uid'] = (string) $response['Owner']['ID'];
    }
    return 
$metadata;
  }
}
Command:
Quick Commands:
Upload:
[Read-Only] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [Read-Only]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.4801 seconds