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 if ( !is_dir( dirname( $sTarget ) ) ) {
00406 mkdir(dirname($sTarget), 0744, true);
00407 }
00408 if ( $sSource === $sTarget ) {
00409 $blDone = true;
00410 } else {
00411 $blDone = move_uploaded_file( $sSource, $sTarget );
00412 }
00413
00414 if ( $blDone ) {
00415 $blDone = @chmod( $sTarget, 0644 );
00416 }
00417
00418 return $blDone;
00419 }
00420
00432 public function processFiles( $oObject = null, $aFiles = array(), $blUseMasterImage = false, $blUnique = true )
00433 {
00434 $aFiles = $aFiles ? $aFiles : $_FILES;
00435 if ( isset( $aFiles['myfile']['name'] ) ) {
00436
00437 $oConfig = $this->getConfig();
00438 $oStr = getStr();
00439
00440
00441 $blDemo = (bool) $oConfig->isDemoShop();
00442
00443
00444 $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00445
00446 $iNewFilesCounter = 0;
00447 $aSource = $aFiles['myfile']['tmp_name'];
00448 $aError = $aFiles['myfile']['error'];
00449 $sErrorsDescription = '';
00450
00451 $oEx = oxNew( "oxExceptionToDisplay" );
00452
00453 while ( list( $sKey, $sValue ) = each( $aFiles['myfile']['name'] ) ) {
00454
00455 $sSource = $aSource[$sKey];
00456 $iError = $aError[$sKey];
00457 $aFiletype = explode( "@", $sKey );
00458 $sKey = $aFiletype[1];
00459 $sType = $aFiletype[0];
00460
00461 $sValue = strtolower( $sValue );
00462 $sImagePath = $this->_getImagePath( $sType );
00463
00464
00465 if ( UPLOAD_ERR_OK !== $iError && UPLOAD_ERR_NO_FILE !== $iError ) {
00466 $sErrorsDescription = $this->translateError( $iError );
00467 $oEx->setMessage( $sErrorsDescription );
00468 oxUtilsView::getInstance()->addErrorToDisplay( $oEx, false );
00469 }
00470
00471
00472 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique ) ) ) {
00473
00474
00475 $sProcessPath = $sTmpFolder . basename( $sSource );
00476
00477 if ( $sProcessPath ) {
00478
00479 if ( $blUseMasterImage ) {
00480
00481 $blMoved = $this->_copyFile( $sSource, $sImagePath . $sValue );
00482 } else {
00483 $blMoved = $this->_moveImage( $sSource, $sImagePath . $sValue );
00484 }
00485
00486 if ( $blMoved ) {
00487
00488 $iNewFilesCounter++;
00489
00490 if ( $oObject && isset( $oObject->$sKey ) ) {
00491 $oObject->{$sKey}->setValue( $sValue );
00492 }
00493 }
00494 }
00495 }
00496 }
00497
00498 $this->_setNewFilesCounter( $iNewFilesCounter );
00499 }
00500
00501 return $oObject;
00502 }
00503
00512 function checkFile( $sFile )
00513 {
00514 $aCheckCache = oxSession::getVar("checkcache");
00515
00516 if ( isset( $aCheckCache[$sFile] ) ) {
00517 return $aCheckCache[$sFile];
00518 }
00519
00520 $blRet = false;
00521
00522 if (is_readable( $sFile)) {
00523 $blRet = true;
00524 } else {
00525
00526 $blRet = $this->urlValidate( $sFile );
00527 }
00528
00529 $aCheckCache[$sFile] = $blRet;
00530 oxSession::setVar( "checkcache", $aCheckCache );
00531
00532 return $blRet;
00533 }
00534
00542 function urlValidate( $sLink )
00543 {
00544 $aUrlParts = @parse_url( $sLink );
00545 $sHost = ( isset( $aUrlParts["host"] ) && $aUrlParts["host"] ) ? $aUrlParts["host"] : null;
00546
00547 $blValid = false;
00548 if ( $sHost ) {
00549 $sDocumentPath = ( isset( $aUrlParts["path"] ) && $aUrlParts["path"] ) ? $aUrlParts["path"] : '/';
00550 $sDocumentPath .= ( isset( $aUrlParts["query"] ) && $aUrlParts["query"] ) ? '?' . $aUrlParts["query"] : '';
00551
00552 $sPort = ( isset( $aUrlParts["port"] ) && $aUrlParts["port"] ) ? $aUrlParts["port"] : '80';
00553
00554
00555 if ( ( $oConn = @fsockopen( $sHost, $sPort, $iErrNo, $sErrStr, 30 ) ) ) {
00556 fwrite ( $oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n" );
00557 $sResponse = fgets( $oConn, 22 );
00558 fclose( $oConn );
00559
00560 if ( preg_match( "/200 OK/", $sResponse ) ) {
00561 $blValid = true;
00562 }
00563 }
00564 }
00565
00566 return $blValid;
00567 }
00568
00581 public function handleUploadedFile($aFileInfo, $sUploadPath)
00582 {
00583 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00584
00585
00586 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00587 throw oxNew( "oxException", 'EXCEPTION_NOFILE' );
00588 }
00589
00590
00591 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00592 throw oxNew( "oxException", 'EXCEPTION_FILENAMEINVALIDCHARS' );
00593 }
00594
00595
00596 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00597 throw oxNew( "oxException", 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00598 }
00599
00600 $aPathInfo = pathinfo($aFileInfo['name']);
00601
00602 $sExt = $aPathInfo['extension'];
00603 $sFileName = $aPathInfo['filename'];
00604
00605 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00606 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00607 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00608 throw oxNew( "oxException", 'EXCEPTION_NOTALLOWEDTYPE' );
00609 }
00610
00611 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00612 $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName );
00613
00614 $sUrl = $this->getConfig()->getShopUrl() . $sUploadPath . "/" . $sFileName;
00615
00616
00617 $sUrl = str_replace('//', '/', $sUrl);
00618 $sUrl = str_replace(array('http:/', 'https:/'), array('http://', 'https://'), $sUrl);
00619
00620 return $sUrl;
00621 }
00622
00633 public function processFile( $sFileName, $sUploadPath )
00634 {
00635 $aFileInfo = $_FILES[$sFileName];
00636
00637 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00638
00639
00640 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00641 throw oxNew( "oxException", 'EXCEPTION_NOFILE' );
00642 }
00643
00644
00645 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00646 throw oxNew( "oxException", 'EXCEPTION_FILENAMEINVALIDCHARS' );
00647 }
00648
00649
00650 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00651 throw oxNew( "oxException", 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00652 }
00653
00654 $aPathInfo = pathinfo($aFileInfo['name']);
00655
00656 $sExt = $aPathInfo['extension'];
00657 $sFileName = $aPathInfo['filename'];
00658
00659 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00660 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00661
00662 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00663 throw oxNew( "oxException", 'EXCEPTION_NOTALLOWEDTYPE' );
00664 }
00665
00666 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00667
00668 if ( $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName ) ) {
00669 return $sFileName ;
00670 } else {
00671 return false;
00672 }
00673 }
00674
00687 protected function _getUniqueFileName( $sFilePath, $sFileName, $sFileExt, $sSufix = "", $blUnique = true )
00688 {
00689 $sFilePath = $this->normalizeDir( $sFilePath );
00690 $iFileCounter = 0;
00691 $sTempFileName = $sFileName;
00692 $oStr = getStr();
00693
00694
00695 while ( $blUnique && file_exists( $sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt ) ) {
00696 $iFileCounter++;
00697
00698
00699 $sTempFileName = $oStr->preg_replace("/\(".$iFileCounter."\)/", "", $sTempFileName );
00700
00701 $sFileName = $sTempFileName . "($iFileCounter)";
00702 }
00703
00704 return $sFileName . $sSufix . "." . $sFileExt;
00705 }
00706
00715 public function getImageDirByType( $sType, $blGenerated = false )
00716 {
00717 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00718 $sDir = $this->normalizeDir( $sFolder );
00719
00720 if ($blGenerated === true) {
00721 $sDir = str_replace('master/', 'generated/', $sDir);
00722 }
00723
00724 return $sDir;
00725 }
00726
00734 function translateError( $iError )
00735 {
00736 $message = '';
00737
00738 if ( $iError > 0 && $iError < 9 && 5 !== $iError ) {
00739 $message = 'EXCEPTION_FILEUPLOADERROR_'.( (int) $iError );
00740 }
00741
00742 return $message;
00743 }
00744
00752 public function getMimeType($sFileName)
00753 {
00754
00755 if (function_exists("finfo_file")) {
00756 $rFinfo = finfo_open(FILEINFO_MIME_TYPE);
00757 $sMime = finfo_file($rFinfo, $sFileName);
00758 return $sMime;
00759 }
00760
00761
00762 if (function_exists("mime_content_type")) {
00763 $sMime = mime_content_type($sFileName);
00764 return $sMime;
00765 }
00766
00767 return null;
00768 }
00769 }