PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/core/Mage/Catalog/Model/Product/Option/Type/File.php

https://github.com/FiveDigital/magento2
PHP | 828 lines | 498 code | 78 blank | 252 comment | 90 complexity | 9f0ae41d019cf0e00efb62a999c1d461 MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Catalog
  23. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. /**
  27. * Catalog product option file type
  28. *
  29. * @category Mage
  30. * @package Mage_Catalog
  31. * @author Magento Core Team <core@magentocommerce.com>
  32. */
  33. class Mage_Catalog_Model_Product_Option_Type_File extends Mage_Catalog_Model_Product_Option_Type_Default
  34. {
  35. /**
  36. * Url for custom option download controller
  37. * @var string
  38. */
  39. protected $_customOptionDownloadUrl = 'sales/download/downloadCustomOption';
  40. /**
  41. * @var mixed
  42. */
  43. protected $_formattedOptionValue = null;
  44. public function isCustomizedView()
  45. {
  46. return true;
  47. }
  48. /**
  49. * Return option html
  50. *
  51. * @param array $optionInfo
  52. * @return string
  53. */
  54. public function getCustomizedView($optionInfo)
  55. {
  56. try {
  57. if (isset($optionInfo['option_value'])) {
  58. return $this->_getOptionHtml($optionInfo['option_value']);
  59. } elseif (isset($optionInfo['value'])) {
  60. return $optionInfo['value'];
  61. }
  62. } catch (Exception $e) {
  63. return $optionInfo['value'];
  64. }
  65. }
  66. /**
  67. * Returns additional params for processing options
  68. *
  69. * @return Varien_Object
  70. */
  71. protected function _getProcessingParams()
  72. {
  73. $buyRequest = $this->getRequest();
  74. $params = $buyRequest->getData('_processing_params');
  75. /*
  76. * Notice check for params to be Varien_Object - by using object we protect from
  77. * params being forged and contain data from user frontend input
  78. */
  79. if ($params instanceof Varien_Object) {
  80. return $params;
  81. }
  82. return new Varien_Object();
  83. }
  84. /**
  85. * Returns file info array if we need to get file from already existing file.
  86. * Or returns null, if we need to get file from uploaded array.
  87. *
  88. * @return null|array
  89. */
  90. protected function _getCurrentConfigFileInfo()
  91. {
  92. $option = $this->getOption();
  93. $optionId = $option->getId();
  94. $processingParams = $this->_getProcessingParams();
  95. $buyRequest = $this->getRequest();
  96. // Check maybe restore file from config requested
  97. $optionActionKey = 'options_' . $optionId . '_file_action';
  98. if ($buyRequest->getData($optionActionKey) == 'save_old') {
  99. $fileInfo = array();
  100. $currentConfig = $processingParams->getCurrentConfig();
  101. if ($currentConfig) {
  102. $fileInfo = $currentConfig->getData('options/' . $optionId);
  103. }
  104. return $fileInfo;
  105. }
  106. return null;
  107. }
  108. /**
  109. * Validate user input for option
  110. *
  111. * @throws Mage_Core_Exception
  112. * @param array $values All product option values, i.e. array (option_id => mixed, option_id => mixed...)
  113. * @return Mage_Catalog_Model_Product_Option_Type_File
  114. */
  115. public function validateUserValue($values)
  116. {
  117. Mage::getSingleton('Mage_Checkout_Model_Session')->setUseNotice(false);
  118. $this->setIsValid(true);
  119. $option = $this->getOption();
  120. /*
  121. * Check whether we receive uploaded file or restore file by: reorder/edit configuration or
  122. * previous configuration with no newly uploaded file
  123. */
  124. $fileInfo = null;
  125. if (isset($values[$option->getId()]) && is_array($values[$option->getId()])) {
  126. // Legacy style, file info comes in array with option id index
  127. $fileInfo = $values[$option->getId()];
  128. } else {
  129. /*
  130. * New recommended style - file info comes in request processing parameters and we
  131. * sure that this file info originates from Magento, not from manually formed POST request
  132. */
  133. $fileInfo = $this->_getCurrentConfigFileInfo();
  134. }
  135. if ($fileInfo !== null) {
  136. if (is_array($fileInfo) && $this->_validateFile($fileInfo)) {
  137. $value = $fileInfo;
  138. } else {
  139. $value = null;
  140. }
  141. $this->setUserValue($value);
  142. return $this;
  143. }
  144. // Process new uploaded file
  145. try {
  146. $this->_validateUploadedFile();
  147. } catch (Exception $e) {
  148. if ($this->getSkipCheckRequiredOption()) {
  149. $this->setUserValue(null);
  150. return $this;
  151. } else {
  152. Mage::throwException($e->getMessage());
  153. }
  154. }
  155. return $this;
  156. }
  157. /**
  158. * Validate uploaded file
  159. *
  160. * @throws Mage_Core_Exception
  161. * @return Mage_Catalog_Model_Product_Option_Type_File
  162. */
  163. protected function _validateUploadedFile()
  164. {
  165. $option = $this->getOption();
  166. $processingParams = $this->_getProcessingParams();
  167. /**
  168. * Upload init
  169. */
  170. $upload = new Zend_File_Transfer_Adapter_Http();
  171. $file = $processingParams->getFilesPrefix() . 'options_' . $option->getId() . '_file';
  172. try {
  173. $runValidation = $option->getIsRequire() || $upload->isUploaded($file);
  174. if (!$runValidation) {
  175. $this->setUserValue(null);
  176. return $this;
  177. }
  178. $fileInfo = $upload->getFileInfo($file);
  179. $fileInfo = $fileInfo[$file];
  180. $fileInfo['title'] = $fileInfo['name'];
  181. } catch (Exception $e) {
  182. // when file exceeds the upload_max_filesize, $_FILES is empty
  183. if (isset($_SERVER['CONTENT_LENGTH']) && $_SERVER['CONTENT_LENGTH'] > $this->_getUploadMaxFilesize()) {
  184. $this->setIsValid(false);
  185. $value = $this->_bytesToMbytes($this->_getUploadMaxFilesize());
  186. Mage::throwException(
  187. Mage::helper('Mage_Catalog_Helper_Data')->__("The file you uploaded is larger than %s Megabytes allowed by server", $value)
  188. );
  189. } else {
  190. switch($this->getProcessMode())
  191. {
  192. case Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_FULL:
  193. Mage::throwException(
  194. Mage::helper('Mage_Catalog_Helper_Data')->__('Please specify the product\'s required option(s).')
  195. );
  196. break;
  197. default:
  198. $this->setUserValue(null);
  199. break;
  200. }
  201. return $this;
  202. }
  203. }
  204. /**
  205. * Option Validations
  206. */
  207. // Image dimensions
  208. $_dimentions = array();
  209. if ($option->getImageSizeX() > 0) {
  210. $_dimentions['maxwidth'] = $option->getImageSizeX();
  211. }
  212. if ($option->getImageSizeY() > 0) {
  213. $_dimentions['maxheight'] = $option->getImageSizeY();
  214. }
  215. if (count($_dimentions) > 0) {
  216. $upload->addValidator('ImageSize', false, $_dimentions);
  217. }
  218. // File extension
  219. $_allowed = $this->_parseExtensionsString($option->getFileExtension());
  220. if ($_allowed !== null) {
  221. $upload->addValidator('Extension', false, $_allowed);
  222. } else {
  223. $_forbidden = $this->_parseExtensionsString($this->getConfigData('forbidden_extensions'));
  224. if ($_forbidden !== null) {
  225. $upload->addValidator('ExcludeExtension', false, $_forbidden);
  226. }
  227. }
  228. // Maximum filesize
  229. $upload->addValidator('FilesSize', false, array('max' => $this->_getUploadMaxFilesize()));
  230. /**
  231. * Upload process
  232. */
  233. $this->_initFilesystem();
  234. if ($upload->isUploaded($file) && $upload->isValid($file)) {
  235. $extension = pathinfo(strtolower($fileInfo['name']), PATHINFO_EXTENSION);
  236. $fileName = Mage_Core_Model_File_Uploader::getCorrectFileName($fileInfo['name']);
  237. $dispersion = Mage_Core_Model_File_Uploader::getDispretionPath($fileName);
  238. $filePath = $dispersion;
  239. $fileHash = md5(file_get_contents($fileInfo['tmp_name']));
  240. $filePath .= DS . $fileHash . '.' . $extension;
  241. $fileFullPath = $this->getQuoteTargetDir() . $filePath;
  242. $upload->addFilter('Rename', array(
  243. 'target' => $fileFullPath,
  244. 'overwrite' => true
  245. ));
  246. $this->getProduct()->getTypeInstance()->addFileQueue(array(
  247. 'operation' => 'receive_uploaded_file',
  248. 'src_name' => $file,
  249. 'dst_name' => $fileFullPath,
  250. 'uploader' => $upload,
  251. 'option' => $this,
  252. ));
  253. $_width = 0;
  254. $_height = 0;
  255. if (is_readable($fileInfo['tmp_name'])) {
  256. $_imageSize = getimagesize($fileInfo['tmp_name']);
  257. if ($_imageSize) {
  258. $_width = $_imageSize[0];
  259. $_height = $_imageSize[1];
  260. }
  261. }
  262. $this->setUserValue(array(
  263. 'type' => $fileInfo['type'],
  264. 'title' => $fileInfo['name'],
  265. 'quote_path' => $this->getQuoteTargetDir(true) . $filePath,
  266. 'order_path' => $this->getOrderTargetDir(true) . $filePath,
  267. 'fullpath' => $fileFullPath,
  268. 'size' => $fileInfo['size'],
  269. 'width' => $_width,
  270. 'height' => $_height,
  271. 'secret_key' => substr($fileHash, 0, 20),
  272. ));
  273. } elseif ($upload->getErrors()) {
  274. $errors = $this->_getValidatorErrors($upload->getErrors(), $fileInfo);
  275. if (count($errors) > 0) {
  276. $this->setIsValid(false);
  277. Mage::throwException( implode("\n", $errors) );
  278. }
  279. } else {
  280. $this->setIsValid(false);
  281. Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__('Please specify the product required option(s)'));
  282. }
  283. return $this;
  284. }
  285. /**
  286. * Validate file
  287. *
  288. * @throws Mage_Core_Exception
  289. * @param array $optionValue
  290. * @return Mage_Catalog_Model_Product_Option_Type_Default
  291. */
  292. protected function _validateFile($optionValue)
  293. {
  294. $option = $this->getOption();
  295. /**
  296. * @see Mage_Catalog_Model_Product_Option_Type_File::_validateUploadFile()
  297. * There setUserValue() sets correct fileFullPath only for
  298. * quote_path. So we must form both full paths manually and
  299. * check them.
  300. */
  301. $checkPaths = array();
  302. if (isset($optionValue['quote_path'])) {
  303. $checkPaths[] = Mage::getBaseDir() . $optionValue['quote_path'];
  304. }
  305. if (isset($optionValue['order_path']) && !$this->getUseQuotePath()) {
  306. $checkPaths[] = Mage::getBaseDir() . $optionValue['order_path'];
  307. }
  308. $fileFullPath = null;
  309. foreach ($checkPaths as $path) {
  310. if (!is_file($path)) {
  311. if (!Mage::helper('Mage_Core_Helper_File_Storage_Database')->saveFileToFilesystem($fileFullPath)) {
  312. continue;
  313. }
  314. }
  315. $fileFullPath = $path;
  316. break;
  317. }
  318. if ($fileFullPath === null) {
  319. return false;
  320. }
  321. $validatorChain = new Zend_Validate();
  322. $_dimentions = array();
  323. if ($option->getImageSizeX() > 0) {
  324. $_dimentions['maxwidth'] = $option->getImageSizeX();
  325. }
  326. if ($option->getImageSizeY() > 0) {
  327. $_dimentions['maxheight'] = $option->getImageSizeY();
  328. }
  329. if (count($_dimentions) > 0 && !$this->_isImage($fileFullPath)) {
  330. return false;
  331. }
  332. if (count($_dimentions) > 0) {
  333. $validatorChain->addValidator(
  334. new Zend_Validate_File_ImageSize($_dimentions)
  335. );
  336. }
  337. // File extension
  338. $_allowed = $this->_parseExtensionsString($option->getFileExtension());
  339. if ($_allowed !== null) {
  340. $validatorChain->addValidator(new Zend_Validate_File_Extension($_allowed));
  341. } else {
  342. $_forbidden = $this->_parseExtensionsString($this->getConfigData('forbidden_extensions'));
  343. if ($_forbidden !== null) {
  344. $validatorChain->addValidator(new Zend_Validate_File_ExcludeExtension($_forbidden));
  345. }
  346. }
  347. // Maximum filesize
  348. $validatorChain->addValidator(
  349. new Zend_Validate_File_FilesSize(array('max' => $this->_getUploadMaxFilesize()))
  350. );
  351. if ($validatorChain->isValid($fileFullPath)) {
  352. $ok = is_readable($fileFullPath)
  353. && isset($optionValue['secret_key'])
  354. && substr(md5(file_get_contents($fileFullPath)), 0, 20) == $optionValue['secret_key'];
  355. return $ok;
  356. } elseif ($validatorChain->getErrors()) {
  357. $errors = $this->_getValidatorErrors($validatorChain->getErrors(), $optionValue);
  358. if (count($errors) > 0) {
  359. $this->setIsValid(false);
  360. Mage::throwException( implode("\n", $errors) );
  361. }
  362. } else {
  363. $this->setIsValid(false);
  364. Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__('Please specify the product required option(s)'));
  365. }
  366. }
  367. /**
  368. * Get Error messages for validator Errors
  369. * @param array $errors Array of validation failure message codes @see Zend_Validate::getErrors()
  370. * @param array $fileInfo File info
  371. * @return array Array of error messages
  372. */
  373. protected function _getValidatorErrors($errors, $fileInfo)
  374. {
  375. $option = $this->getOption();
  376. $result = array();
  377. foreach ($errors as $errorCode) {
  378. if ($errorCode == Zend_Validate_File_ExcludeExtension::FALSE_EXTENSION) {
  379. $result[] = Mage::helper('Mage_Catalog_Helper_Data')->__("The file '%s' for '%s' has an invalid extension", $fileInfo['title'], $option->getTitle());
  380. } elseif ($errorCode == Zend_Validate_File_Extension::FALSE_EXTENSION) {
  381. $result[] = Mage::helper('Mage_Catalog_Helper_Data')->__("The file '%s' for '%s' has an invalid extension", $fileInfo['title'], $option->getTitle());
  382. } elseif ($errorCode == Zend_Validate_File_ImageSize::WIDTH_TOO_BIG
  383. || $errorCode == Zend_Validate_File_ImageSize::HEIGHT_TOO_BIG)
  384. {
  385. $result[] = Mage::helper('Mage_Catalog_Helper_Data')->__("Maximum allowed image size for '%s' is %sx%s px.", $option->getTitle(), $option->getImageSizeX(), $option->getImageSizeY());
  386. } elseif ($errorCode == Zend_Validate_File_FilesSize::TOO_BIG) {
  387. $result[] = Mage::helper('Mage_Catalog_Helper_Data')->__("The file '%s' you uploaded is larger than %s Megabytes allowed by server", $fileInfo['title'], $this->_bytesToMbytes($this->_getUploadMaxFilesize()));
  388. }
  389. }
  390. return $result;
  391. }
  392. /**
  393. * Prepare option value for cart
  394. *
  395. * @return mixed Prepared option value
  396. */
  397. public function prepareForCart()
  398. {
  399. $option = $this->getOption();
  400. $optionId = $option->getId();
  401. $buyRequest = $this->getRequest();
  402. // Prepare value and fill buyRequest with option
  403. $requestOptions = $buyRequest->getOptions();
  404. if ($this->getIsValid() && $this->getUserValue() !== null) {
  405. $value = $this->getUserValue();
  406. // Save option in request, because we have no $_FILES['options']
  407. $requestOptions[$this->getOption()->getId()] = $value;
  408. $result = serialize($value);
  409. } else {
  410. /*
  411. * Clear option info from request, so it won't be stored in our db upon
  412. * unsuccessful validation. Otherwise some bad file data can happen in buyRequest
  413. * and be used later in reorders and reconfigurations.
  414. */
  415. if (is_array($requestOptions)) {
  416. unset($requestOptions[$this->getOption()->getId()]);
  417. }
  418. $result = null;
  419. }
  420. $buyRequest->setOptions($requestOptions);
  421. // Clear action key from buy request - we won't need it anymore
  422. $optionActionKey = 'options_' . $optionId . '_file_action';
  423. $buyRequest->unsetData($optionActionKey);
  424. return $result;
  425. }
  426. /**
  427. * Return formatted option value for quote option
  428. *
  429. * @param string $optionValue Prepared for cart option value
  430. * @return string
  431. */
  432. public function getFormattedOptionValue($optionValue)
  433. {
  434. if ($this->_formattedOptionValue === null) {
  435. try {
  436. $value = unserialize($optionValue);
  437. $customOptionUrlParams = $this->getCustomOptionUrlParams()
  438. ? $this->getCustomOptionUrlParams()
  439. : array(
  440. 'id' => $this->getConfigurationItemOption()->getId(),
  441. 'key' => $value['secret_key']
  442. );
  443. $value['url'] = array('route' => $this->_customOptionDownloadUrl, 'params' => $customOptionUrlParams);
  444. $this->_formattedOptionValue = $this->_getOptionHtml($value);
  445. $this->getConfigurationItemOption()->setValue(serialize($value));
  446. return $this->_formattedOptionValue;
  447. } catch (Exception $e) {
  448. return $optionValue;
  449. }
  450. }
  451. return $this->_formattedOptionValue;
  452. }
  453. /**
  454. * Format File option html
  455. *
  456. * @param string|array $optionValue Serialized string of option data or its data array
  457. * @return string
  458. */
  459. protected function _getOptionHtml($optionValue)
  460. {
  461. $value = $this->_unserializeValue($optionValue);
  462. try {
  463. if (isset($value) && isset($value['width']) && isset($value['height'])
  464. && $value['width'] > 0 && $value['height'] > 0
  465. ) {
  466. $sizes = $value['width'] . ' x ' . $value['height'] . ' ' . Mage::helper('Mage_Catalog_Helper_Data')->__('px.');
  467. } else {
  468. $sizes = '';
  469. }
  470. $urlRoute = !empty($value['url']['route']) ? $value['url']['route'] : '';
  471. $urlParams = !empty($value['url']['params']) ? $value['url']['params'] : '';
  472. $title = !empty($value['title']) ? $value['title'] : '';
  473. return sprintf('<a href="%s" target="_blank">%s</a> %s',
  474. $this->_getOptionDownloadUrl($urlRoute, $urlParams),
  475. Mage::helper('Mage_Core_Helper_Data')->escapeHtml($title),
  476. $sizes
  477. );
  478. } catch (Exception $e) {
  479. Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__("File options format is not valid."));
  480. }
  481. }
  482. /**
  483. * Create a value from a storable representation
  484. *
  485. * @param mixed $value
  486. * @return array
  487. */
  488. protected function _unserializeValue($value)
  489. {
  490. if (is_array($value)) {
  491. return $value;
  492. } elseif (is_string($value) && !empty($value)) {
  493. return unserialize($value);
  494. } else {
  495. return array();
  496. }
  497. }
  498. /**
  499. * Return printable option value
  500. *
  501. * @param string $optionValue Prepared for cart option value
  502. * @return string
  503. */
  504. public function getPrintableOptionValue($optionValue)
  505. {
  506. return strip_tags($this->getFormattedOptionValue($optionValue));
  507. }
  508. /**
  509. * Return formatted option value ready to edit, ready to parse
  510. *
  511. * @param string $optionValue Prepared for cart option value
  512. * @return string
  513. */
  514. public function getEditableOptionValue($optionValue)
  515. {
  516. try {
  517. $value = unserialize($optionValue);
  518. return sprintf('%s [%d]',
  519. Mage::helper('Mage_Core_Helper_Data')->escapeHtml($value['title']),
  520. $this->getConfigurationItemOption()->getId()
  521. );
  522. } catch (Exception $e) {
  523. return $optionValue;
  524. }
  525. }
  526. /**
  527. * Parse user input value and return cart prepared value
  528. *
  529. * @param string $optionValue
  530. * @param array $productOptionValues Values for product option
  531. * @return string|null
  532. */
  533. public function parseOptionValue($optionValue, $productOptionValues)
  534. {
  535. // search quote item option Id in option value
  536. if (preg_match('/\[([0-9]+)\]/', $optionValue, $matches)) {
  537. $confItemOptionId = $matches[1];
  538. $option = Mage::getModel('Mage_Sales_Model_Quote_Item_Option')->load($confItemOptionId);
  539. try {
  540. unserialize($option->getValue());
  541. return $option->getValue();
  542. } catch (Exception $e) {
  543. return null;
  544. }
  545. } else {
  546. return null;
  547. }
  548. }
  549. /**
  550. * Prepare option value for info buy request
  551. *
  552. * @param string $optionValue
  553. * @return mixed
  554. */
  555. public function prepareOptionValueForRequest($optionValue)
  556. {
  557. try {
  558. $result = unserialize($optionValue);
  559. return $result;
  560. } catch (Exception $e) {
  561. return null;
  562. }
  563. }
  564. /**
  565. * Quote item to order item copy process
  566. *
  567. * @return Mage_Catalog_Model_Product_Option_Type_File
  568. */
  569. public function copyQuoteToOrder()
  570. {
  571. $quoteOption = $this->getConfigurationItemOption();
  572. try {
  573. $value = unserialize($quoteOption->getValue());
  574. if (!isset($value['quote_path'])) {
  575. throw new Exception();
  576. }
  577. $quoteFileFullPath = Mage::getBaseDir() . $value['quote_path'];
  578. if (!is_file($quoteFileFullPath) || !is_readable($quoteFileFullPath)) {
  579. throw new Exception();
  580. }
  581. $orderFileFullPath = Mage::getBaseDir() . $value['order_path'];
  582. $dir = pathinfo($orderFileFullPath, PATHINFO_DIRNAME);
  583. $this->_createWriteableDir($dir);
  584. Mage::helper('Mage_Core_Helper_File_Storage_Database')->copyFile($quoteFileFullPath, $orderFileFullPath);
  585. @copy($quoteFileFullPath, $orderFileFullPath);
  586. } catch (Exception $e) {
  587. return $this;
  588. }
  589. return $this;
  590. }
  591. /**
  592. * Main Destination directory
  593. *
  594. * @param boolean $relative If true - returns relative path to the webroot
  595. * @return string
  596. */
  597. public function getTargetDir($relative = false)
  598. {
  599. $fullPath = Mage::getBaseDir('media') . DS . 'custom_options';
  600. return $relative ? str_replace(Mage::getBaseDir(), '', $fullPath) : $fullPath;
  601. }
  602. /**
  603. * Quote items destination directory
  604. *
  605. * @param boolean $relative If true - returns relative path to the webroot
  606. * @return string
  607. */
  608. public function getQuoteTargetDir($relative = false)
  609. {
  610. return $this->getTargetDir($relative) . DS . 'quote';
  611. }
  612. /**
  613. * Order items destination directory
  614. *
  615. * @param boolean $relative If true - returns relative path to the webroot
  616. * @return string
  617. */
  618. public function getOrderTargetDir($relative = false)
  619. {
  620. return $this->getTargetDir($relative) . DS . 'order';
  621. }
  622. /**
  623. * Set url to custom option download controller
  624. *
  625. * @param string $url
  626. * @return Mage_Catalog_Model_Product_Option_Type_File
  627. */
  628. public function setCustomOptionDownloadUrl($url)
  629. {
  630. $this->_customOptionDownloadUrl = $url;
  631. return $this;
  632. }
  633. /**
  634. * Directory structure initializing
  635. */
  636. protected function _initFilesystem()
  637. {
  638. $this->_createWriteableDir($this->getTargetDir());
  639. $this->_createWriteableDir($this->getQuoteTargetDir());
  640. $this->_createWriteableDir($this->getOrderTargetDir());
  641. // Directory listing and hotlink secure
  642. $io = new Varien_Io_File();
  643. $io->cd($this->getTargetDir());
  644. if (!$io->fileExists($this->getTargetDir() . DS . '.htaccess')) {
  645. $io->streamOpen($this->getTargetDir() . DS . '.htaccess');
  646. $io->streamLock(true);
  647. $io->streamWrite("Order deny,allow\nDeny from all");
  648. $io->streamUnlock();
  649. $io->streamClose();
  650. }
  651. }
  652. /**
  653. * Create Writeable directory if it doesn't exist
  654. *
  655. * @param string Absolute directory path
  656. * @return void
  657. */
  658. protected function _createWriteableDir($path)
  659. {
  660. $io = new Varien_Io_File();
  661. if (!$io->isWriteable($path) && !$io->mkdir($path, 0777, true)) {
  662. Mage::throwException(Mage::helper('Mage_Catalog_Helper_Data')->__("Cannot create writeable directory '%s'.", $path));
  663. }
  664. }
  665. /**
  666. * Return URL for option file download
  667. *
  668. * @return string
  669. */
  670. protected function _getOptionDownloadUrl($route, $params)
  671. {
  672. return Mage::getUrl($route, $params);
  673. }
  674. /**
  675. * Parse file extensions string with various separators
  676. *
  677. * @param string $extensions String to parse
  678. * @return array|null
  679. */
  680. protected function _parseExtensionsString($extensions)
  681. {
  682. preg_match_all('/[a-z0-9]+/si', strtolower($extensions), $matches);
  683. if (isset($matches[0]) && is_array($matches[0]) && count($matches[0]) > 0) {
  684. return $matches[0];
  685. }
  686. return null;
  687. }
  688. /**
  689. * Simple check if file is image
  690. *
  691. * @param array|string $fileInfo - either file data from Zend_File_Transfer or file path
  692. * @return boolean
  693. */
  694. protected function _isImage($fileInfo)
  695. {
  696. // Maybe array with file info came in
  697. if (is_array($fileInfo)) {
  698. return strstr($fileInfo['type'], 'image/');
  699. }
  700. // File path came in - check the physical file
  701. if (!is_readable($fileInfo)) {
  702. return false;
  703. }
  704. $imageInfo = getimagesize($fileInfo);
  705. if (!$imageInfo) {
  706. return false;
  707. }
  708. return true;
  709. }
  710. /**
  711. * Max upload filesize in bytes
  712. *
  713. * @return int
  714. */
  715. protected function _getUploadMaxFilesize()
  716. {
  717. return min($this->_getBytesIniValue('upload_max_filesize'), $this->_getBytesIniValue('post_max_size'));
  718. }
  719. /**
  720. * Return php.ini setting value in bytes
  721. *
  722. * @param string $ini_key php.ini Var name
  723. * @return int Setting value
  724. */
  725. protected function _getBytesIniValue($ini_key)
  726. {
  727. $_bytes = @ini_get($ini_key);
  728. // kilobytes
  729. if (stristr($_bytes, 'k')) {
  730. $_bytes = intval($_bytes) * 1024;
  731. // megabytes
  732. } elseif (stristr($_bytes, 'm')) {
  733. $_bytes = intval($_bytes) * 1024 * 1024;
  734. // gigabytes
  735. } elseif (stristr($_bytes, 'g')) {
  736. $_bytes = intval($_bytes) * 1024 * 1024 * 1024;
  737. }
  738. return (int)$_bytes;
  739. }
  740. /**
  741. * Simple converrt bytes to Megabytes
  742. *
  743. * @param int $bytes
  744. * @return int
  745. */
  746. protected function _bytesToMbytes($bytes)
  747. {
  748. return round($bytes / (1024 * 1024));
  749. }
  750. }