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