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
00245 protected function _prepareImageName( $sValue, $sType, $blDemo, $sImagePath )
00246 {
00247 if ( $sValue ) {
00248
00249 $aFilename = explode( ".", $sValue );
00250 $sFileType = trim( $aFilename[count( $aFilename )-1] );
00251
00252 if ( isset( $sFileType ) ) {
00253
00254 $oStr = getStr();
00255
00256
00257 if ( in_array( $sFileType, $this->_aBadFiles ) || ( $blDemo && !in_array( $sFileType, $this->_aAllowedFiles ) ) ) {
00258 oxUtils::getInstance()->showMessageAndExit( "We don't play this game, go away" );
00259 }
00260
00261
00262 if ( count( $aFilename ) > 0 ) {
00263 unset( $aFilename[count( $aFilename )-1] );
00264 }
00265
00266 $sFName = '';
00267 if ( isset( $aFilename[0] ) ) {
00268 $sFName = $oStr->preg_replace( '/[^a-zA-Z0-9()_\.-]/', '', implode( '.', $aFilename ) );
00269 }
00270
00271
00272
00273 $sSufix = ( $oStr->preg_match( "/P\d+/", $sType ) ) ? "" : "_".strtolower( $sType );
00274
00275 $sValue = $this->_getUniqueFileName( $sImagePath, "{$sFName}", $sFileType, $sSufix );
00276 }
00277 }
00278 return $sValue;
00279 }
00280
00288 protected function _getImagePath( $sType )
00289 {
00290 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00291 $sPath = $this->normalizeDir( $this->getConfig()->getAbsDynImageDir() ) . "{$sFolder}/";
00292 return $sPath;
00293 }
00294
00305 protected function _getImageSize( $sImgType, $iImgNum, $sImgConf )
00306 {
00307 $myConfig = $this->getConfig();
00308 $sSize = false;
00309
00310 switch ( $sImgConf ) {
00311 case 'aDetailImageSizes':
00312 $aDetailImageSizes = $myConfig->getConfigParam( $sImgConf );
00313 $sSize = $myConfig->getConfigParam( 'sDetailImageSize' );
00314 if ( isset( $aDetailImageSizes['oxpic'.$iImgNum] ) ) {
00315 $sSize = $aDetailImageSizes['oxpic'.$iImgNum];
00316 }
00317 break;
00318 default:
00319 $sSize = $myConfig->getConfigParam( $sImgConf );
00320 break;
00321 }
00322 if ( $sSize ) {
00323 return explode( '*', $sSize );
00324 }
00325 }
00326
00337 protected function _prepareImage( $sType, $sSource, $sTarget )
00338 {
00339 $oUtilsPic = oxUtilspic::getInstance();
00340 $oPictureHandler = oxPictureHandler::getInstance();
00341 $oStr = getStr();
00342
00343
00344 $sPicType = $oStr->preg_replace( "/\d*$/", "", $sType );
00345
00346
00347 $iPicNum = (int) $oStr->preg_replace( "/^\D*/", "", $sType );
00348 $iPicNum = $iPicNum ? abs( $iPicNum ) : 1;
00349
00350 $aSize = false;
00351 $blResize = false;
00352
00353
00354 switch ( $sPicType ) {
00355 case 'TH':
00356 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sThumbnailsize' );
00357 break;
00358 case 'TC':
00359 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sCatThumbnailsize' );
00360 break;
00361 case 'CICO':
00362 case 'ICO':
00363 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sIconsize' );
00364 break;
00365 case 'P':
00366
00367 $iPicNum = ( $iPicNum > $this->_iMaxPicImgCount ) ? $this->_iMaxPicImgCount : $iPicNum;
00368
00369
00370 if ( ( $aSize = $this->_getImageSize( $sType, 1, 'sIconsize' ) ) ) {
00371 $sIconTarget = dirname($sTarget) . '/' . $oPictureHandler->getIconName( $sTarget );
00372 $oUtilsPic->resizeImage( $sSource, $sIconTarget, $aSize[0], $aSize[1] );
00373 }
00374
00375 $aSize = $this->_getImageSize( $sType, $iPicNum, 'aDetailImageSizes' );
00376 break;
00377 case 'M':
00378 case 'WP':
00379 case 'FL':
00380
00381 $this->_copyFile($sSource, $sTarget);
00382 break;
00383 case 'Z':
00384 $aSize = $this->_getImageSize( $sType, $iPicNum, 'sZoomImageSize' );
00385 break;
00386 }
00387
00388 if ( $aSize ) {
00389 $blResize = $oUtilsPic->resizeImage( $sSource, $sTarget, $aSize[0], $aSize[1] );
00390 }
00391 return $blResize;
00392 }
00393
00402 protected function _copyFile( $sSource, $sTarget )
00403 {
00404 $blDone = false;
00405
00406 if ( $sSource === $sTarget ) {
00407 $blDone = true;
00408 } else {
00409 $blDone = copy( $sSource, $sTarget );
00410 }
00411
00412 if ( $blDone ) {
00413 $blDone = @chmod( $sTarget, 0644 );
00414 }
00415
00416 return $blDone;
00417 }
00418
00427 protected function _moveImage( $sSource, $sTarget )
00428 {
00429 $blDone = false;
00430
00431 if ( $sSource === $sTarget ) {
00432 $blDone = true;
00433 } else {
00434 $blDone = move_uploaded_file( $sSource, $sTarget );
00435 }
00436
00437 if ( $blDone ) {
00438 $blDone = @chmod( $sTarget, 0644 );
00439 }
00440
00441 return $blDone;
00442 }
00443
00451 protected function _removeTempImage( $sImagePath )
00452 {
00453 return unlink( $sImagePath );
00454 }
00455
00466 public function processFiles( $oObject = null, $aFiles = array(), $blUseMasterImage = false )
00467 {
00468 $aFiles = $aFiles ? $aFiles : $_FILES;
00469 if ( isset( $aFiles['myfile']['name'] ) ) {
00470
00471 $oConfig = $this->getConfig();
00472 $oStr = getStr();
00473
00474
00475 $blDemo = (bool) $oConfig->isDemoShop();
00476
00477
00478 $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00479
00480
00481 while ( list( $sKey, $sValue ) = each( $aFiles['myfile']['name'] ) ) {
00482
00483 $aSource = $aFiles['myfile']['tmp_name'];
00484 $sSource = $aSource[$sKey];
00485 $aFiletype = explode( "@", $sKey );
00486 $sKey = $aFiletype[1];
00487 $sType = $aFiletype[0];
00488
00489
00490
00491
00492
00493 if ( $oStr->preg_match("/(M)(\d+)/", $sType, $aMatches ) ) {
00494 $sMasterImageType = "P" . $aMatches[2];
00495 }
00496
00497 $sValue = strtolower( $sValue );
00498 $sImagePath = $this->_getImagePath( $sType );
00499
00500 $sImageNameType = ( $sMasterImageType ) ? $sMasterImageType : $sType;
00501
00502
00503 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sImageNameType, $blDemo, $sImagePath ) ) ) {
00504
00505
00506 $sProcessPath = $sTmpFolder . basename( $sSource );
00507 if ( $sProcessPath ) {
00508
00509 if ( $blUseMasterImage ) {
00510
00511
00512 $blMoved = $this->_copyFile( $sSource, $sProcessPath );
00513 } else {
00514 $blMoved = $this->_moveImage( $sSource, $sProcessPath );
00515 }
00516
00517 if ( $blMoved ) {
00518
00519 if ( ( $sTarget = $sImagePath . $sValue ) ) {
00520
00521 $this->_prepareImage( $sType, $sProcessPath, $sTarget );
00522
00523
00524 if ( $oObject ) {
00525 $oObject->{$sKey}->setValue( $sValue );
00526 }
00527 }
00528 }
00529
00530
00531 $this->_removeTempImage( $sProcessPath );
00532 }
00533 }
00534 }
00535 }
00536
00537 return $oObject;
00538 }
00539
00548 function checkFile( $sFile )
00549 {
00550 $aCheckCache = oxSession::getVar("checkcache");
00551
00552 if ( isset( $aCheckCache[$sFile] ) ) {
00553 return $aCheckCache[$sFile];
00554 }
00555
00556 $blRet = false;
00557
00558 if (is_readable( $sFile)) {
00559 $blRet = true;
00560 } else {
00561
00562 $blRet = $this->urlValidate( $sFile );
00563 }
00564
00565 $aCheckCache[$sFile] = $blRet;
00566 oxSession::setVar( "checkcache", $aCheckCache );
00567
00568 return $blRet;
00569 }
00570
00578 function urlValidate( $sLink )
00579 {
00580 $aUrlParts = @parse_url( $sLink );
00581 $sHost = ( isset( $aUrlParts["host"] ) && $aUrlParts["host"] ) ? $aUrlParts["host"] : null;
00582
00583 $blValid = false;
00584 if ( $sHost ) {
00585 $sDocumentPath = ( isset( $aUrlParts["path"] ) && $aUrlParts["path"] ) ? $aUrlParts["path"] : '/';
00586 $sDocumentPath .= ( isset( $aUrlParts["query"] ) && $aUrlParts["query"] ) ? '?' . $aUrlParts["query"] : '';
00587
00588 $sPort = ( isset( $aUrlParts["port"] ) && $aUrlParts["port"] ) ? $aUrlParts["port"] : '80';
00589
00590
00591 if ( ( $oConn = @fsockopen( $sHost, $sPort, $iErrNo, $sErrStr, 30 ) ) ) {
00592 fwrite ( $oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n" );
00593 $sResponse = fgets( $oConn, 22 );
00594 fclose( $oConn );
00595
00596 if ( preg_match( "/200 OK/", $sResponse ) ) {
00597 $blValid = true;
00598 }
00599 }
00600 }
00601
00602 return $blValid;
00603 }
00604
00615 public function handleUploadedFile($aFileInfo, $sUploadPath)
00616 {
00617 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00618
00619
00620 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00621 throw new oxException( 'EXCEPTION_NOFILE' );
00622 }
00623
00624
00625 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00626 throw new oxException( 'EXCEPTION_FILENAMEINVALIDCHARS' );
00627 }
00628
00629
00630 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00631 throw new oxException( 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00632 }
00633
00634 $aPathInfo = pathinfo($aFileInfo['name']);
00635
00636 $sExt = $aPathInfo['extension'];
00637 $sFileName = $aPathInfo['filename'];
00638
00639 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00640 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00641 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00642 throw new oxException( 'EXCEPTION_NOTALLOWEDTYPE' );
00643 }
00644
00645 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00646 $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName );
00647
00648 $sUrl = $this->getConfig()->getShopUrl() . $sUploadPath . "/" . $sFileName;
00649
00650
00651 $sUrl = str_replace('//', '/', $sUrl);
00652 $sUrl = str_replace('http:/', 'http://', $sUrl);
00653
00654 return $sUrl;
00655 }
00656
00668 protected function _getUniqueFileName( $sFilePath, $sFileName, $sFileExt, $sSufix = "" )
00669 {
00670 $sFilePath = $this->normalizeDir( $sFilePath );
00671 $iFileCounter = 0;
00672 $sTempFileName = $sFileName;
00673 $oStr = getStr();
00674
00675
00676 while ( 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 }