<?php
/*
Plugin Name: AWS S3 Upload Storage Strategy
Description: Uses AWS S3 to store uploads
Version: 0.06
Requires at least: 3.06
*/

// this function is called at the bottom of this file, so that the class is defined (because class definitions aren't hoisted like functions are)
function aws_s3_uploads_init() {

  if(!function_exists('_aws_s3_init')) { alert("Cannot find function '_aws_s3_init', have you installed and setup the AWS S3 Plugin?<br>\n", E_USER_NOTICE); }
  
  // set global upload storage strategy!
  upload_storage_strategy(new S3UploadStorageStrategy());
  
}

pluginAction_addHandlerAndLink('Migrate Uploads', 'aws_s3_migrate_uploads', 'admins');

function aws_s3_migrate_uploads() {
  echo plugin_header("Migrate Uploads");
  ?>
    <table class="table" style="width: auto;" id="upload_count_table">
      <tr>
        <td>Uploads on filesystem</td>
        <td class="count"><?php echo mysql_count('uploads', "(storage = '' OR storage IS NULL) AND fieldName != ''"); ?></td>
        <td><?php echo adminUI_button(['name' => 'move_to_filesystem', 'label' => 'Move all uploads here']) ?></td>
      </tr>
      <tr>
        <td>Uploads on S3</td>
        <td class="count"><?php echo mysql_count('uploads', [ 'storage' => 's3' ]); ?></td>
        <td><?php echo adminUI_button(['name' => 'move_to_s3', 'label' => 'Move all uploads here']) ?></td>
      </tr>
    </table>
    
    <div id="processing" style="display: none;">
      
      <div id="danger">
        <?php echo _displayNotificationType('danger', 'Uploads are currently being processed. Do not close this page until this process has completed.') ?>
      </div>
      
      <h4 id="status">Processing...</h4>
      
      <p id="completeLink" style="display: none;">
        <a href="#" onclick="window.location.reload(); return false;">Click here to reload this page.</a>
      </p>
      
      <p>
        <span id="processedCount">0</span>
        of
        <span id="totalToProcess"></span>
      </p>
      
      <xmp id="requestLog"></xmp>
      
    </div>
    
    <script>
      $(function() {
        
        $('#upload_count_table button').on('click', function() {
          //$('#upload_count_table button').attr('disabled', 'disabled').addClass('disabled');
          var btnName        = $(this).attr('name');
          var destination    = btnName.match(/_([^_]+)$/)[1]; // e.g. move_to_(filesystem)
          var totalToProcess = $(this).closest('tr').siblings().find('.count').html();
          $('#status').html('Migrating all uploads to ' + destination + '...');
          $('#totalToProcess').html(totalToProcess);
          $('#processing').show();
          $('#upload_count_table').hide();
          processMoreUploads(destination, function() {
            $('#status').text('Complete!');
            $('#danger').hide();
            $('#completeLink').show();
          });
          return false;
        });
        
        function processMoreUploads(destination, onCompleteCallback) {
          $.ajax({
            url: '?',
            data: {
              _pluginAction: 'aws_s3_uploads_migrate_worker',
              destination:   destination,
            },
            dataType: 'json',
            success: function(res) {
              if (!res.success) { return alert("An error occurred processing the request: the response did not contain the key 'success'"); }
              
              // show response in log
              $('#requestLog').append(JSON.stringify(res) + '\n');
              
              // increment processedCount
              $('#processedCount').text(parseInt(res.processed) + parseInt($('#processedCount').text()));
              
              // done processing?
              if (res.done) {
                onCompleteCallback();
              }
              // continue processing
              else {
                processMoreUploads(destination, onCompleteCallback);
              }
            },
            error: function(jqXHR, textStatus, errorThrown) {
              alert("An error occurred processing the request: " + textStatus + " -- " + errorThrown);
            }
          });
        }
        
      });
    </script>
  <?php
  echo plugin_footer();
  exit;
}

pluginAction_addHandler('aws_s3_uploads_migrate_worker', 'admins');
function aws_s3_uploads_migrate_worker() {
  $maxUploadsPerRequest = 100;
  $stopAfterElapsedTime = ini_get('max_execution_time') * 0.5; // 50% of reported max_execution_time
  
  $destination = @$_REQUEST['destination'];
  $where       = 'TRUE';
  if ($destination === 's3'){
    $where     = "storage = '' OR storage IS NULL";
  }
  else{
    $where     = "storage = 's3'";
  }
  $where      .= " AND fieldName != ''"; // do not include expired uploads (upload records with empty fieldname)
  
  $uploads     = mysql_select('uploads', "$where LIMIT $maxUploadsPerRequest");
  
  $processedCount  = 0;
  $toProcessCount  = count($uploads);
  $withErrorsCount = 0;

  foreach ($uploads as $upload) {
    
    $processedCount += 1;
    
    if (_aws_s3_uploads_migrate_haveErrors($upload, $destination)) { $withErrorsCount += 1; continue; }
    
    if ($destination === 's3') {
      upload_storage_strategy()->migrate_upload_to_s3($upload);
    }
    
    else {
      upload_storage_strategy()->migrate_upload_to_filesystem($upload);
    }
    
    // if we're getting close to hitting max_execute_seconds, break
    $requestElapsedTime = microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'];
    if ($requestElapsedTime > $stopAfterElapsedTime) { break; }
    
    // if max upload records limit per request has been reach, break to create a new request
    if ($processedCount == $maxUploadsPerRequest) { break; }
    
  }
  
  $done = ($processedCount == $toProcessCount);
  
  echo json_encode([
    'success'     => 1,
    'processed'   => $processedCount,
    'withError'   => $withErrorsCount . ' -> check error log',
    'elapsedTime' => microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'],
    'memoryUsed'  => memory_get_peak_usage(),
    'done'        => $done,
  ]);
  exit;
}

// error check - return true if there's an error
function _aws_s3_uploads_migrate_haveErrors($upload, $destination){
  
  $schema      = loadSchema($upload['tableName']);
  $fieldSchema = @$schema[$upload['fieldName']];
  
  // if field schema doesn't exist. ie. upload field has been deleted
  if (!$fieldSchema) {
    @trigger_error("S3 Uploads Error: Field schema for upload num {$upload['num']} is not found", E_USER_NOTICE);
    return true;
  } 
  
  // make filePath absolute
  upload_storage_strategy()->makeUploadPathAndUrlAbsolute($upload, $fieldSchema);
  
  if ($destination == "s3"){
    // check if main and thumbnail files doen'st exist
    if (!file_exists($upload['filePath'])){
      @trigger_error("S3 Uploads Error: Failed to upload to S3 - file not found {$upload['filePath']} for upload num {$upload['num']}", E_USER_NOTICE);
      return true;
    }
    
    foreach (_getThumbFieldSuffixes() as $suffix) {
      $thumbNameFilePath = $upload["thumbFilePath$suffix"];
      if ($thumbNameFilePath && !file_exists($thumbNameFilePath)){
        @trigger_error("S3 Uploads Error: Failed to upload to S3 - thumbnail file not found {$thumbNameFilePath} for upload num {$upload['num']}", E_USER_NOTICE);
        return true;
      }
    }
  }
  else{
    $s3Key = upload_storage_strategy()->getS3KeyFromUrl($upload['urlPath']);
    if (!$s3Key){
      @trigger_error("S3 Uploads Error: Failed to upload to filesystem - missing S3 Key for upload num {$upload['num']}.", E_USER_NOTICE);
      return true;
    }
    foreach (_getThumbFieldSuffixes() as $suffix) {
      if ($upload["thumbUrlPath$suffix"]) {
        $thumbS3Key = upload_storage_strategy()->getS3KeyFromUrl($upload["thumbUrlPath$suffix"]);
        if (!$thumbS3Key){
          @trigger_error("S3 Uploads Error: Failed to upload to filesystem - missing Thumb S3 Key for upload num {$upload['num']}.", E_USER_NOTICE);
          return true;
        }
      }
    }
  }
  
  return false;
}


// update the old uploads URL paths saved in a WYSIWYG field with the new URL paths
function _aws_s3_uploads_migrate_updateWysiwygContent($uploadUpdates, $preMigrateUploadRecords, $uploadDirUrl = null){
  
  $relatedRecordSchema      = loadSchema($preMigrateUploadRecords['tableName']);
  $wysiwygFieldName         = $preMigrateUploadRecords['fieldName'];
  $relatedRecordFieldSchema = @$relatedRecordSchema[$wysiwygFieldName];
  
  // return if this upload is NOT for a WYSIWYG field
  if ($relatedRecordFieldSchema['type'] != 'wysiwyg') {
    return;
  }
  
  // log error then return if the migration is not to/from s3 or file system
  $uploadStorage = $preMigrateUploadRecords['storage'] == '' || $preMigrateUploadRecords['storage'] == NULL ? 'file_system' : $preMigrateUploadRecords['storage'];
  if ($uploadStorage != 's3' && $uploadStorage != 'file_system') {
    @trigger_error("S3 Uploads Error: Skipped updating the WYSIWYG content's uploads src path - migrated from unknown storage '$uploadStorage': upload num {$preMigrateUploadRecords['num']}.", E_USER_NOTICE);
    return;
  }
  
  // get the upload URL paths: old URL => new URL
  $uploadPathsOldToNew = array();
  
  // main URL Paths
  $newMainUrlPath = $uploadUpdates['urlPath'];
  if ($uploadStorage == 's3') {
    // if migrated from s3 to filesystem
    // .. re-add upload path prefix so that we have a full relative URL path
    $newMainUrlPath = addUploadPathPrefix($newMainUrlPath, $uploadDirUrl); 
  }
  $uploadPathsOldToNew[$preMigrateUploadRecords['urlPath']] = $newMainUrlPath;
  
  // thumbnail paths for images
  foreach (_getThumbFieldSuffixes() as $suffix) {
    if (!@$preMigrateUploadRecords["thumbUrlPath$suffix"] || !@$uploadUpdates["thumbUrlPath$suffix"]) {
      continue; // skip if empty
    }
    
    $newThumbUrlPath = $uploadUpdates["thumbUrlPath$suffix"];
    if ($uploadStorage == 's3') {
      // if migrated from s3 to filesystem
      // .. re-add upload path prefix so that we have a full relative URL path
      $newThumbUrlPath = addUploadPathPrefix($newThumbUrlPath, $uploadDirUrl);
    }
    
    $uploadPathsOldToNew[$preMigrateUploadRecords["thumbUrlPath$suffix"]] = $newThumbUrlPath;
  }
 
  // get the related records to update
  $relatedRecords =  mysql_get($preMigrateUploadRecords['tableName'], $preMigrateUploadRecords['recordNum']);
  $wysiwygContent = $relatedRecords[$wysiwygFieldName];
  
  // replace the old URLs in the related record's WYSIWYG contents with the new ones
  foreach ($uploadPathsOldToNew as $oldPath => $newPath) {
    $wysiwygContent = str_replace($oldPath, $newPath, $wysiwygContent);
  }
  
  // save updated WYSIWYG content
  mysql_update($preMigrateUploadRecords['tableName'], $preMigrateUploadRecords['recordNum'], true, array($wysiwygFieldName => $wysiwygContent));
  
  return;
}


// define Upload Storage Strategy
class S3UploadStorageStrategy implements iUploadStorageStrategy {
  
  public $defaultStorageStrategy;
  function __construct() {
    $this->defaultStorageStrategy = new DefaultUploadStorageStrategy(); // provides support for uploads not in s3!
  }
  
  public function storeMainFile($mainUploadWorkingPath, $desiredFilename, $fieldSchema, &$uploadRecordDetails, $doNotUnlink = false) {
    
    // determine s3Key (which defines the url)
    $s3Key       = $this->makeUniqueKey($desiredFilename, '');
    
    // determine contentType (TODO: is this required?)
    $contentType = $this->getContentType($mainUploadWorkingPath, @$uploadRecordDetails['imageType']);
    
    // push the file to s3
    $url = aws_s3_put($s3Key, $contentType, file_get_contents($mainUploadWorkingPath));
    
    $uploadRecordDetails['storage']   = 's3';
    $uploadRecordDetails['mainS3Key'] = $s3Key;     // record this for convenience in determining s3 keys for thumbs below in storeThumbFile()
    $uploadRecordDetails['filePath']  = $s3Key;     // there is no file in the filesystem... [TODO: will this break any front-end code which checks the truthiness of this value?]
    $uploadRecordDetails['urlPath']   = $url;
    
    if (!$doNotUnlink) { unlink_on_shutdown($mainUploadWorkingPath); }
  }
  
  public function storeThumbFile($thumbWorkingPath, $fieldSchema, $suffix, &$uploadRecordDetails, $doNotUnlink = false) {
    $s3Key = "thumb$suffix/" . upload_storage_strategy()->getS3KeyFromUrl($uploadRecordDetails['urlPath']);
    $contentType = $this->getContentType($thumbWorkingPath, @$uploadRecordDetails['imageType']); // assume thumb has same image "type" as main upload
    $url = aws_s3_put($s3Key, $contentType, file_get_contents($thumbWorkingPath));
    
    $uploadRecordDetails['thumbFilePath' . $suffix] = '';
    $uploadRecordDetails['thumbUrlPath'  . $suffix] = $url;
    
    if (!$doNotUnlink) { unlink_on_shutdown($thumbWorkingPath); }
  }

  public function customStoreMainFile($mainUploadWorkingPath, $desiredFilename, $fieldSchema, &$uploadRecordDetails, $s3UploadPath, $doNotUnlink = false) {
    
    // determine s3Key (which defines the url)
    $s3Key       = $this->makeUniqueKey($desiredFilename, '');
    
    // determine contentType (TODO: is this required?)
    $contentType = $this->getContentType($mainUploadWorkingPath, @$uploadRecordDetails['imageType']);
    
    // push the file to s3
    $url = aws_s3_put($s3UploadPath.'/'.$s3Key, $contentType, file_get_contents($mainUploadWorkingPath));
    
    $uploadRecordDetails['storage']   = 's3';
    $uploadRecordDetails['mainS3Key'] = $s3Key;     // record this for convenience in determining s3 keys for thumbs below in storeThumbFile()
    $uploadRecordDetails['filePath']  = $s3Key;     // there is no file in the filesystem... [TODO: will this break any front-end code which checks the truthiness of this value?]
    $uploadRecordDetails['urlPath']   = $url;
    
    if (!$doNotUnlink) { unlink_on_shutdown($mainUploadWorkingPath); }
  }

  public function customStoreThumbFile($thumbWorkingPath, $fieldSchema, $suffix, &$uploadRecordDetails, $s3UploadPath, $doNotUnlink = false) {
    $s3Key = "$s3UploadPath/thumb$suffix/" . $uploadRecordDetails['filePath'];
    $contentType = $this->getContentType($thumbWorkingPath, @$uploadRecordDetails['imageType']); // assume thumb has same image "type" as main upload
    $url = aws_s3_put($s3Key, $contentType, file_get_contents($thumbWorkingPath));
    
    $uploadRecordDetails['thumbFilePath' . $suffix] = '';
    $uploadRecordDetails['thumbUrlPath'  . $suffix] = $url;
    
    if (!$doNotUnlink) { unlink_on_shutdown($thumbWorkingPath); }
  }

  //Abhishek
  public function storeUserPic($filePath){

    // determine contentType (TODO: is this required?)
    $imageType = mime_content_type($filePath);
    // determine s3Key (which defines the url)
    $imageExt  = ["image/jpeg"=>'jpg',"image/gif"=>"gif","image/png"=>"png"];
    $s3Key     = time().".".$imageExt[$imageType];

    // push the file to s3
    $url = aws_s3_put('users/profile_pic/'.$s3Key, $imageType, file_get_contents($filePath));

    return $url;
  }
  
  public function makeUploadPathAndUrlAbsolute(&$record, $fieldSchema) {
    
    // support legacy uploads (i.e. uploads from before this plugin was activated, which still live in the filesystem)
    if ($record['storage'] == '') {
      return $this->defaultStorageStrategy->makeUploadPathAndUrlAbsolute($record, $fieldSchema);
    }
    
    // noop -- the url is already absolute and the path is ''
    
  }
  
  public function removeUploadsForRecord($record) {
    
    // support legacy uploads (i.e. uploads from before this plugin was activated, which still live in the filesystem)
    if ($record['storage'] == '') {
      return $this->defaultStorageStrategy->removeUploadsForRecord($record);
    }
    
    // loop through url fields, extract s3 keys, delete them from s3
    foreach ($GLOBALS['UPLOAD_URL_PATH_FIELDS'] as $urlPathField) {
      $s3Key = $this->getS3KeyFromUrl($record[$urlPathField]);
      if ($s3Key) {
        aws_s3_delete($s3Key);
      }
    }
    
  }
  
  public function resizeThumb($uploadRecord, $thumbNum, $maxWidth, $maxHeight, $cropThumb = false) {
    
    // support legacy uploads (i.e. uploads from before this plugin was activated, which still live in the filesystem)
    if ($uploadRecord['storage'] == '') {
      return $this->defaultStorageStrategy->resizeThumb($uploadRecord, $thumbNum, $maxWidth, $maxHeight);
    }
    
    // check if extension implies this is an image
    $isImage = preg_match("/\.(gif|jpg|jpeg|png)$/i", $uploadRecord['urlPath']);
    if (!$isImage) {
      return [ null, null, null, null ];
    }

    // download the main image to the "working directory"
    $schema = loadSchema( $uploadRecord['tableName'] );
    list($workingDir) = getUploadDirAndUrl($schema[ $uploadRecord['fieldName'] ]);
    
    $tmpMainFilePath = tempnam($workingDir, 'temp_resize_');
    unlink_on_shutdown($tmpMainFilePath);

    $mainS3Key = $this->getS3KeyFromUrl($uploadRecord['urlPath']);
    aws_s3_get_saveToFile($mainS3Key, $tmpMainFilePath);
    
    // resample
    $tmpThumbFilePath = tempnam($workingDir, 'temp_resize_');
    unlink_on_shutdown($tmpThumbFilePath);
    
    list($thumbWidth, $thumbHeight, $imageType) = saveResampledImageAs($tmpThumbFilePath, $tmpMainFilePath, $maxWidth, $maxHeight, $cropThumb);
    doAction('upload_thumbnail_save', array($uploadRecord['tableName'], $uploadRecord['fieldName'], $thumbNum, $tmpThumbFilePath));
    
    // aws_s3_put
    $thumbS3Key   = "thumb$thumbNum/$mainS3Key";
    $contentType  = $this->getContentType($tmpMainFilePath, $imageType);
    $thumbUrlPath = aws_s3_put($thumbS3Key, $contentType, file_get_contents($tmpThumbFilePath));
    
    // return file path(null), url path, width, and height
    return [ null, $thumbUrlPath, $thumbWidth, $thumbHeight ];
  }
  
  // Migration
  // ---------
  
  public function migrate_upload_to_s3($upload) {
    
    if ($upload['storage'] == 's3') { return; } // already migrated
    if ($upload['storage'] != '')   { die("Cannot migrate from unknown storage: " . htmlencode($upload['storage'])); }
    
    $schema      = loadSchema($upload['tableName']);
    $fieldSchema = @$schema[$upload['fieldName']];
    
    // make filePath absolute
    $this->makeUploadPathAndUrlAbsolute($upload, $fieldSchema);
    
    // migrate main upload (for safety, do not unlink until after we update the upload record)
    $update = [];
    $desiredFilename = basename($upload['filePath']); // TODO: consider removing numbered suffix (e.g. "_001") because we may add a hash suffix too (e.g. "example_001_3b12c03f.jpg")
    $this->storeMainFile($upload['filePath'], $desiredFilename, $fieldSchema, $update, 'DO_NOT_UNLINK');
    
    // migrate thumbs (for safety, do not unlink until after we update the upload record)
    foreach (_getThumbFieldSuffixes() as $suffix) {
      if ($upload["thumbFilePath$suffix"]) {
        $this->storeThumbFile($upload["thumbFilePath$suffix"], $fieldSchema, $suffix, $update, 'DO_NOT_UNLINK');
      }
    }
    
    // remove fake field
    unset($update['mainS3Key']);
    
    // update upload record
    mysql_update('uploads', $upload['num'], null, $update);
    
    // unlink uploads from filesystem (main file and thumbs)
    unlink($upload['filePath']);
    foreach (_getThumbFieldSuffixes() as $suffix) {
      if ($upload["thumbFilePath$suffix"] && file_exists($upload["thumbFilePath$suffix"])) {
        unlink($upload["thumbFilePath$suffix"]);
      }
    }
    
    // update WYSIWYG content's img src with the new image URL path
    _aws_s3_uploads_migrate_updateWysiwygContent($update, $upload);
  }

  public function migrate_upload_to_filesystem($upload) {
    
    if ($upload['storage'] == '')   { return; } // already migrated
    if ($upload['storage'] != 's3') { die("Cannot migrate from unknown storage: " . htmlencode($upload['storage'])); }

    $schema      = loadSchema($upload['tableName']);
    $fieldSchema = @$schema[$upload['fieldName']];
    
    // choose filename of main upload file
    list($uploadDir, $uploadUrl) = getUploadDirAndUrl($fieldSchema);
    
    // choose a uniqueNumberedFilename_123.ext
    $desiredFilename = $upload['filePath'];
    list(, $mainUploadFilepath) = _saveUpload_chooseUniqueNumberedFilename( $desiredFilename, $uploadDir );
    
    $update = [
      'storage' => '',
    ];
    
    // download main upload from s3
    $s3Key = $this->getS3KeyFromUrl($upload['urlPath']);
    aws_s3_get_saveToFile($s3Key, $mainUploadFilepath);
    $urlPath            = _getUploadUrlFromPath($fieldSchema, $mainUploadFilepath);
    $update['filePath'] = removeUploadPathPrefix($mainUploadFilepath, $uploadDir);
    $update['urlPath']  = removeUploadPathPrefix($urlPath,            $uploadUrl);

    // download thumbs from s3
    foreach (_getThumbFieldSuffixes() as $suffix) {
      if ($upload["thumbUrlPath$suffix"]) {
        $thumbS3Key    = $this->getS3KeyFromUrl($upload["thumbUrlPath$suffix"]);
        $thumbFilepath = preg_replace("|([^/]+)$|", "thumb$suffix/$1", $mainUploadFilepath);
        
        aws_s3_get_saveToFile($thumbS3Key, $thumbFilepath);
        $thumbUrl                       = _getUploadUrlFromPath($fieldSchema, $thumbFilepath);
        $thumbUrl                       = preg_replace("|([^/]+)$|", "thumb$suffix/$1", $thumbUrl);
        $update["thumbFilePath$suffix"] = removeUploadPathPrefix($thumbFilepath, $uploadDir);
        $update["thumbUrlPath$suffix"]  = removeUploadPathPrefix($thumbUrl,      $uploadUrl);
      }
    }
    
    // update upload record
    mysql_update('uploads', $upload['num'], null, $update);
    
    // remove objects from s3
    aws_s3_delete($s3Key);
    
    foreach (_getThumbFieldSuffixes() as $suffix) {
      if ($upload["thumbUrlPath$suffix"]) {
        $thumbS3Key = $this->getS3KeyFromUrl($upload["thumbUrlPath$suffix"]);
        
        if ($thumbS3Key){ aws_s3_delete($thumbS3Key); }
      }
    }
    
    // update WYSIWYG content's img src with the new image URL path
    _aws_s3_uploads_migrate_updateWysiwygContent($update, $upload, $uploadUrl);
  }
  
  // we aren't recording the s3 key independently, but we can extract it from the url (assuming no url-encoded characters were used!)
  public function getS3KeyFromUrl($url) {
    $url   = urldecode($url);
    $s3Key = null;
    if (preg_match('#^\w+://[^/]+/[^/]+/(.*)#', $url, $matches)) { // e.g. "protocol://domain/bucket/KEY"
      list (, $s3Key) = $matches;
    }
    return $s3Key;
  }
  
  // Private methods
  // ---------------
  
  // given a user-reported filename "myfile.gif", find a unique key in the bucket, preferring "myfile.gif", but falling back on "myfile_HASHHASH.gif"
  private function makeUniqueKey($desiredFilename, $keyPrefix) {
    list($saveAsBasename, $saveAsExtension) = _saveUpload_getTargetBasenameAndExtension($desiredFilename);
    $hash = '';
    $counter = 0;
    while (true) {
      $key = $keyPrefix . $saveAsBasename . $hash . '.' . $saveAsExtension;

      if (!aws_s3_exists($key)) { return $key; }
      
      $hash = '_' . substr(uniqid(''), -8); // last 8 chars of random hex chars
      
      $counter += 1;
      if ($counter > 100) {
        die(__FUNCTION__ . " was unable to find a unique s3 key after 100 tries");
      }
      
    }
  }
  
  // when "put"ting a file to s3, we can supply the Content-Type that s3 will supply when users request it.
  // this method makes a guess as to the content-type we should set.
  private function getContentType($filePath, $imageType) {
    switch ($imageType) {
      case IMAGETYPE_JPEG:
        return "image/jpeg";
      case IMAGETYPE_GIF:
        return "image/gif";
      case IMAGETYPE_PNG:
        return "image/png";
      default:
        return mime_content_type($filePath);
    }
  }
  
}

// now that everything is defined, call the function at the top of this file
aws_s3_uploads_init();

