OXID eShop CE  4.10.5
 All Classes Namespaces Files Functions Variables Pages
oxfile.php
Go to the documentation of this file.
1 <?php
2 
7 class oxFile extends oxBase
8 {
9 
13  const NO_USER = 2;
14 
20  protected $_sCoreTable = 'oxfiles';
21 
27  protected $_sClassName = 'oxfile';
28 
34  protected $_sRelativeFilePath = null;
35 
41  protected $_blIsPaid = null;
42 
49  protected $_sDownloadLink = null;
50 
56  protected $_blHasValidDownloads = null;
57 
63  protected $_sManualUploadDir = "uploads";
64 
69  public function __construct()
70  {
72  $this->init();
73  }
74 
83  public function processFile($sFileIndex)
84  {
85  $aFileInfo = $this->getConfig()->getUploadedFile($sFileIndex);
86 
87  $this->_checkArticleFile($aFileInfo);
88 
89  $sFileHash = $this->_getFileHash($aFileInfo['tmp_name']);
90  $this->oxfiles__oxstorehash = new oxField($sFileHash, oxField::T_RAW);
91  $sUploadTo = $this->getStoreLocation();
92 
93  if (!$this->_uploadFile($aFileInfo['tmp_name'], $sUploadTo)) {
94  throw new oxException('EXCEPTION_COULDNOTWRITETOFILE');
95  }
96 
97  }
98 
106  protected function _checkArticleFile($aFileInfo)
107  {
108  //checking params
109  if (!isset($aFileInfo['name']) || !isset($aFileInfo['tmp_name'])) {
110  throw new oxException('EXCEPTION_NOFILE');
111  }
112 
113  // error uploading file ?
114  if (isset($aFileInfo['error']) && $aFileInfo['error']) {
115  throw new oxException('EXCEPTION_FILEUPLOADERROR_' . ((int) $aFileInfo['error']));
116  }
117 
118  }
119 
125  protected function _getBaseDownloadDirPath()
126  {
127  $sConfigValue = oxRegistry::getConfig()->getConfigParam('sDownloadsDir');
128 
129  //Unix full path is set
130  if ($sConfigValue && $sConfigValue[0] == DIRECTORY_SEPARATOR) {
131  return $sConfigValue;
132  }
133 
134  //relative path is set
135  if ($sConfigValue) {
136  $sPath = getShopBasePath() . DIRECTORY_SEPARATOR . $sConfigValue;
137 
138  return $sPath;
139  }
140 
141  //no path is set
142  $sPath = getShopBasePath() . "/out/downloads/";
143 
144  return $sPath;
145  }
146 
154  public function getStoreLocation()
155  {
156  $sPath = $this->_getBaseDownloadDirPath();
157  $sPath .= DIRECTORY_SEPARATOR . $this->_getFileLocation();
158 
159  return $sPath;
160  }
161 
168  public function isUnderDownloadFolder()
169  {
170  $storageLocation = realpath($this->getStoreLocation());
171 
172  if ($storageLocation === false) {
173  return false;
174  }
175 
176  $downloadFolder = realpath($this->_getBaseDownloadDirPath());
177 
178  return strpos($storageLocation, $downloadFolder) !== false;
179  }
180 
186  protected function _getFileLocation()
187  {
188  $this->_sRelativeFilePath = '';
189  $sFileHash = $this->oxfiles__oxstorehash->value;
190  $sFileName = $this->oxfiles__oxfilename->value;
191 
192  //security check for demo shops
193  if ($this->getConfig()->isDemoShop()) {
194  $sFileName = basename($sFileName);
195  }
196 
197  if ($this->isUploaded()) {
198  $this->_sRelativeFilePath = $this->_getHashedFileDir($sFileHash);
199  $this->_sRelativeFilePath .= DIRECTORY_SEPARATOR . $sFileHash;
200  } else {
201  $this->_sRelativeFilePath = DIRECTORY_SEPARATOR . $this->_sManualUploadDir . DIRECTORY_SEPARATOR . $sFileName;
202  }
203 
205  }
206 
216  protected function _getHashedFileDir($sFileHash)
217  {
218  $sDir = substr($sFileHash, 0, 2);
219  $sAbsDir = $this->_getBaseDownloadDirPath() . DIRECTORY_SEPARATOR . $sDir;
220 
221  if (!is_dir($sAbsDir)) {
222  mkdir($sAbsDir, 0755);
223  }
224 
225  return $sDir;
226  }
227 
236  protected function _getFileHash($sFileName)
237  {
238  return md5_file($sFileName);
239  }
240 
250  protected function _uploadFile($sSource, $sTarget)
251  {
252  $blDone = move_uploaded_file($sSource, $sTarget);
253 
254  if ($blDone) {
255  $blDone = @chmod($sTarget, 0644);
256  }
257 
258  return $blDone;
259  }
260 
269  public function isUploaded()
270  {
271  $blHashed = false;
272  if ($this->oxfiles__oxstorehash->value) {
273  $blHashed = true;
274  }
275 
276  return $blHashed;
277  }
278 
286  public function delete($sOxId = null)
287  {
288  $sOxId = $sOxId ? $sOxId : $this->getId();
289 
290  $this->load($sOxId);
291  // if record cannot be delete, abort deletion
292  if ($blDeleted = parent::delete($sOxId)) {
293  $this->_deleteFile();
294  }
295 
296  return $blDeleted;
297  }
298 
305  protected function _deleteFile()
306  {
307  if (!$this->isUploaded()) {
308  return false;
309  }
310  $sHash = $this->oxfiles__oxstorehash->value;
311  $oDb = oxDb::getDb();
312  $iCount = $oDb->getOne(
313  'SELECT COUNT(*) FROM `oxfiles` WHERE `OXSTOREHASH` = ' . $oDb->quote($sHash), false, false
314  );
315  if (!$iCount) {
316  $sPath = $this->getStoreLocation();
317  unlink($sPath);
318  }
319  }
320 
327  protected function _getFilenameForUrl()
328  {
329  return rawurlencode($this->oxfiles__oxfilename->value);
330  }
331 
335  public function download()
336  {
337  $oUtils = oxRegistry::getUtils();
338  $sFileName = $this->_getFilenameForUrl();
339  $sFileLocations = $this->getStoreLocation();
340 
341  if (!$this->exist() || !$this->isUnderDownloadFolder()) {
342  throw new oxException('EXCEPTION_NOFILE');
343  }
344 
345  $oUtils->setHeader("Pragma: public");
346  $oUtils->setHeader("Expires: 0");
347  $oUtils->setHeader("Cache-Control: must-revalidate, post-check=0, pre-check=0, private");
348  $oUtils->setHeader('Content-Disposition: attachment;filename=' . $sFileName);
349  $oUtils->setHeader("Content-Type: application/octet-stream");
350  if ($iFileSize = $this->getSize()) {
351  $oUtils->setHeader("Content-Length: " . $iFileSize);
352  }
353  readfile($sFileLocations);
354  $oUtils->showMessageAndExit(null);
355  }
356 
362  public function exist()
363  {
364  return file_exists($this->getStoreLocation());
365  }
366 
372  public function hasValidDownloads()
373  {
374  if ($this->_blHasValidDownloads == null) {
375  $this->_blHasValidDownloads = false;
376  $sNow = date('Y-m-d H:i:s', oxRegistry::get("oxUtilsDate")->getTime());
377  $sFileId = $this->getId();
378 
379  $oDb = oxDb::getDb();
380 
381  $sSql = "SELECT
382  `oxorderfiles`.`oxid`
383  FROM `oxorderfiles`
384  LEFT JOIN `oxorderarticles` ON `oxorderarticles`.`oxid` = `oxorderfiles`.`oxorderarticleid`
385  LEFT JOIN `oxorder` ON `oxorder`.`oxid` = `oxorderfiles`.`oxorderid`
386  WHERE `oxorderfiles`.`oxfileid` = " . $oDb->quote($sFileId) . "
387  AND ( ! `oxorderfiles`.`oxmaxdownloadcount` OR `oxorderfiles`.`oxmaxdownloadcount` > `oxorderfiles`.`oxdownloadcount`)
388  AND ( `oxorderfiles`.`oxvaliduntil` = '0000-00-00 00:00:00' OR `oxorderfiles`.`oxvaliduntil` > '{$sNow}' )
389  AND `oxorder`.`oxstorno` = 0
390  AND `oxorderarticles`.`oxstorno` = 0";
391 
392  if ($oDb->getOne($sSql)) {
393  $this->_blHasValidDownloads = true;
394  }
395  }
396 
398  }
399 
405  public function getMaxDownloadsCount()
406  {
407  $iMaxCount = $this->oxfiles__oxmaxdownloads->value;
408  //if value is -1, takes global options
409  if ($iMaxCount < 0) {
410  $iMaxCount = $this->getConfig()->getConfigParam("iMaxDownloadsCount");
411  }
412 
413  return $iMaxCount;
414  }
415 
422  {
423  $iMaxCount = $this->oxfiles__oxmaxunregdownloads->value;
424  //if value is -1, takes global options
425  if ($iMaxCount < 0) {
426  $iMaxCount = $this->getConfig()->getConfigParam("iMaxDownloadsCountUnregistered");
427  }
428 
429  return $iMaxCount;
430  }
431 
437  public function getLinkExpirationTime()
438  {
439  $iExpTime = $this->oxfiles__oxlinkexptime->value;
440  //if value is -1, takes global options
441  if ($iExpTime < 0) {
442  $iExpTime = $this->getConfig()->getConfigParam("iLinkExpirationTime");
443  }
444 
445  return $iExpTime;
446  }
447 
453  public function getDownloadExpirationTime()
454  {
455  $iExpTime = $this->oxfiles__oxdownloadexptime->value;
456  //if value is -1, takes global options
457  if ($iExpTime < 0) {
458  $iExpTime = $this->getConfig()->getConfigParam("iDownloadExpirationTime");
459  }
460 
461  return $iExpTime;
462  }
463 
469  public function getSize()
470  {
471  $iSize = 0;
472  if ($this->exist()) {
473  $iSize = filesize($this->getStoreLocation());
474  }
475 
476  return $iSize;
477  }
478 }