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