00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 class Mage_Catalog_Model_Product_Option_Type_File extends Mage_Catalog_Model_Product_Option_Type_Default
00035 {
00036 public function isCustomizedView()
00037 {
00038 return true;
00039 }
00040
00041
00042
00043
00044
00045
00046
00047 public function getCustomizedView($optionInfo)
00048 {
00049 try {
00050 $result = $this->_getOptionHtml($optionInfo['option_value']);
00051 return $result;
00052 } catch (Exception $e) {
00053 return $optionInfo['value'];
00054 }
00055 }
00056
00057
00058
00059
00060
00061
00062
00063
00064 public function validateUserValue($values)
00065 {
00066 Mage::getSingleton('checkout/session')->setUseNotice(false);
00067
00068 $this->setIsValid(true);
00069 $option = $this->getOption();
00070
00071
00072 if (isset($values[$option->getId()]) && is_array($values[$option->getId()])) {
00073 if (isset($values[$option->getId()]['order_path'])) {
00074 $orderFileFullPath = Mage::getBaseDir() . $values[$option->getId()]['order_path'];
00075 } else {
00076 $this->setUserValue(null);
00077 return $this;
00078 }
00079
00080 $ok = is_file($orderFileFullPath) && is_readable($orderFileFullPath)
00081 && isset($values[$option->getId()]['secret_key'])
00082 && substr(md5(file_get_contents($orderFileFullPath)), 0, 20) == $values[$option->getId()]['secret_key'];
00083
00084 $this->setUserValue($ok ? $values[$option->getId()] : null);
00085 return $this;
00086 } elseif ($this->getProduct()->getSkipCheckRequiredOption()) {
00087 $this->setUserValue(null);
00088 return $this;
00089 }
00090
00091
00092
00093
00094 $upload = new Zend_File_Transfer_Adapter_Http();
00095 $file = 'options_' . $option->getId() . '_file';
00096
00097 try {
00098 $runValidation = $option->getIsRequire() || $upload->isUploaded($file);
00099 if (!$runValidation) {
00100 $this->setUserValue(null);
00101 return $this;
00102 }
00103
00104 $fileInfo = $upload->getFileInfo($file);
00105 $fileInfo = $fileInfo[$file];
00106
00107 } catch (Exception $e) {
00108
00109 if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > $this->_getUploadMaxFilesize()) {
00110 $this->setIsValid(false);
00111 Mage::throwException(
00112 Mage::helper('catalog')->__("The file you uploaded is larger than %s Megabytes allowed by server",
00113 $this->_bytesToMbytes($this->_getUploadMaxFilesize())
00114 )
00115 );
00116 } else {
00117 $this->setUserValue(null);
00118 return $this;
00119 }
00120 }
00121
00122
00123
00124
00125
00126
00127 $_dimentions = array();
00128 if ($option->getImageSizeX() > 0 && $this->_isImage($fileInfo)) {
00129 $_dimentions['maxwidth'] = $option->getImageSizeX();
00130 }
00131 if ($option->getImageSizeY() > 0 && $this->_isImage($fileInfo)) {
00132 $_dimentions['maxheight'] = $option->getImageSizeY();
00133 }
00134 if (count($_dimentions) > 0) {
00135 $upload->addValidator('ImageSize', false, $_dimentions);
00136 }
00137
00138
00139 $_allowed = $this->_parseExtensionsString($option->getFileExtension());
00140 if ($_allowed !== null) {
00141 $upload->addValidator('Extension', false, $_allowed);
00142 } else {
00143 $_forbidden = $this->_parseExtensionsString($this->getConfigData('forbidden_extensions'));
00144 if ($_forbidden !== null) {
00145 $upload->addValidator('ExcludeExtension', false, $_forbidden);
00146 }
00147 }
00148
00149
00150 $upload->addValidator('FilesSize', false, array('max' => $this->_getUploadMaxFilesize()));
00151
00152
00153
00154
00155
00156 $this->_initFilesystem();
00157
00158 if ($upload->isUploaded($file) && $upload->isValid($file)) {
00159
00160 $extension = pathinfo(strtolower($fileInfo['name']), PATHINFO_EXTENSION);
00161
00162 $fileName = Varien_File_Uploader::getCorrectFileName($fileInfo['name']);
00163 $dispersion = Varien_File_Uploader::getDispretionPath($fileName);
00164
00165 $filePath = $dispersion;
00166 $destination = $this->getQuoteTargetDir() . $filePath;
00167 $this->_createWriteableDir($destination);
00168 $upload->setDestination($destination);
00169
00170 $fileHash = md5(file_get_contents($fileInfo['tmp_name']));
00171 $filePath .= DS . $fileHash . '.' . $extension;
00172
00173 $fileFullPath = $this->getQuoteTargetDir() . $filePath;
00174
00175 $upload->addFilter('Rename', array(
00176 'target' => $fileFullPath,
00177 'overwrite' => true
00178 ));
00179 if (!$upload->receive()) {
00180 $this->setIsValid(false);
00181 Mage::throwException(Mage::helper('catalog')->__("File upload failed"));
00182 }
00183
00184 $_imageSize = @getimagesize($fileFullPath);
00185 if (is_array($_imageSize) && count($_imageSize) > 0) {
00186 $_width = $_imageSize[0];
00187 $_height = $_imageSize[1];
00188 } else {
00189 $_width = 0;
00190 $_height = 0;
00191 }
00192
00193 $this->setUserValue(array(
00194 'type' => $fileInfo['type'],
00195 'title' => $fileInfo['name'],
00196 'quote_path' => $this->getQuoteTargetDir(true) . $filePath,
00197 'order_path' => $this->getOrderTargetDir(true) . $filePath,
00198 'fullpath' => $fileFullPath,
00199 'size' => $fileInfo['size'],
00200 'width' => $_width,
00201 'height' => $_height,
00202 'secret_key' => substr($fileHash, 0, 20)
00203 ));
00204
00205 } elseif ($upload->getErrors()) {
00206 $errors = array();
00207 foreach ($upload->getErrors() as $errorCode) {
00208 if ($errorCode == Zend_Validate_File_ExcludeExtension::FALSE_EXTENSION) {
00209 $errors[] = Mage::helper('catalog')->__("The file '%s' for '%s' has an invalid extension",
00210 $fileInfo['name'],
00211 $option->getTitle()
00212 );
00213 } elseif ($errorCode == Zend_Validate_File_Extension::FALSE_EXTENSION) {
00214 $errors[] = Mage::helper('catalog')->__("The file '%s' for '%s' has an invalid extension",
00215 $fileInfo['name'],
00216 $option->getTitle()
00217 );
00218 } elseif ($errorCode == Zend_Validate_File_ImageSize::WIDTH_TOO_BIG
00219 || $errorCode == Zend_Validate_File_ImageSize::WIDTH_TOO_BIG)
00220 {
00221 $errors[] = Mage::helper('catalog')->__("Maximum allowed image size for '%s' is %sx%s px.",
00222 $option->getTitle(),
00223 $option->getImageSizeX(),
00224 $option->getImageSizeY()
00225 );
00226 } elseif ($errorCode == Zend_Validate_File_FilesSize::TOO_BIG) {
00227 $errors[] = Mage::helper('catalog')->__("The file '%s' you uploaded is larger than %s Megabytes allowed by server",
00228 $fileInfo['name'],
00229 $this->_bytesToMbytes($this->_getUploadMaxFilesize())
00230 );
00231 }
00232 }
00233 if (count($errors) > 0) {
00234 $this->setIsValid(false);
00235 Mage::throwException( implode("\n", $errors) );
00236 }
00237 } else {
00238 $this->setIsValid(false);
00239 Mage::throwException(Mage::helper('catalog')->__('Please specify the product required option(s)'));
00240 }
00241 return $this;
00242 }
00243
00244
00245
00246
00247
00248
00249 public function prepareForCart()
00250 {
00251 if ($this->getIsValid() && $this->getUserValue() !== null) {
00252 $value = $this->getUserValue();
00253
00254 $requestOptions = $this->getRequest()->getOptions();
00255 $requestOptions[$this->getOption()->getId()] = $value;
00256 $this->getRequest()->setOptions($requestOptions);
00257 return serialize($value);
00258 } else {
00259 return null;
00260 }
00261 }
00262
00263
00264
00265
00266
00267
00268
00269 public function getFormattedOptionValue($optionValue)
00270 {
00271 if ($this->_formattedOptionValue === null) {
00272 try {
00273 $value = unserialize($optionValue);
00274
00275 $value['url'] = array(
00276 'route' => 'sales/download/downloadCustomOption',
00277 'params' => array(
00278 'id' => $this->getQuoteItemOption()->getId(),
00279 'key' => $value['secret_key']
00280 )
00281 );
00282
00283 $this->_formattedOptionValue = $this->_getOptionHtml($value);
00284 $this->getQuoteItemOption()->setValue(serialize($value));
00285 return $this->_formattedOptionValue;
00286
00287 } catch (Exception $e) {
00288 return $optionValue;
00289 }
00290 }
00291 return $this->_formattedOptionValue;
00292 }
00293
00294
00295
00296
00297
00298
00299
00300 protected function _getOptionHtml($optionValue)
00301 {
00302 try {
00303 $value = unserialize($optionValue);
00304 } catch (Exception $e) {
00305 $value = $optionValue;
00306 }
00307 try {
00308 if ($value['width'] > 0 && $value['height'] > 0) {
00309 $sizes = $value['width'] . ' x ' . $value['height'] . ' ' . Mage::helper('catalog')->__('px.');
00310 } else {
00311 $sizes = '';
00312 }
00313 return sprintf('<a href="%s" target="_blank">%s</a> %s',
00314 $this->_getOptionDownloadUrl($value['url']['route'], $value['url']['params']),
00315 Mage::helper('core')->htmlEscape($value['title']),
00316 $sizes
00317 );
00318 } catch (Exception $e) {
00319 Mage::throwException(Mage::helper('catalog')->__("File options format is not valid"));
00320 }
00321 }
00322
00323
00324
00325
00326
00327
00328
00329 public function getPrintableOptionValue($optionValue)
00330 {
00331 return strip_tags($this->getFormattedOptionValue($optionValue));
00332 }
00333
00334
00335
00336
00337
00338
00339
00340 public function getEditableOptionValue($optionValue)
00341 {
00342 try {
00343 $value = unserialize($optionValue);
00344 return sprintf('%s [%d]',
00345 Mage::helper('core')->htmlEscape($value['title']),
00346 $this->getQuoteItemOption()->getId()
00347 );
00348
00349 } catch (Exception $e) {
00350 return $optionValue;
00351 }
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361 public function parseOptionValue($optionValue, $productOptionValues)
00362 {
00363
00364 if (preg_match('/\[([0-9]+)\]/', $optionValue, $matches)) {
00365 $quoteItemOptionId = $matches[1];
00366 $option = Mage::getModel('sales/quote_item_option')->load($quoteItemOptionId);
00367 try {
00368 unserialize($option->getValue());
00369 return $option->getValue();
00370 } catch (Exception $e) {
00371 return null;
00372 }
00373 } else {
00374 return null;
00375 }
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 public function prepareOptionValueForRequest($optionValue)
00385 {
00386 try {
00387 $result = unserialize($optionValue);
00388 return $result;
00389 } catch (Exception $e) {
00390 return null;
00391 }
00392 }
00393
00394
00395
00396
00397
00398
00399 public function copyQuoteToOrder()
00400 {
00401 $quoteOption = $this->getQuoteItemOption();
00402 try {
00403 $value = unserialize($quoteOption->getValue());
00404 if (!isset($value['quote_path'])) {
00405 throw new Exception();
00406 }
00407 $quoteFileFullPath = Mage::getBaseDir() . $value['quote_path'];
00408 if (!is_file($quoteFileFullPath) || !is_readable($quoteFileFullPath)) {
00409 throw new Exception();
00410 }
00411 $orderFileFullPath = Mage::getBaseDir() . $value['order_path'];
00412 $dir = pathinfo($orderFileFullPath, PATHINFO_DIRNAME);
00413 $this->_createWriteableDir($dir);
00414 @copy($quoteFileFullPath, $orderFileFullPath);
00415 } catch (Exception $e) {
00416 return $this;
00417 }
00418 return $this;
00419 }
00420
00421
00422
00423
00424
00425
00426
00427 public function getTargetDir($relative = false)
00428 {
00429 $fullPath = Mage::getBaseDir('media') . DS . 'custom_options';
00430 return $relative ? str_replace(Mage::getBaseDir(), '', $fullPath) : $fullPath;
00431 }
00432
00433
00434
00435
00436
00437
00438
00439 public function getQuoteTargetDir($relative = false)
00440 {
00441 return $this->getTargetDir($relative) . DS . 'quote';
00442 }
00443
00444
00445
00446
00447
00448
00449
00450 public function getOrderTargetDir($relative = false)
00451 {
00452 return $this->getTargetDir($relative) . DS . 'order';
00453 }
00454
00455
00456
00457
00458 protected function _initFilesystem()
00459 {
00460 $this->_createWriteableDir($this->getTargetDir());
00461 $this->_createWriteableDir($this->getQuoteTargetDir());
00462 $this->_createWriteableDir($this->getOrderTargetDir());
00463
00464
00465 $io = new Varien_Io_File();
00466 $io->cd($this->getTargetDir());
00467 if (!$io->fileExists($this->getTargetDir() . DS . '.htaccess')) {
00468 $io->streamOpen($this->getTargetDir() . DS . '.htaccess');
00469 $io->streamLock(true);
00470 $io->streamWrite("Order deny,allow\nDeny from all");
00471 $io->streamUnlock();
00472 $io->streamClose();
00473 }
00474 }
00475
00476
00477
00478
00479
00480
00481
00482 protected function _createWriteableDir($path)
00483 {
00484 $io = new Varien_Io_File();
00485 if (!$io->isWriteable($path) && !$io->mkdir($path, 0777, true)) {
00486 Mage::throwException(Mage::helper('catalog')->__("Cannot create writeable directory '%s'", $path));
00487 }
00488 }
00489
00490
00491
00492
00493
00494
00495 protected function _getOptionDownloadUrl($route, $params)
00496 {
00497 return Mage::getUrl($route, $params);
00498 }
00499
00500
00501
00502
00503
00504
00505
00506 protected function _parseExtensionsString($extensions)
00507 {
00508 preg_match_all('/[a-z0-9]+/si', strtolower($extensions), $matches);
00509 if (isset($matches[0]) && is_array($matches[0]) && count($matches[0]) > 0) {
00510 return $matches[0];
00511 }
00512 return null;
00513 }
00514
00515
00516
00517
00518
00519
00520
00521 protected function _isImage($fileInfo)
00522 {
00523 try {
00524
00525 return strstr($fileInfo['type'], 'image/');
00526
00527
00528
00529
00530
00531 } catch (Exception $e) {
00532 return false;
00533 }
00534 }
00535
00536
00537
00538
00539
00540
00541 protected function _getUploadMaxFilesize()
00542 {
00543 return min($this->_getBytesIniValue('upload_max_filesize'), $this->_getBytesIniValue('post_max_size'));
00544 }
00545
00546
00547
00548
00549
00550
00551
00552 protected function _getBytesIniValue($ini_key)
00553 {
00554 $_bytes = @ini_get($ini_key);
00555
00556
00557 if (stristr($_bytes, 'k')) {
00558 $_bytes = intval($_bytes) * 1024;
00559
00560 } elseif (stristr($_bytes, 'm')) {
00561 $_bytes = intval($_bytes) * 1024 * 1024;
00562
00563 } elseif (stristr($_bytes, 'g')) {
00564 $_bytes = intval($_bytes) * 1024 * 1024 * 1024;
00565 }
00566 return (int)$_bytes;
00567 }
00568
00569
00570
00571
00572
00573
00574
00575 protected function _bytesToMbytes($bytes)
00576 {
00577 return round($bytes / (1024 * 1024));
00578 }
00579 }