/** * Test that isObjectAvailable() works if object name contains spaces * * @depends testCreateBucket * @depends testObjectPath * * ZF-10017 */ public function testIsObjectAvailableWithSpacesInKey() { $this->_amazon->createBucket($this->_bucket); $filedir = dirname(__FILE__) . "/_files/"; $key = $this->_bucket . '/subdir/another dir with spaces/zftestfile.html'; $this->_amazon->putFile($filedir . "testdata.html", $key); $this->assertTrue($this->_amazon->isObjectAvailable($key)); }
/** * Test bucket name with /'s and encoding * * ZF-6855 * */ public function testObjectPath() { $this->_amazon->createBucket($this->_bucket); $filedir = __DIR__ . "/_files/"; $this->_amazon->putFile($filedir . "testdata.html", $this->_bucket . "/subdir/dir with spaces/zftestfile.html", array(S3\S3::S3_ACL_HEADER => S3\S3::S3_ACL_PUBLIC_READ)); $url = 'http://' . S3\S3::S3_ENDPOINT . "/" . $this->_bucket . "/subdir/dir%20with%20spaces/zftestfile.html"; $data = @file_get_contents($url); $this->assertEquals(file_get_contents($filedir . "testdata.html"), $data); }
public function syncDirectory() { $accessKey = Mage::getStoreConfig('amazonsync/general/access_key_id'); $secretKey = Mage::getStoreConfig('amazonsync/general/secret_access_key'); $bucket = Mage::getStoreConfig('amazonsync/general/s3_bucket_path'); $prefix = Mage::getStoreConfig('amazonsync/general/prefix'); $magentoDir = Mage::getStoreConfig('amazonsync/general/magento_directory'); $magentoDir = Mage::getBaseDir() . "/" . $magentoDir; //Return if S3 settings are empty if (!($accessKey && $secretKey && $bucket)) { return; } //Prepare meta data for uploading. All uploaded images are public $meta = array(Zend_Service_Amazon_S3::S3_ACL_HEADER => Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ); $s3 = new Zend_Service_Amazon_S3($accessKey, $secretKey); //Build prefix for all files on S3 if ($prefix) { $cdnPrefix = $bucket . '/' . $prefix; } else { $cdnPrefix = $bucket; } $allFiles = array(); if (is_dir($magentoDir)) { $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($magentoDir), RecursiveIteratorIterator::SELF_FIRST); $dir = null; foreach ($objects as $name => $object) { //Get name of the file and create its key on S3 if (!($object->getFileName() == '.' || $object->getFileName() == '..')) { if (is_dir($object)) { continue; } $fileName = str_replace($magentoDir, '', $name); $cdnPath = $cdnPrefix . $fileName; //Full path to uploaded file $file = $name; //Upload original file $allFiles[] = $cdnPath; if (!$s3->putFile($file, $cdnPath, $meta)) { $msg = 'Can\'t upload original image (' . $file . ') to S3 with ' . $cdnPath . ' key'; throw new Mage_Core_Exception($msg); } } } //Remove Not Matched Files foreach ($s3->getObjectsByBucket($bucket) as $object) { $object = $bucket . '/' . $object; if (!in_array($object, $allFiles)) { $s3->removeObject($object); } } return 'All files uploaded to S3 with ' . $bucket . ' bucket'; } else { $msg = $magentoDir . ' directory does not exist'; throw new Mage_Core_Exception($msg); } }
/** * Stores a local file in the storage service * * @param Zend_Form_Element_File|array|string $file Temporary local file to store * @param array $params Contains iden * @return string Storage type specific path (internal use only) */ public function store(Storage_Model_File $model, $file) { $path = $this->getScheme()->generate($model->toArray()); // Prefix path with bucket? //$path = $this->_bucket . '/' . $path; // Copy file try { $return = $this->_internalService->putFile($file, $this->_bucket . '/' . $path, array(Zend_Service_Amazon_S3::S3_ACL_HEADER => Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ, 'Cache-Control' => 'max-age=864000, public')); if (!$return) { throw new Storage_Service_Exception('Unable to store file.'); } } catch (Exception $e) { throw $e; } return $path; }
/** * Upload placeholders to CDN * * @return null */ public function uploadAction() { $website = $this->getRequest()->getParam('website'); $website = Mage::app()->getWebsite($website); if (!$website->getId()) { return $this->_back('No website parameter', self::ERROR, $website); } $store = $website->getDefaultStore(); $accessKey = $store->getConfig(MVentory_CDN_Model_Config::ACCESS_KEY); $secretKey = $store->getConfig(MVentory_CDN_Model_Config::SECRET_KEY); $bucket = $store->getConfig(MVentory_CDN_Model_Config::BUCKET); $prefix = $store->getConfig(MVentory_CDN_Model_Config::PREFIX); $dimensions = $store->getConfig(MVentory_CDN_Model_Config::DIMENSIONS); Mage::log($dimensions); if (!($accessKey && $secretKey && $bucket && $prefix)) { return $this->_back('CDN settings are not specified', self::ERROR, $website); } unset($path); $config = Mage::getSingleton('catalog/product_media_config'); $destSubdirs = array('image', 'small_image', 'thumbnail'); $placeholders = array(); $appEmulation = Mage::getModel('core/app_emulation'); $env = $appEmulation->startEnvironmentEmulation($store->getId()); foreach ($destSubdirs as $destSubdir) { $placeholder = Mage::getModel('catalog/product_image')->setDestinationSubdir($destSubdir)->setBaseFile(null)->getBaseFile(); $basename = basename($placeholder); $result = copy($placeholder, $config->getMediaPath($basename)); if ($result !== true) { return $this->_back('Error on copy ' . $placeholder . ' to media folder', self::ERROR, $website); } $placeholders[] = '/' . $basename; } $appEmulation->stopEnvironmentEmulation($env); unset($store); unset($appEmulation); $s3 = new Zend_Service_Amazon_S3($accessKey, $secretKey); $cdnPrefix = $bucket . '/' . $prefix . '/'; $dimensions = str_replace(', ', ',', $dimensions); $dimensions = explode(',', $dimensions); $meta = array(Zend_Service_Amazon_S3::S3_ACL_HEADER => Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ); foreach ($placeholders as $fileName) { $cdnPath = $cdnPrefix . 'full' . $fileName; $file = $config->getMediaPath($fileName); try { $s3->putFile($file, $cdnPath, $meta); } catch (Exception $e) { return $this->_back($e->getMessage(), self::ERROR, $website); } if (!count($dimensions)) { continue; } foreach ($dimensions as $dimension) { $newCdnPath = $cdnPrefix . $dimension . $fileName; $productImage = Mage::getModel('catalog/product_image'); $destinationSubdir = ''; foreach ($destSubdirs as $destSubdir) { $newFile = $productImage->setDestinationSubdir($destSubdir)->setSize($dimension)->setBaseFile($fileName)->getNewFile(); if (file_exists($newFile)) { $destinationSubdir = $destSubdir; break; } } if ($destinationSubdir == '') { try { $newFile = $productImage->setDestinationSubdir($destinationSubdir)->setSize($dimension)->setBaseFile($fileName)->resize()->saveFile()->getNewFile(); } catch (Exception $e) { return $this->_back($e->getMessage(), self::ERROR, $website); } } try { $s3->putFile($newFile, $newCdnPath, $meta); } catch (Exception $e) { return $this->_back($e->getMessage(), self::ERROR, $website); } } } return $this->_back('Successfully uploaded all placeholders', self::SUCCESS, $website); }
public function upload($observer) { $product = $observer->getEvent()->getProduct(); //There's nothing to process because we're using images //from original product in duplicate if ($product->getIsDuplicate() || $product->getData('mventory_update_duplicate')) { return; } $images = $observer->getEvent()->getImages(); //Use product helper from MVentory_API if it's installed and is activated //The helper is used to get correct store for the product when MVentory_API //extension is used //Change current store if product's store is different for correct //file name of images if (Mage::helper('core')->isModuleEnabled('MVentory_API')) { $store = Mage::helper('mventory/product')->getWebsite($product)->getDefaultStore(); $changeStore = $store->getId() != Mage::app()->getStore()->getId(); } else { $store = Mage::app()->getStore(); $changeStore = false; } //Get settings for S3 $accessKey = $store->getConfig(MVentory_CDN_Model_Config::ACCESS_KEY); $secretKey = $store->getConfig(MVentory_CDN_Model_Config::SECRET_KEY); $bucket = $store->getConfig(MVentory_CDN_Model_Config::BUCKET); $prefix = $store->getConfig(MVentory_CDN_Model_Config::PREFIX); $dimensions = $store->getConfig(MVentory_CDN_Model_Config::DIMENSIONS); $cacheTime = (int) $store->getConfig(MVentory_CDN_Model_Config::CACHE_TIME); //Return if S3 settings are empty if (!($accessKey && $secretKey && $bucket && $prefix)) { return; } //Build prefix for all files on S3 $cdnPrefix = $bucket . '/' . $prefix . '/'; //Parse dimension. Split string to pairs of width and height $dimensions = str_replace(', ', ',', $dimensions); $dimensions = explode(',', $dimensions); //Prepare meta data for uploading. All uploaded images are public $meta = array(Zend_Service_Amazon_S3::S3_ACL_HEADER => Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ); if ($cacheTime > 0) { $meta[MVentory_CDN_Model_Config::AMAZON_CACHE_CONTROL] = 'max-age=' . $cacheTime; } if ($changeStore) { $emu = Mage::getModel('core/app_emulation'); $origEnv = $emu->startEnvironmentEmulation($store); } $config = Mage::getSingleton('catalog/product_media_config'); $s3 = new Zend_Service_Amazon_S3($accessKey, $secretKey); foreach ($images['images'] as &$image) { //Process new images only if (isset($image['value_id'])) { continue; } //Get name of the image and create its key on S3 $fileName = $image['file']; $cdnPath = $cdnPrefix . 'full' . $fileName; //Full path to uploaded image $file = $config->getMediaPath($fileName); //Check if object with the key exists if ($s3->isObjectAvailable($cdnPath)) { $position = strrpos($fileName, '.'); //Split file name and extension $name = substr($fileName, 0, $position); $ext = substr($fileName, $position); //Search key $_key = $prefix . '/full' . $name . '_'; //Get all objects which is started with the search key $keys = $s3->getObjectsByBucket($bucket, array('prefix' => $_key)); $index = 1; //If there're objects which names begin with the search key then... if (count($keys)) { $extLength = strlen($ext); $_keys = array(); //... store object names without extension as indeces of the array //for fast searching foreach ($keys as $key) { $_keys[substr($key, 0, -$extLength)] = true; } //Find next unused object name while (isset($_keys[$_key . $index])) { ++$index; } unset($_keys); } //Build new name and path with selected index $fileName = $name . '_' . $index . $ext; $cdnPath = $cdnPrefix . 'full' . $fileName; //Get new name for uploaded file $_file = $config->getMediaPath($fileName); //Rename file uploaded to Magento rename($file, $_file); //Update values of media attribute in the product after renaming //uploaded image if the image was marked as 'image', 'small_image' //or 'thumbnail' in the product foreach ($product->getMediaAttributes() as $mediaAttribute) { $code = $mediaAttribute->getAttributeCode(); if ($product->getData($code) == $image['file']) { $product->setData($code, $fileName); } } //Save its new name in Magento $image['file'] = $fileName; $file = $_file; unset($_file); } //Upload original image if (!$s3->putFile($file, $cdnPath, $meta)) { $msg = 'Can\'t upload original image (' . $file . ') to S3 with ' . $cdnPath . ' key'; if ($changeStore) { $emu->stopEnvironmentEmulation($origEnv); } throw new Mage_Core_Exception($msg); } //Go to next newly uploaded image if image dimensions for resizing //were not set if (!count($dimensions)) { continue; } //For every dimension... foreach ($dimensions as $dimension) { //... resize original image and get path to resized image $newFile = Mage::getModel('catalog/product_image')->setDestinationSubdir('image')->setSize($dimension)->setKeepFrame(false)->setConstrainOnly(true)->setBaseFile($fileName)->resize()->saveFile()->getNewFile(); //Build S3 path for the resized image $newCdnPath = $cdnPrefix . $dimension . $fileName; //Upload resized images if (!$s3->putFile($newFile, $newCdnPath, $meta)) { $msg = 'Can\'t upload resized (' . $dimension . ') image (' . $file . ') to S3 with ' . $cdnPath . ' key'; if ($changeStore) { $emu->stopEnvironmentEmulation($origEnv); } throw new Mage_Core_Exception($msg); } } } if ($changeStore) { $emu->stopEnvironmentEmulation($origEnv); } }
if ($result === true) { $images[] = '/' . basename($placeholder); } else { Mage::log('Error on copy ' . $placeholder . ' to media folder', null, 's3.log'); } } $s3 = new Zend_Service_Amazon_S3($accessKey, $secretKey); $imageNumber = 1; foreach ($images as $fileName) { Mage::log('Processing image ' . $imageNumber++ . ' of ' . $totalImages, null, 's3.log'); $cdnPath = $cdnPrefix . 'full' . $fileName; $file = $config->getMediaPath($fileName); if (!$s3->isObjectAvailable($cdnPath)) { Mage::log('Trying to upload original file ' . $file . ' as ' . $cdnPath, null, 's3.log'); try { $s3->putFile($file, $cdnPath, $meta); } catch (Exception $e) { Mage::log($e->getMessage(), null, 's3.log'); continue; } } else { Mage::log('File ' . $file . ' has been already uploaded', null, 's3.log'); } if (!count($dimensions)) { continue; } foreach ($dimensions as $dimension) { $newCdnPath = $cdnPrefix . $dimension . $fileName; if ($s3->isObjectAvailable($newCdnPath)) { Mage::log('Resized (' . $dimension . ') file ' . $file . ' has been already uploaded', null, 's3.log'); continue;
public function addFile($fileInfo, $userInfo, $privacy = false, $details = false) { $config = self::$_registry->get("config"); $s3 = new Zend_Service_Amazon_S3($config['services']['S3']['key'], $config['services']['S3']['secret']); $filenameFilter = new Ml_Filter_FilenameRobot(); $filenameValidator = new Ml_Validate_Filename(); if (isset($details['title']) && !empty($details['title'])) { $title = $details['title']; } else { $title = mb_substr(trim($fileInfo['name']), 0, 100); /* try to use a good initial title for the file */ $titleNameposition = mb_strrpos($title, "."); $titleSize = mb_strlen($title); if ($titleSize > 5 && $titleSize - $titleNameposition <= 5) { $tryTitle = mb_substr($title, 0, $titleNameposition); if (!empty($tryTitle) && strrpos($tryTitle, ".") < mb_strlen($tryTitle) - 4) { $title = $tryTitle; } } } //get the max value of mt_getrandmax() or the max value of the unsigned int type $maxRand = mt_getrandmax() < 4294967295.0 ? mt_getrandmax() : 4294967295.0; $secret = mt_rand(0, $maxRand); $downloadSecret = mt_rand(0, $maxRand); $filename = $filenameFilter->filter($fileInfo['name']); if (!$filenameValidator->isValid($filename)) { $extension = $filenameFilter->filter(strchr($filename, '.')); if ($filenameValidator->isValid($extension)) { $filename = mt_rand() . $extension; } else { $filename = mt_rand(); } } $this->_dbAdapter->beginTransaction(); try { $this->_dbAdapter->insert("upload_history", array("byUid" => $userInfo['id'], "fileSize" => $fileInfo['size'], "filename" => $fileInfo['name'])); $uploadId = $this->_dbAdapter->lastInsertId("upload_history"); if (!$uploadId) { throw new Exception("Can not create upload ID."); } $objectKey = $userInfo['alias'] . "/" . $uploadId . "-" . $downloadSecret . "/" . $filename; $put = $s3->putFile($fileInfo['tmp_name'], $config['services']['S3']['sharesBucket'] . "/" . $objectKey, array(Zend_Service_Amazon_S3::S3_ACL_HEADER => Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ, "Content-Type" => Zend_Service_Amazon_S3::getMimeType($objectKey), 'Content-Disposition' => 'attachment;', "x-amz-meta-id" => $uploadId, "x-amz-meta-uid" => $userInfo['id'], "x-amz-meta-username" => $userInfo['alias'])); if (!$put) { throw new Exception("Could not upload to storage service."); } $getInfo = $s3->getInfo($objectKey); //If for error we can't retrieve the md5 from the s3 server... if (!$getInfo) { $md5 = md5_file($fileInfo['tmp_name']); } else { $md5 = $getInfo['etag']; } if (!isset($details['short'])) { $details['short'] = ''; } if (!isset($details['description'])) { $details['description'] = ''; } $this->_dbTable->insert(array("id" => $uploadId, "byUid" => $userInfo['id'], "secret" => $secret, "download_secret" => $downloadSecret, "privacy" => $privacy, "title" => $title, "filename" => $filename, "short" => $details['short'], "description" => $details['description'], "type" => mb_substr($fileInfo['type'], 0, 50), "fileSize" => $fileInfo['size'], "md5" => $md5)); if (!$this->_dbAdapter->lastInsertId()) { throw new Exception("Could not create insert for new file."); } $this->_dbAdapter->commit(); return $uploadId; } catch (Exception $e) { $this->_dbAdapter->rollBack(); throw $e; } }
public function setAvatar($userInfo, $source) { $registry = Zend_Registry::getInstance(); $config = $registry->get("config"); $people = Ml_Model_People::getInstance(); $s3config = $config['services']['S3']; $s3 = new Zend_Service_Amazon_S3($s3config['key'], $s3config['secret']); try { $im = new Imagick($source); $im->setimagecompressionquality(self::$_imageQuality); $dim = $im->getimagegeometry(); if (!$dim) { return false; } } catch (Exception $e) { return false; } $sizesInfo = array(); $tmpFilenames = array(); $im->unsharpMaskImage(0, 0.5, 1, 0.05); foreach ($this->_sizes as $sizeInfo) { $tmpFilenames[$sizeInfo[1]] = tempnam(sys_get_temp_dir(), 'HEADSHOT'); if ($sizeInfo[0] == "sq") { if ($dim['height'] < $dim['width']) { $size = $dim['height']; } else { $size = $dim['width']; } //@todo let the user crop using Javascript, so he/she can set the offsets (default 0,0) $im->cropThumbnailImage($sizeInfo[3], $sizeInfo[3]); } else { if ($dim['width'] < $sizeInfo[3] && $dim['height'] < $sizeInfo[3] && $sizeInfo[2] != 'huge') { copy($source, $tmpFilenames[$sizeInfo[1]]); } else { if ($dim['width'] > $dim['height']) { $im->resizeimage($sizeInfo[3], 0, Imagick::FILTER_LANCZOS, 1); } else { $im->resize(0, $sizeInfo[3], Imagick::FILTER_LANCZOS, 1); } } } $im->writeimage($tmpFilenames[$sizeInfo[1]]); $imGeometry = $im->getimagegeometry(); $sizesInfo[$sizeInfo[0]] = array("w" => $imGeometry['width'], "h" => $imGeometry['height']); } $oldData = unserialize($userInfo['avatarInfo']); //get the max value of mt_getrandmax() or the max value of the unsigned int type if (mt_getrandmax() < 4294967295.0) { $maxRand = mt_getrandmax(); } else { $maxRand = 4294967295.0; } $newSecret = mt_rand(0, $maxRand); if (isset($oldData['secret'])) { while ($oldData['secret'] == $newSecret) { $newSecret = mt_rand(0, $maxRand); } } foreach ($tmpFilenames as $size => $file) { if ($size == '_h') { $privacy = Zend_Service_Amazon_S3::S3_ACL_PRIVATE; } else { $privacy = Zend_Service_Amazon_S3::S3_ACL_PUBLIC_READ; } $picAddr = $s3config['headshotsBucket'] . "/" . $userInfo['id'] . '-' . $newSecret . $size . '.jpg'; $meta = array(Zend_Service_Amazon_S3::S3_ACL_HEADER => $privacy, "Content-Type" => Zend_Service_Amazon_S3::getMimeType($picAddr), "Cache-Control" => "max-age=37580000, public", "Expires" => "Thu, 10 May 2029 00:00:00 GMT"); $s3->putFile($file, $picAddr, $meta); unlink($file); } $newAvatarInfo = serialize(array("sizes" => $sizesInfo, "secret" => $newSecret)); $people->update($userInfo['id'], array("avatarInfo" => $newAvatarInfo)); //delete the old files $this->deleteFiles($userInfo); return true; }