00001 <?php
00002
00006 class oxUtilsFile extends oxSuperCfg
00007 {
00013 private static $_instance = null;
00014
00020 protected $_iMaxPicImgCount = 12;
00021
00027 protected $_iMaxZoomImgCount = 12;
00028
00034 protected $_aTypeToPath = array( 'ICO' => 'icon',
00035 'CICO' => 'icon',
00036 'TH' => '0',
00037 'TC' => '0',
00038 'M1' => 'master/1',
00039 'M2' => 'master/2',
00040 'M3' => 'master/3',
00041 'M4' => 'master/4',
00042 'M5' => 'master/5',
00043 'M6' => 'master/6',
00044 'M7' => 'master/7',
00045 'M8' => 'master/8',
00046 'M9' => 'master/9',
00047 'M10' => 'master/10',
00048 'M11' => 'master/11',
00049 'M12' => 'master/12',
00050 'P1' => '1',
00051 'P2' => '2',
00052 'P3' => '3',
00053 'P4' => '4',
00054 'P5' => '5',
00055 'P6' => '6',
00056 'P7' => '7',
00057 'P8' => '8',
00058 'P9' => '9',
00059 'P10' => '10',
00060 'P11' => '11',
00061 'P12' => '12',
00062 'Z1' => 'z1',
00063 'Z2' => 'z2',
00064 'Z3' => 'z3',
00065 'Z4' => 'z4',
00066 'Z5' => 'z5',
00067 'Z6' => 'z6',
00068 'Z7' => 'z7',
00069 'Z8' => 'z8',
00070 'Z9' => 'z9',
00071 'Z10' => 'z10',
00072 'Z11' => 'z11',
00073 'Z12' => 'z12'
00074 );
00075
00081 protected $_aBadFiles = array( 'php', 'jsp', 'cgi', 'cmf', 'exe' );
00082
00083
00089 protected $_aAllowedFiles = array( 'gif', 'jpg', 'png', 'pdf' );
00095 public static function getInstance()
00096 {
00097
00098 if ( defined( 'OXID_PHP_UNIT' ) ) {
00099 self::$_instance = modInstances::getMod( __CLASS__ );
00100 }
00101
00102 if ( !self::$_instance instanceof oxUtilsFile ) {
00103
00104 self::$_instance = oxNew( 'oxUtilsFile' );
00105 if ( defined( 'OXID_PHP_UNIT' ) ) {
00106 modInstances::addMod( __CLASS__, self::$_instance);
00107 }
00108 }
00109 return self::$_instance;
00110 }
00111
00117 public function __construct()
00118 {
00119 $myConfig = $this->getConfig();
00120
00121 if ( $iPicCount = $myConfig->getConfigParam( 'iPicCount' ) ) {
00122 $this->_iMaxPicImgCount = $iPicCount;
00123 }
00124
00125 $this->_iMaxZoomImgCount = $this->_iMaxPicImgCount;
00126 }
00127
00135 public function normalizeDir( $sDir )
00136 {
00137 if ( isset($sDir) && $sDir != "" && substr($sDir, -1) !== '/' ) {
00138 $sDir .= "/";
00139 }
00140
00141 return $sDir;
00142 }
00143
00152 public function copyDir( $sSourceDir, $sTargetDir )
00153 {
00154 $oStr = getStr();
00155 $handle = opendir( $sSourceDir );
00156 while ( false !== ( $file = readdir( $handle ) ) ) {
00157 if ( $file != '.' && $file != '..' ) {
00158 if ( is_dir( $sSourceDir.'/'.$file ) ) {
00159
00160
00161 $sNewSourceDir = $sSourceDir.'/'.$file;
00162 $sNewTargetDir = $sTargetDir.'/'.$file;
00163 if ( strcasecmp( $file, 'CVS' ) && strcasecmp( $file, '.svn' )) {
00164 @mkdir( $sNewTargetDir, 0777 );
00165 $this->copyDir( $sNewSourceDir, $sNewTargetDir );
00166 }
00167 } else {
00168 $sSourceFile = $sSourceDir.'/'.$file;
00169 $sTargetFile = $sTargetDir.'/'.$file;
00170
00171
00172 if ( !$oStr->strstr( $sSourceDir, 'dyn_images' ) || $file == 'nopic.jpg' || $file == 'nopic_ico.jpg' ) {
00173 @copy( $sSourceFile, $sTargetFile );
00174 }
00175 }
00176 }
00177 }
00178 closedir($handle);
00179 }
00180
00188 public function deleteDir( $sSourceDir )
00189 {
00190 if ( is_dir( $sSourceDir ) ) {
00191 if ( $oDir = dir( $sSourceDir ) ) {
00192
00193 while ( false !== $sFile = $oDir->read() ) {
00194 if ( $sFile == '.' || $sFile == '..' ) {
00195 continue;
00196 }
00197
00198 if ( !$this->deleteDir( $oDir->path . DIRECTORY_SEPARATOR . $sFile ) ) {
00199 $oDir->close();
00200 return false;
00201 }
00202 }
00203
00204 $oDir->close();
00205 return rmdir( $sSourceDir );
00206 }
00207 } elseif ( file_exists( $sSourceDir ) ) {
00208 return unlink ( $sSourceDir );
00209 }
00210 }
00211
00219 public function readRemoteFileAsString( $sPath )
00220 {
00221 $sRet = '';
00222 $hFile = @fopen( $sPath, 'r' );
00223 if ( $hFile ) {
00224 socket_set_timeout( $hFile, 2 );
00225 while ( !feof( $hFile ) ) {
00226 $sLine = fgets( $hFile, 4096 );
00227 $sRet .= $sLine;
00228 }
00229 fclose( $hFile );
00230 }
00231
00232 return $sRet;
00233 }
00234
00246 protected function _prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique = true )
00247 {
00248 if ( $sValue ) {
00249
00250 $aFilename = explode( ".", $sValue );
00251
00252 $sFileType = trim( $aFilename[count( $aFilename )-1] );
00253
00254 if ( isset( $sFileType ) ) {
00255
00256 $oStr = getStr();
00257
00258
00259 if ( in_array( $sFileType, $this->_aBadFiles ) || ( $blDemo && !in_array( $sFileType, $this->_aAllowedFiles ) ) ) {
00260 oxUtils::getInstance()->showMessageAndExit( "We don't play this game, go away" );
00261 }
00262
00263
00264 if ( count( $aFilename ) > 0 ) {
00265 unset( $aFilename[count( $aFilename )-1] );
00266 }
00267
00268 $sFName = '';
00269 if ( isset( $aFilename[0] ) ) {
00270 $sFName = $oStr->preg_replace( '/[^a-zA-Z0-9()_\.-]/', '', implode( '.', $aFilename ) );
00271 }
00272
00273
00274
00275 $sSufix = ( $oStr->preg_match( "/(P|M)\d+/", $sType ) ) ? "" : "_".strtolower( $sType );
00276
00277 $sValue = $this->_getUniqueFileName( $sImagePath, "{$sFName}", $sFileType, $sSufix, $blUnique );
00278 }
00279 }
00280 return $sValue;
00281 }
00282
00290 protected function _getImagePath( $sType )
00291 {
00292 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00293 $sPath = $this->normalizeDir( $this->getConfig()->getAbsDynImageDir() ) . "{$sFolder}/";
00294 return $sPath;
00295 }
00296
00307 protected function _getImageSize( $sImgType, $iImgNum, $sImgConf )
00308 {
00309 $myConfig = $this->getConfig();
00310 $sSize = false;
00311
00312 switch ( $sImgConf ) {
00313 case 'aDetailImageSizes':
00314 $aDetailImageSizes = $myConfig->getConfigParam( $sImgConf );
00315 $sSize = $myConfig->getConfigParam( 'sDetailImageSize' );
00316 if ( isset( $aDetailImageSizes['oxpic'.$iImgNum] ) ) {
00317 $sSize = $aDetailImageSizes['oxpic'.$iImgNum];
00318 }
00319 break;
00320 default:
00321 $sSize = $myConfig->getConfigParam( $sImgConf );
00322 break;
00323 }
00324 if ( $sSize ) {
00325 return explode( '*', $sSize );
00326 }
00327 }
00328
00339 protected function _prepareImage( $sType, $sSource, $sTarget )
00340 {
00341 $oUtilsPic = oxUtilspic::getInstance();
00342 $oPictureHandler = oxPictureHandler::getInstance();
00343 $oStr = getStr();
00344
00345
00346 $sPicType = $oStr->preg_replace( "/\d*$/", "", $sType );
00347
00348
00349 $iPicNum = (int) $oStr->preg_replace( "/^\D*/", "", $sType );
00350 $iPicNum = $iPicNum ? abs( $iPicNum ) : 1;
00351
00352 $aSize = false;
00353 $blResize = false;
00354
00355
00356 switch ( $sPicType ) {
00357 case 'TH':
00358 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sThumbnailsize' );
00359 break;
00360 case 'TC':
00361 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sCatThumbnailsize' );
00362 break;
00363 case 'CICO':
00364 case 'ICO':
00365 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sIconsize' );
00366 break;
00367 case 'P':
00368
00369 $iPicNum = ( $iPicNum > $this->_iMaxPicImgCount ) ? $this->_iMaxPicImgCount : $iPicNum;
00370
00371
00372 if ( ( $aSize = $this->_getImageSize( $sType, 1, 'sIconsize' ) ) ) {
00373 $sIconTarget = dirname($sTarget) . '/' . $oPictureHandler->getIconName( $sTarget );
00374 $oUtilsPic->resizeImage( $sSource, $sIconTarget, $aSize[0], $aSize[1] );
00375 }
00376
00377 $aSize = $this->_getImageSize( $sType, $iPicNum, 'aDetailImageSizes' );
00378 break;
00379 case 'M':
00380 case 'WP':
00381 case 'FL':
00382
00383 $this->_copyFile($sSource, $sTarget);
00384 break;
00385 case 'Z':
00386 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sZoomImageSize' );
00387 break;
00388 }
00389
00390 if ( $aSize ) {
00391 $blResize = $oUtilsPic->resizeImage( $sSource, $sTarget, $aSize[0], $aSize[1] );
00392 }
00393 return $blResize;
00394 }
00395
00404 protected function _copyFile( $sSource, $sTarget )
00405 {
00406 $blDone = false;
00407
00408 if ( $sSource === $sTarget ) {
00409 $blDone = true;
00410 } else {
00411 $blDone = copy( $sSource, $sTarget );
00412 }
00413
00414 if ( $blDone ) {
00415 $blDone = @chmod( $sTarget, 0644 );
00416 }
00417
00418 return $blDone;
00419 }
00420
00429 protected function _moveImage( $sSource, $sTarget )
00430 {
00431
00432
00433 $blDone = false;
00434
00435 if ( $sSource === $sTarget ) {
00436 $blDone = true;
00437 } else {
00438
00439
00440 $blDone = move_uploaded_file( $sSource, $sTarget );
00441 }
00442
00443 if ( $blDone ) {
00444 $blDone = @chmod( $sTarget, 0644 );
00445 }
00446
00447 return $blDone;
00448 }
00449
00457 protected function _removeTempImage( $sImagePath )
00458 {
00459 return unlink( $sImagePath );
00460 }
00461
00473 public function processFiles( $oObject = null, $aFiles = array(), $blUseMasterImage = false, $blUnique = true )
00474 {
00475 $aFiles = $aFiles ? $aFiles : $_FILES;
00476 if ( isset( $aFiles['myfile']['name'] ) ) {
00477
00478 $oConfig = $this->getConfig();
00479 $oStr = getStr();
00480
00481
00482 $blDemo = (bool) $oConfig->isDemoShop();
00483
00484
00485 $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00486
00487
00488 while ( list( $sKey, $sValue ) = each( $aFiles['myfile']['name'] ) ) {
00489
00490 $aSource = $aFiles['myfile']['tmp_name'];
00491 $sSource = $aSource[$sKey];
00492 $aFiletype = explode( "@", $sKey );
00493 $sKey = $aFiletype[1];
00494 $sType = $aFiletype[0];
00495
00496 $sValue = strtolower( $sValue );
00497 $sImagePath = $this->_getImagePath( $sType );
00498
00499
00500 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique ) ) ) {
00501
00502
00503
00504 $sProcessPath = $sTmpFolder . basename( $sSource );
00505
00506 if ( $sProcessPath ) {
00507
00508 if ( $blUseMasterImage ) {
00509
00510
00511 $blMoved = $this->_copyFile( $sSource, $sProcessPath );
00512 } else {
00513 $blMoved = $this->_moveImage( $sSource, $sProcessPath );
00514 }
00515
00516 if ( $blMoved ) {
00517
00518 if ( ( $sTarget = $sImagePath . $sValue ) ) {
00519
00520 $this->_prepareImage( $sType, $sProcessPath, $sTarget );
00521
00522
00523 if ( $oObject ) {
00524 $oObject->{$sKey}->setValue( $sValue );
00525 }
00526 }
00527 }
00528
00529
00530 $this->_removeTempImage( $sProcessPath );
00531 }
00532 }
00533 }
00534 }
00535
00536 return $oObject;
00537 }
00538
00547 function checkFile( $sFile )
00548 {
00549 $aCheckCache = oxSession::getVar("checkcache");
00550
00551 if ( isset( $aCheckCache[$sFile] ) ) {
00552 return $aCheckCache[$sFile];
00553 }
00554
00555 $blRet = false;
00556
00557 if (is_readable( $sFile)) {
00558 $blRet = true;
00559 } else {
00560
00561 $blRet = $this->urlValidate( $sFile );
00562 }
00563
00564 $aCheckCache[$sFile] = $blRet;
00565 oxSession::setVar( "checkcache", $aCheckCache );
00566
00567 return $blRet;
00568 }
00569
00577 function urlValidate( $sLink )
00578 {
00579 $aUrlParts = @parse_url( $sLink );
00580 $sHost = ( isset( $aUrlParts["host"] ) && $aUrlParts["host"] ) ? $aUrlParts["host"] : null;
00581
00582 $blValid = false;
00583 if ( $sHost ) {
00584 $sDocumentPath = ( isset( $aUrlParts["path"] ) && $aUrlParts["path"] ) ? $aUrlParts["path"] : '/';
00585 $sDocumentPath .= ( isset( $aUrlParts["query"] ) && $aUrlParts["query"] ) ? '?' . $aUrlParts["query"] : '';
00586
00587 $sPort = ( isset( $aUrlParts["port"] ) && $aUrlParts["port"] ) ? $aUrlParts["port"] : '80';
00588
00589
00590 if ( ( $oConn = @fsockopen( $sHost, $sPort, $iErrNo, $sErrStr, 30 ) ) ) {
00591 fwrite ( $oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n" );
00592 $sResponse = fgets( $oConn, 22 );
00593 fclose( $oConn );
00594
00595 if ( preg_match( "/200 OK/", $sResponse ) ) {
00596 $blValid = true;
00597 }
00598 }
00599 }
00600
00601 return $blValid;
00602 }
00603
00614 public function handleUploadedFile($aFileInfo, $sUploadPath)
00615 {
00616 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00617
00618
00619 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00620 throw new oxException( 'EXCEPTION_NOFILE' );
00621 }
00622
00623
00624 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00625 throw new oxException( 'EXCEPTION_FILENAMEINVALIDCHARS' );
00626 }
00627
00628
00629 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00630 throw new oxException( 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00631 }
00632
00633 $aPathInfo = pathinfo($aFileInfo['name']);
00634
00635 $sExt = $aPathInfo['extension'];
00636 $sFileName = $aPathInfo['filename'];
00637
00638 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00639 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00640 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00641 throw new oxException( 'EXCEPTION_NOTALLOWEDTYPE' );
00642 }
00643
00644 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00645 $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName );
00646
00647 $sUrl = $this->getConfig()->getShopUrl() . $sUploadPath . "/" . $sFileName;
00648
00649
00650 $sUrl = str_replace('//', '/', $sUrl);
00651 $sUrl = str_replace('http:/', 'http://', $sUrl);
00652
00653 return $sUrl;
00654 }
00655
00668 protected function _getUniqueFileName( $sFilePath, $sFileName, $sFileExt, $sSufix = "", $blUnique = true )
00669 {
00670 $sFilePath = $this->normalizeDir( $sFilePath );
00671 $iFileCounter = 0;
00672 $sTempFileName = $sFileName;
00673 $oStr = getStr();
00674
00675
00676 while ( $blUnique && file_exists( $sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt ) ) {
00677 $iFileCounter++;
00678
00679
00680 $sTempFileName = $oStr->preg_replace("/\(".$iFileCounter."\)/", "", $sTempFileName );
00681
00682 $sFileName = $sTempFileName . "($iFileCounter)";
00683 }
00684
00685 return $sFileName . $sSufix . "." . $sFileExt;
00686 }
00687
00695 public function getImageDirByType( $sType )
00696 {
00697 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00698
00699 return $this->normalizeDir( $sFolder );
00700 }
00701 }