00001 <?php
00002
00006 class oxUtilsFile extends oxSuperCfg
00007 {
00013 const PROMO_PICTURE_DIR = 'promo';
00014
00020 private static $_instance = null;
00021
00027 protected $_iMaxPicImgCount = 12;
00028
00034 protected $_iMaxZoomImgCount = 12;
00035
00041 protected $_aTypeToPath = array( 'TC' => 'master/category/thumb',
00042 'CICO' => 'master/category/icon',
00043 'PICO' => 'master/category/promo_icon',
00044 'MICO' => 'master/manufacturer/icon',
00045 'VICO' => 'master/vendor/icon',
00046 'PROMO'=> self::PROMO_PICTURE_DIR,
00047 'ICO' => 'master/product/icon',
00048 'TH' => 'master/product/thumb',
00049 'M1' => 'master/product/1',
00050 'M2' => 'master/product/2',
00051 'M3' => 'master/product/3',
00052 'M4' => 'master/product/4',
00053 'M5' => 'master/product/5',
00054 'M6' => 'master/product/6',
00055 'M7' => 'master/product/7',
00056 'M8' => 'master/product/8',
00057 'M9' => 'master/product/9',
00058 'M10' => 'master/product/10',
00059 'M11' => 'master/product/11',
00060 'M12' => 'master/product/12',
00061
00062 'P1' => '1',
00063 'P2' => '2',
00064 'P3' => '3',
00065 'P4' => '4',
00066 'P5' => '5',
00067 'P6' => '6',
00068 'P7' => '7',
00069 'P8' => '8',
00070 'P9' => '9',
00071 'P10' => '10',
00072 'P11' => '11',
00073 'P12' => '12',
00074 'Z1' => 'z1',
00075 'Z2' => 'z2',
00076 'Z3' => 'z3',
00077 'Z4' => 'z4',
00078 'Z5' => 'z5',
00079 'Z6' => 'z6',
00080 'Z7' => 'z7',
00081 'Z8' => 'z8',
00082 'Z9' => 'z9',
00083 'Z10' => 'z10',
00084 'Z11' => 'z11',
00085 'Z12' => 'z12',
00086
00087 'WP' => 'master/wrapping',
00088 'FL' => 'media',
00089 );
00090
00096 protected $_aBadFiles = array( 'php', 'php3', 'php4', 'php5', 'phps', 'php6', 'jsp', 'cgi', 'cmf', 'exe' );
00097
00103 protected $_aAllowedFiles = array( 'gif', 'jpg', 'jpeg', 'png', 'pdf' );
00104
00110 protected $_iNewFilesCounter = 0;
00111
00117 public static function getInstance()
00118 {
00119
00120 if ( defined( 'OXID_PHP_UNIT' ) ) {
00121 self::$_instance = modInstances::getMod( __CLASS__ );
00122 }
00123
00124 if ( !self::$_instance instanceof oxUtilsFile ) {
00125
00126 self::$_instance = oxNew( 'oxUtilsFile' );
00127 if ( defined( 'OXID_PHP_UNIT' ) ) {
00128 modInstances::addMod( __CLASS__, self::$_instance);
00129 }
00130 }
00131 return self::$_instance;
00132 }
00133
00139 public function __construct()
00140 {
00141 $myConfig = $this->getConfig();
00142
00143 if ( $iPicCount = $myConfig->getConfigParam( 'iPicCount' ) ) {
00144 $this->_iMaxPicImgCount = $iPicCount;
00145 }
00146
00147 $this->_iMaxZoomImgCount = $this->_iMaxPicImgCount;
00148 }
00149
00155 public function getNewFilesCounter()
00156 {
00157 return $this->_iNewFilesCounter;
00158 }
00159
00167 protected function _setNewFilesCounter( $iNewFilesCounter )
00168 {
00169 $this->_iNewFilesCounter = (int) $iNewFilesCounter;
00170 }
00171
00179 public function normalizeDir( $sDir )
00180 {
00181 if ( isset($sDir) && $sDir != "" && substr($sDir, -1) !== '/' ) {
00182 $sDir .= "/";
00183 }
00184
00185 return $sDir;
00186 }
00187
00196 public function copyDir( $sSourceDir, $sTargetDir )
00197 {
00198 $oStr = getStr();
00199 $handle = opendir( $sSourceDir );
00200 while ( false !== ( $file = readdir( $handle ) ) ) {
00201 if ( $file != '.' && $file != '..' ) {
00202 if ( is_dir( $sSourceDir.'/'.$file ) ) {
00203
00204
00205 $sNewSourceDir = $sSourceDir.'/'.$file;
00206 $sNewTargetDir = $sTargetDir.'/'.$file;
00207 if ( strcasecmp( $file, 'CVS' ) && strcasecmp( $file, '.svn' )) {
00208 @mkdir( $sNewTargetDir, 0777 );
00209 $this->copyDir( $sNewSourceDir, $sNewTargetDir );
00210 }
00211 } else {
00212 $sSourceFile = $sSourceDir.'/'.$file;
00213 $sTargetFile = $sTargetDir.'/'.$file;
00214
00215
00216 if ( !$oStr->strstr( $sSourceDir, 'dyn_images' ) || $file == 'nopic.jpg' || $file == 'nopic_ico.jpg' ) {
00217 @copy( $sSourceFile, $sTargetFile );
00218 }
00219 }
00220 }
00221 }
00222 closedir($handle);
00223 }
00224
00232 public function deleteDir( $sSourceDir )
00233 {
00234 if ( is_dir( $sSourceDir ) ) {
00235 if ( $oDir = dir( $sSourceDir ) ) {
00236
00237 while ( false !== $sFile = $oDir->read() ) {
00238 if ( $sFile == '.' || $sFile == '..' ) {
00239 continue;
00240 }
00241
00242 if ( !$this->deleteDir( $oDir->path . DIRECTORY_SEPARATOR . $sFile ) ) {
00243 $oDir->close();
00244 return false;
00245 }
00246 }
00247
00248 $oDir->close();
00249 return rmdir( $sSourceDir );
00250 }
00251 } elseif ( file_exists( $sSourceDir ) ) {
00252 return unlink ( $sSourceDir );
00253 }
00254 }
00255
00263 public function readRemoteFileAsString( $sPath )
00264 {
00265 $sRet = '';
00266 $hFile = @fopen( $sPath, 'r' );
00267 if ( $hFile ) {
00268 socket_set_timeout( $hFile, 2 );
00269 while ( !feof( $hFile ) ) {
00270 $sLine = fgets( $hFile, 4096 );
00271 $sRet .= $sLine;
00272 }
00273 fclose( $hFile );
00274 }
00275
00276 return $sRet;
00277 }
00278
00290 protected function _prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique = true )
00291 {
00292 if ( $sValue ) {
00293
00294 $aFilename = explode( ".", $sValue );
00295
00296 $sFileType = trim( $aFilename[count( $aFilename )-1] );
00297
00298 if ( isset( $sFileType ) ) {
00299
00300 $oStr = getStr();
00301
00302
00303 if ( in_array( $sFileType, $this->_aBadFiles ) || ( $blDemo && !in_array( $sFileType, $this->_aAllowedFiles ) ) ) {
00304 oxUtils::getInstance()->showMessageAndExit( "We don't play this game, go away" );
00305 }
00306
00307
00308 if ( count( $aFilename ) > 0 ) {
00309 unset( $aFilename[count( $aFilename )-1] );
00310 }
00311
00312 $sFName = '';
00313 if ( isset( $aFilename[0] ) ) {
00314 $sFName = $oStr->preg_replace( '/[^a-zA-Z0-9()_\.-]/', '', implode( '.', $aFilename ) );
00315 }
00316
00317 $sValue = $this->_getUniqueFileName( $sImagePath, "{$sFName}", $sFileType, "", $blUnique );
00318 }
00319 }
00320 return $sValue;
00321 }
00322
00330 protected function _getImagePath( $sType )
00331 {
00332 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00333 $sPath = $this->normalizeDir( $this->getConfig()->getPictureDir(false) ) . "{$sFolder}/";
00334 return $sPath;
00335 }
00336
00347 protected function _getImageSize( $sImgType, $iImgNum, $sImgConf )
00348 {
00349 $myConfig = $this->getConfig();
00350 $sSize = false;
00351
00352 switch ( $sImgConf ) {
00353 case 'aDetailImageSizes':
00354 $aDetailImageSizes = $myConfig->getConfigParam( $sImgConf );
00355 $sSize = $myConfig->getConfigParam( 'sDetailImageSize' );
00356 if ( isset( $aDetailImageSizes['oxpic'.$iImgNum] ) ) {
00357 $sSize = $aDetailImageSizes['oxpic'.$iImgNum];
00358 }
00359 break;
00360 default:
00361 $sSize = $myConfig->getConfigParam( $sImgConf );
00362 break;
00363 }
00364 if ( $sSize ) {
00365 return explode( '*', $sSize );
00366 }
00367 }
00368
00377 protected function _copyFile( $sSource, $sTarget )
00378 {
00379 $blDone = false;
00380
00381 if ( $sSource === $sTarget ) {
00382 $blDone = true;
00383 } else {
00384 $blDone = copy( $sSource, $sTarget );
00385 }
00386
00387 if ( $blDone ) {
00388 $blDone = @chmod( $sTarget, 0644 );
00389 }
00390
00391 return $blDone;
00392 }
00393
00402 protected function _moveImage( $sSource, $sTarget )
00403 {
00404 $blDone = false;
00405
00406 if ( $sSource === $sTarget ) {
00407 $blDone = true;
00408 } else {
00409 $blDone = move_uploaded_file( $sSource, $sTarget );
00410 }
00411
00412 if ( $blDone ) {
00413 $blDone = @chmod( $sTarget, 0644 );
00414 }
00415
00416 return $blDone;
00417 }
00418
00430 public function processFiles( $oObject = null, $aFiles = array(), $blUseMasterImage = false, $blUnique = true )
00431 {
00432 $aFiles = $aFiles ? $aFiles : $_FILES;
00433 if ( isset( $aFiles['myfile']['name'] ) ) {
00434
00435 $oConfig = $this->getConfig();
00436 $oStr = getStr();
00437
00438
00439 $blDemo = (bool) $oConfig->isDemoShop();
00440
00441
00442 $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00443
00444 $iNewFilesCounter = 0;
00445 $aSource = $aFiles['myfile']['tmp_name'];
00446 $aError = $aFiles['myfile']['error'];
00447 $sErrorsDescription = '';
00448
00449 $oEx = oxNew( "oxExceptionToDisplay" );
00450
00451 while ( list( $sKey, $sValue ) = each( $aFiles['myfile']['name'] ) ) {
00452
00453 $sSource = $aSource[$sKey];
00454 $iError = $aError[$sKey];
00455 $aFiletype = explode( "@", $sKey );
00456 $sKey = $aFiletype[1];
00457 $sType = $aFiletype[0];
00458
00459 $sValue = strtolower( $sValue );
00460 $sImagePath = $this->_getImagePath( $sType );
00461
00462
00463 if ( UPLOAD_ERR_OK !== $iError && UPLOAD_ERR_NO_FILE !== $iError ) {
00464 $sErrorsDescription = $this->translateError( $iError );
00465 $oEx->setMessage( $sErrorsDescription );
00466 oxUtilsView::getInstance()->addErrorToDisplay( $oEx, false );
00467 }
00468
00469
00470 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique ) ) ) {
00471
00472
00473 $sProcessPath = $sTmpFolder . basename( $sSource );
00474
00475 if ( $sProcessPath ) {
00476
00477 if ( $blUseMasterImage ) {
00478
00479 $blMoved = $this->_copyFile( $sSource, $sImagePath . $sValue );
00480 } else {
00481 $blMoved = $this->_moveImage( $sSource, $sImagePath . $sValue );
00482 }
00483
00484 if ( $blMoved ) {
00485
00486 $iNewFilesCounter++;
00487
00488 if ( $oObject && isset( $oObject->$sKey ) ) {
00489 $oObject->{$sKey}->setValue( $sValue );
00490 }
00491 }
00492 }
00493 }
00494 }
00495
00496 $this->_setNewFilesCounter( $iNewFilesCounter );
00497 }
00498
00499 return $oObject;
00500 }
00501
00510 function checkFile( $sFile )
00511 {
00512 $aCheckCache = oxSession::getVar("checkcache");
00513
00514 if ( isset( $aCheckCache[$sFile] ) ) {
00515 return $aCheckCache[$sFile];
00516 }
00517
00518 $blRet = false;
00519
00520 if (is_readable( $sFile)) {
00521 $blRet = true;
00522 } else {
00523
00524 $blRet = $this->urlValidate( $sFile );
00525 }
00526
00527 $aCheckCache[$sFile] = $blRet;
00528 oxSession::setVar( "checkcache", $aCheckCache );
00529
00530 return $blRet;
00531 }
00532
00540 function urlValidate( $sLink )
00541 {
00542 $aUrlParts = @parse_url( $sLink );
00543 $sHost = ( isset( $aUrlParts["host"] ) && $aUrlParts["host"] ) ? $aUrlParts["host"] : null;
00544
00545 $blValid = false;
00546 if ( $sHost ) {
00547 $sDocumentPath = ( isset( $aUrlParts["path"] ) && $aUrlParts["path"] ) ? $aUrlParts["path"] : '/';
00548 $sDocumentPath .= ( isset( $aUrlParts["query"] ) && $aUrlParts["query"] ) ? '?' . $aUrlParts["query"] : '';
00549
00550 $sPort = ( isset( $aUrlParts["port"] ) && $aUrlParts["port"] ) ? $aUrlParts["port"] : '80';
00551
00552
00553 if ( ( $oConn = @fsockopen( $sHost, $sPort, $iErrNo, $sErrStr, 30 ) ) ) {
00554 fwrite ( $oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n" );
00555 $sResponse = fgets( $oConn, 22 );
00556 fclose( $oConn );
00557
00558 if ( preg_match( "/200 OK/", $sResponse ) ) {
00559 $blValid = true;
00560 }
00561 }
00562 }
00563
00564 return $blValid;
00565 }
00566
00579 public function handleUploadedFile($aFileInfo, $sUploadPath)
00580 {
00581 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00582
00583
00584 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00585 throw oxNew( "oxException", 'EXCEPTION_NOFILE' );
00586 }
00587
00588
00589 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00590 throw oxNew( "oxException", 'EXCEPTION_FILENAMEINVALIDCHARS' );
00591 }
00592
00593
00594 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00595 throw oxNew( "oxException", 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00596 }
00597
00598 $aPathInfo = pathinfo($aFileInfo['name']);
00599
00600 $sExt = $aPathInfo['extension'];
00601 $sFileName = $aPathInfo['filename'];
00602
00603 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00604 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00605 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00606 throw oxNew( "oxException", 'EXCEPTION_NOTALLOWEDTYPE' );
00607 }
00608
00609 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00610 $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName );
00611
00612 $sUrl = $this->getConfig()->getShopUrl() . $sUploadPath . "/" . $sFileName;
00613
00614
00615 $sUrl = str_replace('//', '/', $sUrl);
00616 $sUrl = str_replace(array('http:/', 'https:/'), array('http://', 'https://'), $sUrl);
00617
00618 return $sUrl;
00619 }
00620
00631 public function processFile( $sFileName, $sUploadPath )
00632 {
00633 $aFileInfo = $_FILES[$sFileName];
00634
00635 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00636
00637
00638 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00639 throw oxNew( "oxException", 'EXCEPTION_NOFILE' );
00640 }
00641
00642
00643 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00644 throw oxNew( "oxException", 'EXCEPTION_FILENAMEINVALIDCHARS' );
00645 }
00646
00647
00648 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00649 throw oxNew( "oxException", 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00650 }
00651
00652 $aPathInfo = pathinfo($aFileInfo['name']);
00653
00654 $sExt = $aPathInfo['extension'];
00655 $sFileName = $aPathInfo['filename'];
00656
00657 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00658 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00659
00660 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00661 throw oxNew( "oxException", 'EXCEPTION_NOTALLOWEDTYPE' );
00662 }
00663
00664 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00665
00666 if ( $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName ) ) {
00667 return $sFileName ;
00668 } else {
00669 return false;
00670 }
00671 }
00672
00685 protected function _getUniqueFileName( $sFilePath, $sFileName, $sFileExt, $sSufix = "", $blUnique = true )
00686 {
00687 $sFilePath = $this->normalizeDir( $sFilePath );
00688 $iFileCounter = 0;
00689 $sTempFileName = $sFileName;
00690 $oStr = getStr();
00691
00692
00693 while ( $blUnique && file_exists( $sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt ) ) {
00694 $iFileCounter++;
00695
00696
00697 $sTempFileName = $oStr->preg_replace("/\(".$iFileCounter."\)/", "", $sTempFileName );
00698
00699 $sFileName = $sTempFileName . "($iFileCounter)";
00700 }
00701
00702 return $sFileName . $sSufix . "." . $sFileExt;
00703 }
00704
00713 public function getImageDirByType( $sType, $blGenerated = false )
00714 {
00715 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00716 $sDir = $this->normalizeDir( $sFolder );
00717
00718 if ($blGenerated === true) {
00719 $sDir = str_replace('master/', 'generated/', $sDir);
00720 }
00721
00722 return $sDir;
00723 }
00724
00732 function translateError( $iError )
00733 {
00734 $message = '';
00735
00736 if ( $iError > 0 && $iError < 9 && 5 !== $iError ) {
00737 $message = 'EXCEPTION_FILEUPLOADERROR_'.( (int) $iError );
00738 }
00739
00740 return $message;
00741 }
00742
00750 public function getMimeType($sFileName)
00751 {
00752
00753 if (function_exists("finfo_file")) {
00754 $rFinfo = finfo_open(FILEINFO_MIME_TYPE);
00755 $sMime = finfo_file($rFinfo, $sFileName);
00756 return $sMime;
00757 }
00758
00759
00760 if (function_exists("mime_content_type")) {
00761 $sMime = mime_content_type($sFileName);
00762 return $sMime;
00763 }
00764
00765 return null;
00766 }
00767 }