OXID eShop CE  4.8.12
 All Classes Files Functions Variables Pages
oxfile.php
Go to the documentation of this file.
1 <?php
2 
7 class oxFile extends oxBase
8 {
12  const NO_USER = 2;
13 
19  protected $_sCoreTable = 'oxfiles';
20 
26  protected $_sClassName = 'oxfile';
27 
33  protected $_sRelativeFilePath = null;
34 
40  protected $_blIsPaid = null;
41 
48  protected $_sDownloadLink = null;
49 
55  protected $_blHasValidDownloads = null;
56 
62  protected $_sManualUploadDir = "uploads";
63 
68  public function __construct()
69  {
71  $this->init();
72  }
73 
81  public function processFile( $sFileIndex )
82  {
83  $aFileInfo = $this->getConfig()->getUploadedFile( $sFileIndex );
84 
85  $this->_checkArticleFile( $aFileInfo );
86 
87  $sFileHash = $this->_getFileHash( $aFileInfo['tmp_name'] );
88  $this->oxfiles__oxstorehash = new oxField( $sFileHash, oxField::T_RAW );
89  $sUploadTo = $this->getStoreLocation();
90 
91  if ( !$this->_uploadFile( $aFileInfo['tmp_name'], $sUploadTo ) ) {
92  throw new oxException( 'EXCEPTION_COULDNOTWRITETOFILE' );
93  }
94 
95  }
96 
104  protected function _checkArticleFile( $aFileInfo )
105  {
106  //checking params
107  if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
108  throw new oxException( 'EXCEPTION_NOFILE' );
109  }
110 
111  // error uploading file ?
112  if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
113  throw new oxException( 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
114  }
115 
116  }
117 
123  protected function _getBaseDownloadDirPath()
124  {
125  $sConfigValue = oxRegistry::getConfig()->getConfigParam( 'sDownloadsDir' );
126 
127  //Unix full path is set
128  if ( $sConfigValue && $sConfigValue[0] == DIR_SEP) {
129  return $sConfigValue;
130  }
131 
132  //relative path is set
133  if ( $sConfigValue ) {
134  $sPath = getShopBasePath() . DIR_SEP . $sConfigValue;
135  return $sPath;
136  }
137 
138  //no path is set
139  $sPath = getShopBasePath() . "/out/downloads/";
140  return $sPath;
141  }
142 
150  public function getStoreLocation()
151  {
152  $sPath = $this->_getBaseDownloadDirPath();
153  $sPath .= DIR_SEP . $this->_getFileLocation();
154  return $sPath;
155  }
156 
163  public function isUnderDownloadFolder()
164  {
165  $storageLocation = realpath($this->getStoreLocation());
166 
167  if ($storageLocation === false) {
168  return false;
169  }
170 
171  $downloadFolder = realpath($this->_getBaseDownloadDirPath());
172 
173  return strpos($storageLocation, $downloadFolder) !== false;
174  }
175 
181  protected function _getFileLocation()
182  {
183  $this->_sRelativeFilePath = '';
184  $sFileHash = $this->oxfiles__oxstorehash->value;
185  $sFileName = $this->oxfiles__oxfilename->value;
186 
187  //security check for demo shops
188  if ($this->getConfig()->isDemoShop()) {
189  $sFileName = basename($sFileName);
190  }
191 
192  if ($this->isUploaded()) {
193  $this->_sRelativeFilePath = $this->_getHashedFileDir($sFileHash);
194  $this->_sRelativeFilePath .= DIR_SEP . $sFileHash;
195  } else {
196  $this->_sRelativeFilePath = DIR_SEP . $this->_sManualUploadDir . DIR_SEP . $sFileName;
197  }
198 
200  }
201 
211  protected function _getHashedFileDir( $sFileHash )
212  {
213  $sDir = substr($sFileHash, 0, 2);
214  $sAbsDir = $this->_getBaseDownloadDirPath() . DIR_SEP . $sDir;
215 
216  if (!is_dir($sAbsDir)) {
217  mkdir($sAbsDir, 0755);
218  }
219  return $sDir;
220  }
221 
230  protected function _getFileHash( $sFileName )
231  {
232  return md5_file( $sFileName );
233  }
234 
244  protected function _uploadFile( $sSource, $sTarget )
245  {
246  $blDone = move_uploaded_file( $sSource, $sTarget );
247 
248  if ( $blDone ) {
249  $blDone = @chmod( $sTarget, 0644 );
250  }
251 
252  return $blDone;
253  }
254 
263  public function isUploaded()
264  {
265  $blHashed = false;
266  if ($this->oxfiles__oxstorehash->value) {
267  $blHashed = true;
268  }
269  return $blHashed;
270  }
271 
279  public function delete( $sOxId = null )
280  {
281  $sOxId = $sOxId ? $sOxId : $this->getId();
282 
283  $this->load($sOxId);
284  // if record cannot be delete, abort deletion
285  if ($blDeleted = parent::delete( $sOxId ) ) {
286  $this->_deleteFile( );
287  }
288 
289  return $blDeleted;
290  }
291 
298  protected function _deleteFile()
299  {
300  if (!$this->isUploaded()) {
301  return false;
302  }
303  $sHash = $this->oxfiles__oxstorehash->value;
304  $oDb = oxDb::getDb();
305  $iCount = $oDb->getOne(
306  'SELECT COUNT(*) FROM `oxfiles` WHERE `OXSTOREHASH` = ' . $oDb->quote( $sHash ), false, false );
307  if (!$iCount) {
308  $sPath = $this->getStoreLocation();
309  unlink($sPath);
310  }
311  }
312 
319  protected function _getFilenameForUrl()
320  {
321  return rawurlencode($this->oxfiles__oxfilename->value);
322  }
323 
327  public function download()
328  {
329  $oUtils = oxRegistry::getUtils();
330  $sFileName = $this->_getFilenameForUrl();
331  $sFileLocations = $this->getStoreLocation();
332 
333  if ( !$this->exist() || !$this->isUnderDownloadFolder() ) {
334  throw new oxException( 'EXCEPTION_NOFILE' );
335  }
336 
337  $oUtils->setHeader("Pragma: public");
338  $oUtils->setHeader("Expires: 0");
339  $oUtils->setHeader("Cache-Control: must-revalidate, post-check=0, pre-check=0, private");
340  $oUtils->setHeader('Content-Disposition: attachment;filename=' . $sFileName);
341  $oUtils->setHeader("Content-Type: application/octet-stream");
342  if ( $iFileSize = $this->getSize() ) {
343  $oUtils->setHeader("Content-Length: " . $iFileSize);
344  }
345  readfile( $sFileLocations );
346  $oUtils->showMessageAndExit( null );
347  }
348 
354  public function exist()
355  {
356  return file_exists( $this->getStoreLocation() );
357  }
358 
364  public function hasValidDownloads()
365  {
366  if ( $this->_blHasValidDownloads == null ) {
367  $this->_blHasValidDownloads = false;
368  $sNow = date( 'Y-m-d H:i:s', oxRegistry::get("oxUtilsDate")->getTime() );
369  $sFileId = $this->getId();
370 
371  $oDb = oxDb::getDb();
372 
373  $sSql = "SELECT
374  `oxorderfiles`.`oxid`
375  FROM `oxorderfiles`
376  LEFT JOIN `oxorderarticles` ON `oxorderarticles`.`oxid` = `oxorderfiles`.`oxorderarticleid`
377  LEFT JOIN `oxorder` ON `oxorder`.`oxid` = `oxorderfiles`.`oxorderid`
378  WHERE `oxorderfiles`.`oxfileid` = " . $oDb->quote($sFileId) . "
379  AND ( ! `oxorderfiles`.`oxmaxdownloadcount` OR `oxorderfiles`.`oxmaxdownloadcount` > `oxorderfiles`.`oxdownloadcount`)
380  AND ( `oxorderfiles`.`oxvaliduntil` = '0000-00-00 00:00:00' OR `oxorderfiles`.`oxvaliduntil` > '{$sNow}' )
381  AND `oxorder`.`oxstorno` = 0
382  AND `oxorderarticles`.`oxstorno` = 0";
383 
384  if ( $oDb->getOne( $sSql ) ) {
385  $this->_blHasValidDownloads = true;
386  }
387  }
389  }
390 
396  public function getMaxDownloadsCount()
397  {
398  $iMaxCount = $this->oxfiles__oxmaxdownloads->value;
399  //if value is -1, takes global options
400  if ( $iMaxCount < 0) {
401  $iMaxCount = $this->getConfig()->getConfigParam( "iMaxDownloadsCount" );
402  }
403  return $iMaxCount;
404  }
405 
412  {
413  $iMaxCount = $this->oxfiles__oxmaxunregdownloads->value;
414  //if value is -1, takes global options
415  if ( $iMaxCount < 0) {
416  $iMaxCount = $this->getConfig()->getConfigParam( "iMaxDownloadsCountUnregistered" );
417  }
418  return $iMaxCount;
419  }
420 
426  public function getLinkExpirationTime()
427  {
428  $iExpTime = $this->oxfiles__oxlinkexptime->value;
429  //if value is -1, takes global options
430  if ( $iExpTime < 0) {
431  $iExpTime = $this->getConfig()->getConfigParam( "iLinkExpirationTime" );
432  }
433  return $iExpTime;
434  }
435 
441  public function getDownloadExpirationTime()
442  {
443  $iExpTime = $this->oxfiles__oxdownloadexptime->value;
444  //if value is -1, takes global options
445  if ( $iExpTime < 0) {
446  $iExpTime = $this->getConfig()->getConfigParam( "iDownloadExpirationTime" );
447  }
448  return $iExpTime;
449  }
450 
456  public function getSize()
457  {
458  $iSize = 0;
459  if ( $this->exist() ) {
460  $iSize = filesize( $this->getStoreLocation() );
461  }
462  return $iSize;
463  }
464 
465 }