1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29: 30: 31: 32: 33:
34: class Mage_Downloadable_Helper_Download extends Mage_Core_Helper_Abstract
35: {
36: const LINK_TYPE_URL = 'url';
37: const LINK_TYPE_FILE = 'file';
38:
39: const XML_PATH_CONTENT_DISPOSITION = 'catalog/downloadable/content_disposition';
40:
41: 42: 43: 44: 45:
46: protected $_linkType = self::LINK_TYPE_FILE;
47:
48: 49: 50: 51: 52:
53: protected $_resourceFile = null;
54:
55: 56: 57: 58: 59:
60: protected $_handle = null;
61:
62: 63: 64: 65: 66:
67: protected = array();
68:
69: 70: 71: 72: 73:
74: protected $_contentType = 'application/octet-stream';
75:
76: 77: 78: 79: 80:
81: protected $_fileName = 'download';
82:
83: 84: 85: 86: 87:
88: protected function _getHandle()
89: {
90: if (!$this->_resourceFile) {
91: Mage::throwException(Mage::helper('downloadable')->__('Please set resource file and link type.'));
92: }
93:
94: if (is_null($this->_handle)) {
95: if ($this->_linkType == self::LINK_TYPE_URL) {
96: $port = 80;
97:
98: 99: 100:
101: $urlProp = parse_url($this->_resourceFile);
102: if (!isset($urlProp['scheme']) || strtolower($urlProp['scheme'] != 'http')) {
103: Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL scheme.'));
104: }
105: if (!isset($urlProp['host'])) {
106: Mage::throwException(Mage::helper('downloadable')->__('Invalid download URL host.'));
107: }
108: $hostname = $urlProp['host'];
109:
110: if (isset($urlProp['port'])) {
111: $port = (int)$urlProp['port'];
112: }
113:
114: $path = '/';
115: if (isset($urlProp['path'])) {
116: $path = $urlProp['path'];
117: }
118: $query = '';
119: if (isset($urlProp['query'])) {
120: $query = '?' . $urlProp['query'];
121: }
122:
123: try {
124: $this->_handle = fsockopen($hostname, $port, $errno, $errstr);
125: }
126: catch (Exception $e) {
127: throw $e;
128: }
129:
130: if ($this->_handle === false) {
131: Mage::throwException(Mage::helper('downloadable')->__('Cannot connect to remote host, error: %s.', $errstr));
132: }
133:
134: $headers = 'GET ' . $path . $query . ' HTTP/1.0' . "\r\n"
135: . 'Host: ' . $hostname . "\r\n"
136: . 'User-Agent: Magento ver/' . Mage::getVersion() . "\r\n"
137: . 'Connection: close' . "\r\n"
138: . "\r\n";
139: fwrite($this->_handle, $headers);
140:
141: while (!feof($this->_handle)) {
142: $str = fgets($this->_handle, 1024);
143: if ($str == "\r\n") {
144: break;
145: }
146: $match = array();
147: if (preg_match('#^([^:]+): (.*)\s+$#', $str, $match)) {
148: $k = strtolower($match[1]);
149: if ($k == 'set-cookie') {
150: continue;
151: }
152: else {
153: $this->_urlHeaders[$k] = trim($match[2]);
154: }
155: }
156: elseif (preg_match('#^HTTP/[0-9\.]+ (\d+) (.*)\s$#', $str, $match)) {
157: $this->_urlHeaders['code'] = $match[1];
158: $this->_urlHeaders['code-string'] = trim($match[2]);
159: }
160: }
161:
162: if (!isset($this->_urlHeaders['code']) || $this->_urlHeaders['code'] != 200) {
163: Mage::throwException(Mage::helper('downloadable')->__('An error occurred while getting the requested content. Please contact the store owner.'));
164: }
165: }
166: elseif ($this->_linkType == self::LINK_TYPE_FILE) {
167: $this->_handle = new Varien_Io_File();
168: if (!is_file($this->_resourceFile)) {
169: Mage::helper('core/file_storage_database')->saveFileToFilesystem($this->_resourceFile);
170: }
171: $this->_handle->open(array('path'=>Mage::getBaseDir('var')));
172: if (!$this->_handle->fileExists($this->_resourceFile, true)) {
173: Mage::throwException(Mage::helper('downloadable')->__('The file does not exist.'));
174: }
175: $this->_handle->streamOpen($this->_resourceFile, 'r');
176: }
177: else {
178: Mage::throwException(Mage::helper('downloadable')->__('Invalid download link type.'));
179: }
180: }
181: return $this->_handle;
182: }
183:
184: 185: 186:
187: public function getFilesize()
188: {
189: $handle = $this->_getHandle();
190: if ($this->_linkType == self::LINK_TYPE_FILE) {
191: return $handle->streamStat('size');
192: }
193: elseif ($this->_linkType == self::LINK_TYPE_URL) {
194: if (isset($this->_urlHeaders['content-length'])) {
195: return $this->_urlHeaders['content-length'];
196: }
197: }
198: return null;
199: }
200:
201: public function getContentType()
202: {
203: $handle = $this->_getHandle();
204: if ($this->_linkType == self::LINK_TYPE_FILE) {
205: if (function_exists('mime_content_type') && ($contentType = mime_content_type($this->_resourceFile))) {
206: return $contentType;
207: } else {
208: return Mage::helper('downloadable/file')->getFileType($this->_resourceFile);
209: }
210: }
211: elseif ($this->_linkType == self::LINK_TYPE_URL) {
212: if (isset($this->_urlHeaders['content-type'])) {
213: $contentType = explode('; ', $this->_urlHeaders['content-type']);
214: return $contentType[0];
215: }
216: }
217: return $this->_contentType;
218: }
219:
220: public function getFilename()
221: {
222: $handle = $this->_getHandle();
223: if ($this->_linkType == self::LINK_TYPE_FILE) {
224: return pathinfo($this->_resourceFile, PATHINFO_BASENAME);
225: }
226: elseif ($this->_linkType == self::LINK_TYPE_URL) {
227: if (isset($this->_urlHeaders['content-disposition'])) {
228: $contentDisposition = explode('; ', $this->_urlHeaders['content-disposition']);
229: if (!empty($contentDisposition[1]) && strpos($contentDisposition[1], 'filename=') !== false) {
230: return substr($contentDisposition[1], 9);
231: }
232: }
233: if ($fileName = @pathinfo($this->_resourceFile, PATHINFO_BASENAME)) {
234: return $fileName;
235: }
236: }
237: return $this->_fileName;
238: }
239:
240: 241: 242: 243: 244: 245: 246:
247: public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE)
248: {
249: if (self::LINK_TYPE_FILE == $linkType) {
250:
251:
252: $helper = Mage::helper('core');
253: $helper->checkLfiProtection($resourceFile);
254: }
255:
256: $this->_resourceFile = $resourceFile;
257: $this->_linkType = $linkType;
258:
259: return $this;
260: }
261:
262: 263: 264: 265: 266:
267: public function getHttpRequest()
268: {
269: return Mage::app()->getFrontController()->getRequest();
270: }
271:
272: 273: 274: 275: 276:
277: public function getHttpResponse()
278: {
279: return Mage::app()->getFrontController()->getResponse();
280: }
281:
282: public function output()
283: {
284: $handle = $this->_getHandle();
285: if ($this->_linkType == self::LINK_TYPE_FILE) {
286: while ($buffer = $handle->streamRead()) {
287: print $buffer;
288: }
289: }
290: elseif ($this->_linkType == self::LINK_TYPE_URL) {
291: while (!feof($handle)) {
292: print fgets($handle, 1024);
293: }
294: }
295: }
296:
297: 298: 299: 300: 301: 302:
303: public function getContentDisposition($store = null)
304: {
305: return Mage::getStoreConfig(self::XML_PATH_CONTENT_DISPOSITION, $store);
306: }
307: }
308: