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
00119 public static function getInstance()
00120 {
00121 return oxRegistry::get("oxUtilsFile");
00122 }
00123
00129 public function __construct()
00130 {
00131 $myConfig = $this->getConfig();
00132
00133 if ( $iPicCount = $myConfig->getConfigParam( 'iPicCount' ) ) {
00134 $this->_iMaxPicImgCount = $iPicCount;
00135 }
00136
00137 $this->_iMaxZoomImgCount = $this->_iMaxPicImgCount;
00138 }
00139
00145 public function getNewFilesCounter()
00146 {
00147 return $this->_iNewFilesCounter;
00148 }
00149
00157 protected function _setNewFilesCounter( $iNewFilesCounter )
00158 {
00159 $this->_iNewFilesCounter = (int) $iNewFilesCounter;
00160 }
00161
00169 public function normalizeDir( $sDir )
00170 {
00171 if ( isset($sDir) && $sDir != "" && substr($sDir, -1) !== '/' ) {
00172 $sDir .= "/";
00173 }
00174
00175 return $sDir;
00176 }
00177
00186 public function copyDir( $sSourceDir, $sTargetDir )
00187 {
00188 $oStr = getStr();
00189 $handle = opendir( $sSourceDir );
00190 while ( false !== ( $file = readdir( $handle ) ) ) {
00191 if ( $file != '.' && $file != '..' ) {
00192 if ( is_dir( $sSourceDir.'/'.$file ) ) {
00193
00194
00195 $sNewSourceDir = $sSourceDir.'/'.$file;
00196 $sNewTargetDir = $sTargetDir.'/'.$file;
00197 if ( strcasecmp( $file, 'CVS' ) && strcasecmp( $file, '.svn' )) {
00198 @mkdir( $sNewTargetDir, 0777 );
00199 $this->copyDir( $sNewSourceDir, $sNewTargetDir );
00200 }
00201 } else {
00202 $sSourceFile = $sSourceDir.'/'.$file;
00203 $sTargetFile = $sTargetDir.'/'.$file;
00204
00205
00206 if ( !$oStr->strstr( $sSourceDir, 'dyn_images' ) || $file == 'nopic.jpg' || $file == 'nopic_ico.jpg' ) {
00207 @copy( $sSourceFile, $sTargetFile );
00208 }
00209 }
00210 }
00211 }
00212 closedir($handle);
00213 }
00214
00222 public function deleteDir( $sSourceDir )
00223 {
00224 if ( is_dir( $sSourceDir ) ) {
00225 if ( $oDir = dir( $sSourceDir ) ) {
00226
00227 while ( false !== $sFile = $oDir->read() ) {
00228 if ( $sFile == '.' || $sFile == '..' ) {
00229 continue;
00230 }
00231
00232 if ( !$this->deleteDir( $oDir->path . DIRECTORY_SEPARATOR . $sFile ) ) {
00233 $oDir->close();
00234 return false;
00235 }
00236 }
00237
00238 $oDir->close();
00239 return rmdir( $sSourceDir );
00240 }
00241 } elseif ( file_exists( $sSourceDir ) ) {
00242 return unlink ( $sSourceDir );
00243 }
00244 }
00245
00253 public function readRemoteFileAsString( $sPath )
00254 {
00255 $sRet = '';
00256 $hFile = @fopen( $sPath, 'r' );
00257 if ( $hFile ) {
00258 socket_set_timeout( $hFile, 2 );
00259 while ( !feof( $hFile ) ) {
00260 $sLine = fgets( $hFile, 4096 );
00261 $sRet .= $sLine;
00262 }
00263 fclose( $hFile );
00264 }
00265
00266 return $sRet;
00267 }
00268
00280 protected function _prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique = true )
00281 {
00282 if ( $sValue ) {
00283
00284 $aFilename = explode( ".", $sValue );
00285
00286 $sFileType = trim( $aFilename[count( $aFilename )-1] );
00287
00288 if ( isset( $sFileType ) ) {
00289
00290 $oStr = getStr();
00291
00292
00293 if ( in_array( $sFileType, $this->_aBadFiles ) || ( $blDemo && !in_array( $sFileType, $this->_aAllowedFiles ) ) ) {
00294 oxRegistry::getUtils()->showMessageAndExit( "We don't play this game, go away" );
00295 }
00296
00297
00298 if ( count( $aFilename ) > 0 ) {
00299 unset( $aFilename[count( $aFilename )-1] );
00300 }
00301
00302 $sFName = '';
00303 if ( isset( $aFilename[0] ) ) {
00304 $sFName = $oStr->preg_replace( '/[^a-zA-Z0-9()_\.-]/', '', implode( '.', $aFilename ) );
00305 }
00306
00307 $sValue = $this->_getUniqueFileName( $sImagePath, "{$sFName}", $sFileType, "", $blUnique );
00308 }
00309 }
00310 return $sValue;
00311 }
00312
00320 protected function _getImagePath( $sType )
00321 {
00322 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00323 $sPath = $this->normalizeDir( $this->getConfig()->getPictureDir(false) ) . "{$sFolder}/";
00324 return $sPath;
00325 }
00326
00337 protected function _getImageSize( $sImgType, $iImgNum, $sImgConf )
00338 {
00339 $myConfig = $this->getConfig();
00340 $sSize = false;
00341
00342 switch ( $sImgConf ) {
00343 case 'aDetailImageSizes':
00344 $aDetailImageSizes = $myConfig->getConfigParam( $sImgConf );
00345 $sSize = $myConfig->getConfigParam( 'sDetailImageSize' );
00346 if ( isset( $aDetailImageSizes['oxpic'.$iImgNum] ) ) {
00347 $sSize = $aDetailImageSizes['oxpic'.$iImgNum];
00348 }
00349 break;
00350 default:
00351 $sSize = $myConfig->getConfigParam( $sImgConf );
00352 break;
00353 }
00354 if ( $sSize ) {
00355 return explode( '*', $sSize );
00356 }
00357 }
00358
00367 protected function _copyFile( $sSource, $sTarget )
00368 {
00369 $blDone = false;
00370
00371 if ( $sSource === $sTarget ) {
00372 $blDone = true;
00373 } else {
00374 $blDone = copy( $sSource, $sTarget );
00375 }
00376
00377 if ( $blDone ) {
00378 $blDone = @chmod( $sTarget, 0644 );
00379 }
00380
00381 return $blDone;
00382 }
00383
00392 protected function _moveImage( $sSource, $sTarget )
00393 {
00394 $blDone = false;
00395 if ( !is_dir( dirname( $sTarget ) ) ) {
00396 mkdir(dirname($sTarget), 0744, true);
00397 }
00398 if ( $sSource === $sTarget ) {
00399 $blDone = true;
00400 } else {
00401 $blDone = move_uploaded_file( $sSource, $sTarget );
00402 }
00403
00404 if ( $blDone ) {
00405 $blDone = @chmod( $sTarget, 0644 );
00406 }
00407
00408 return $blDone;
00409 }
00410
00422 public function processFiles( $oObject = null, $aFiles = array(), $blUseMasterImage = false, $blUnique = true )
00423 {
00424 $aFiles = $aFiles ? $aFiles : $_FILES;
00425 if ( isset( $aFiles['myfile']['name'] ) ) {
00426
00427 $oConfig = $this->getConfig();
00428 $oStr = getStr();
00429
00430
00431 $blDemo = (bool) $oConfig->isDemoShop();
00432
00433
00434 $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00435
00436 $iNewFilesCounter = 0;
00437 $aSource = $aFiles['myfile']['tmp_name'];
00438 $aError = $aFiles['myfile']['error'];
00439 $sErrorsDescription = '';
00440
00441 $oEx = oxNew( "oxExceptionToDisplay" );
00442
00443 while ( list( $sKey, $sValue ) = each( $aFiles['myfile']['name'] ) ) {
00444
00445 $sSource = $aSource[$sKey];
00446 $iError = $aError[$sKey];
00447 $aFiletype = explode( "@", $sKey );
00448 $sKey = $aFiletype[1];
00449 $sType = $aFiletype[0];
00450
00451 $sValue = strtolower( $sValue );
00452 $sImagePath = $this->_getImagePath( $sType );
00453
00454
00455 if ( UPLOAD_ERR_OK !== $iError && UPLOAD_ERR_NO_FILE !== $iError ) {
00456 $sErrorsDescription = $this->translateError( $iError );
00457 $oEx->setMessage( $sErrorsDescription );
00458 oxRegistry::get("oxUtilsView")->addErrorToDisplay( $oEx, false );
00459 }
00460
00461
00462 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique ) ) ) {
00463
00464
00465 $sProcessPath = $sTmpFolder . basename( $sSource );
00466
00467 if ( $sProcessPath ) {
00468
00469 if ( $blUseMasterImage ) {
00470
00471 $blMoved = $this->_copyFile( $sSource, $sImagePath . $sValue );
00472 } else {
00473 $blMoved = $this->_moveImage( $sSource, $sImagePath . $sValue );
00474 }
00475
00476 if ( $blMoved ) {
00477
00478 $iNewFilesCounter++;
00479
00480 if ( $oObject && isset( $oObject->$sKey ) ) {
00481 $oObject->{$sKey}->setValue( $sValue );
00482 }
00483 }
00484 }
00485 }
00486 }
00487
00488 $this->_setNewFilesCounter( $iNewFilesCounter );
00489 }
00490
00491 return $oObject;
00492 }
00493
00502 function checkFile( $sFile )
00503 {
00504 $aCheckCache = oxSession::getVar("checkcache");
00505
00506 if ( isset( $aCheckCache[$sFile] ) ) {
00507 return $aCheckCache[$sFile];
00508 }
00509
00510 $blRet = false;
00511
00512 if (is_readable( $sFile)) {
00513 $blRet = true;
00514 } else {
00515
00516 $blRet = $this->urlValidate( $sFile );
00517 }
00518
00519 $aCheckCache[$sFile] = $blRet;
00520 oxSession::setVar( "checkcache", $aCheckCache );
00521
00522 return $blRet;
00523 }
00524
00532 function urlValidate( $sLink )
00533 {
00534 $aUrlParts = @parse_url( $sLink );
00535 $sHost = ( isset( $aUrlParts["host"] ) && $aUrlParts["host"] ) ? $aUrlParts["host"] : null;
00536
00537 $blValid = false;
00538 if ( $sHost ) {
00539 $sDocumentPath = ( isset( $aUrlParts["path"] ) && $aUrlParts["path"] ) ? $aUrlParts["path"] : '/';
00540 $sDocumentPath .= ( isset( $aUrlParts["query"] ) && $aUrlParts["query"] ) ? '?' . $aUrlParts["query"] : '';
00541
00542 $sPort = ( isset( $aUrlParts["port"] ) && $aUrlParts["port"] ) ? $aUrlParts["port"] : '80';
00543
00544
00545 if ( ( $oConn = @fsockopen( $sHost, $sPort, $iErrNo, $sErrStr, 30 ) ) ) {
00546 fwrite ( $oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n" );
00547 $sResponse = fgets( $oConn, 22 );
00548 fclose( $oConn );
00549
00550 if ( preg_match( "/200 OK/", $sResponse ) ) {
00551 $blValid = true;
00552 }
00553 }
00554 }
00555
00556 return $blValid;
00557 }
00558
00569 public function processFile( $sFileName, $sUploadPath )
00570 {
00571 $aFileInfo = $_FILES[$sFileName];
00572
00573 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00574
00575
00576 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00577 throw oxNew( "oxException", 'EXCEPTION_NOFILE' );
00578 }
00579
00580
00581 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00582 throw oxNew( "oxException", 'EXCEPTION_FILENAMEINVALIDCHARS' );
00583 }
00584
00585
00586 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00587 throw oxNew( "oxException", 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00588 }
00589
00590 $aPathInfo = pathinfo($aFileInfo['name']);
00591
00592 $sExt = $aPathInfo['extension'];
00593 $sFileName = $aPathInfo['filename'];
00594
00595 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00596 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00597
00598 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00599 throw oxNew( "oxException", 'EXCEPTION_NOTALLOWEDTYPE' );
00600 }
00601
00602 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00603
00604 if ( $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName ) ) {
00605 return $sFileName ;
00606 } else {
00607 return false;
00608 }
00609 }
00610
00623 protected function _getUniqueFileName( $sFilePath, $sFileName, $sFileExt, $sSufix = "", $blUnique = true )
00624 {
00625 $sFilePath = $this->normalizeDir( $sFilePath );
00626 $iFileCounter = 0;
00627 $sTempFileName = $sFileName;
00628 $oStr = getStr();
00629
00630
00631 while ( $blUnique && file_exists( $sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt ) ) {
00632 $iFileCounter++;
00633
00634
00635 $sTempFileName = $oStr->preg_replace("/\(".$iFileCounter."\)/", "", $sTempFileName );
00636
00637 $sFileName = $sTempFileName . "($iFileCounter)";
00638 }
00639
00640 return $sFileName . $sSufix . "." . $sFileExt;
00641 }
00642
00651 public function getImageDirByType( $sType, $blGenerated = false )
00652 {
00653 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00654 $sDir = $this->normalizeDir( $sFolder );
00655
00656 if ($blGenerated === true) {
00657 $sDir = str_replace('master/', 'generated/', $sDir);
00658 }
00659
00660 return $sDir;
00661 }
00662
00670 function translateError( $iError )
00671 {
00672 $message = '';
00673
00674 if ( $iError > 0 && $iError < 9 && 5 !== $iError ) {
00675 $message = 'EXCEPTION_FILEUPLOADERROR_'.( (int) $iError );
00676 }
00677
00678 return $message;
00679 }
00680
00681 }