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
00093 protected $_aBadFiles = array( 'php', 'jsp', 'cgi', 'cmf', 'exe' );
00094
00100 protected $_aAllowedFiles = array( 'gif', 'jpg', 'png', 'pdf' );
00106 public static function getInstance()
00107 {
00108
00109 if ( defined( 'OXID_PHP_UNIT' ) ) {
00110 self::$_instance = modInstances::getMod( __CLASS__ );
00111 }
00112
00113 if ( !self::$_instance instanceof oxUtilsFile ) {
00114
00115 self::$_instance = oxNew( 'oxUtilsFile' );
00116 if ( defined( 'OXID_PHP_UNIT' ) ) {
00117 modInstances::addMod( __CLASS__, self::$_instance);
00118 }
00119 }
00120 return self::$_instance;
00121 }
00122
00128 public function __construct()
00129 {
00130 $myConfig = $this->getConfig();
00131
00132 if ( $iPicCount = $myConfig->getConfigParam( 'iPicCount' ) ) {
00133 $this->_iMaxPicImgCount = $iPicCount;
00134 }
00135
00136 $this->_iMaxZoomImgCount = $this->_iMaxPicImgCount;
00137 }
00138
00146 public function normalizeDir( $sDir )
00147 {
00148 if ( isset($sDir) && $sDir != "" && substr($sDir, -1) !== '/' ) {
00149 $sDir .= "/";
00150 }
00151
00152 return $sDir;
00153 }
00154
00163 public function copyDir( $sSourceDir, $sTargetDir )
00164 {
00165 $oStr = getStr();
00166 $handle = opendir( $sSourceDir );
00167 while ( false !== ( $file = readdir( $handle ) ) ) {
00168 if ( $file != '.' && $file != '..' ) {
00169 if ( is_dir( $sSourceDir.'/'.$file ) ) {
00170
00171
00172 $sNewSourceDir = $sSourceDir.'/'.$file;
00173 $sNewTargetDir = $sTargetDir.'/'.$file;
00174 if ( strcasecmp( $file, 'CVS' ) && strcasecmp( $file, '.svn' )) {
00175 @mkdir( $sNewTargetDir, 0777 );
00176 $this->copyDir( $sNewSourceDir, $sNewTargetDir );
00177 }
00178 } else {
00179 $sSourceFile = $sSourceDir.'/'.$file;
00180 $sTargetFile = $sTargetDir.'/'.$file;
00181
00182
00183 if ( !$oStr->strstr( $sSourceDir, 'dyn_images' ) || $file == 'nopic.jpg' || $file == 'nopic_ico.jpg' ) {
00184 @copy( $sSourceFile, $sTargetFile );
00185 }
00186 }
00187 }
00188 }
00189 closedir($handle);
00190 }
00191
00199 public function deleteDir( $sSourceDir )
00200 {
00201 if ( is_dir( $sSourceDir ) ) {
00202 if ( $oDir = dir( $sSourceDir ) ) {
00203
00204 while ( false !== $sFile = $oDir->read() ) {
00205 if ( $sFile == '.' || $sFile == '..' ) {
00206 continue;
00207 }
00208
00209 if ( !$this->deleteDir( $oDir->path . DIRECTORY_SEPARATOR . $sFile ) ) {
00210 $oDir->close();
00211 return false;
00212 }
00213 }
00214
00215 $oDir->close();
00216 return rmdir( $sSourceDir );
00217 }
00218 } elseif ( file_exists( $sSourceDir ) ) {
00219 return unlink ( $sSourceDir );
00220 }
00221 }
00222
00230 public function readRemoteFileAsString( $sPath )
00231 {
00232 $sRet = '';
00233 $hFile = @fopen( $sPath, 'r' );
00234 if ( $hFile ) {
00235 socket_set_timeout( $hFile, 2 );
00236 while ( !feof( $hFile ) ) {
00237 $sLine = fgets( $hFile, 4096 );
00238 $sRet .= $sLine;
00239 }
00240 fclose( $hFile );
00241 }
00242
00243 return $sRet;
00244 }
00245
00257 protected function _prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique = true )
00258 {
00259 if ( $sValue ) {
00260
00261 $aFilename = explode( ".", $sValue );
00262
00263 $sFileType = trim( $aFilename[count( $aFilename )-1] );
00264
00265 if ( isset( $sFileType ) ) {
00266
00267 $oStr = getStr();
00268
00269
00270 if ( in_array( $sFileType, $this->_aBadFiles ) || ( $blDemo && !in_array( $sFileType, $this->_aAllowedFiles ) ) ) {
00271 oxUtils::getInstance()->showMessageAndExit( "We don't play this game, go away" );
00272 }
00273
00274
00275 if ( count( $aFilename ) > 0 ) {
00276 unset( $aFilename[count( $aFilename )-1] );
00277 }
00278
00279 $sFName = '';
00280 if ( isset( $aFilename[0] ) ) {
00281 $sFName = $oStr->preg_replace( '/[^a-zA-Z0-9()_\.-]/', '', implode( '.', $aFilename ) );
00282 }
00283
00284 $sValue = $this->_getUniqueFileName( $sImagePath, "{$sFName}", $sFileType, "", $blUnique );
00285 }
00286 }
00287 return $sValue;
00288 }
00289
00297 protected function _getImagePath( $sType )
00298 {
00299 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00300 $sPath = $this->normalizeDir( $this->getConfig()->getPictureDir(false) ) . "{$sFolder}/";
00301 return $sPath;
00302 }
00303
00314 protected function _getImageSize( $sImgType, $iImgNum, $sImgConf )
00315 {
00316 $myConfig = $this->getConfig();
00317 $sSize = false;
00318
00319 switch ( $sImgConf ) {
00320 case 'aDetailImageSizes':
00321 $aDetailImageSizes = $myConfig->getConfigParam( $sImgConf );
00322 $sSize = $myConfig->getConfigParam( 'sDetailImageSize' );
00323 if ( isset( $aDetailImageSizes['oxpic'.$iImgNum] ) ) {
00324 $sSize = $aDetailImageSizes['oxpic'.$iImgNum];
00325 }
00326 break;
00327 default:
00328 $sSize = $myConfig->getConfigParam( $sImgConf );
00329 break;
00330 }
00331 if ( $sSize ) {
00332 return explode( '*', $sSize );
00333 }
00334 }
00335
00344 protected function _copyFile( $sSource, $sTarget )
00345 {
00346 $blDone = false;
00347
00348 if ( $sSource === $sTarget ) {
00349 $blDone = true;
00350 } else {
00351 $blDone = copy( $sSource, $sTarget );
00352 }
00353
00354 if ( $blDone ) {
00355 $blDone = @chmod( $sTarget, 0644 );
00356 }
00357
00358 return $blDone;
00359 }
00360
00369 protected function _moveImage( $sSource, $sTarget )
00370 {
00371 $blDone = false;
00372
00373 if ( $sSource === $sTarget ) {
00374 $blDone = true;
00375 } else {
00376 $blDone = move_uploaded_file( $sSource, $sTarget );
00377 }
00378
00379 if ( $blDone ) {
00380 $blDone = @chmod( $sTarget, 0644 );
00381 }
00382
00383 return $blDone;
00384 }
00385
00397 public function processFiles( $oObject = null, $aFiles = array(), $blUseMasterImage = false, $blUnique = true )
00398 {
00399 $aFiles = $aFiles ? $aFiles : $_FILES;
00400 if ( isset( $aFiles['myfile']['name'] ) ) {
00401
00402 $oConfig = $this->getConfig();
00403 $oStr = getStr();
00404
00405
00406 $blDemo = (bool) $oConfig->isDemoShop();
00407
00408
00409 $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00410
00411
00412 while ( list( $sKey, $sValue ) = each( $aFiles['myfile']['name'] ) ) {
00413
00414 $aSource = $aFiles['myfile']['tmp_name'];
00415 $sSource = $aSource[$sKey];
00416 $aFiletype = explode( "@", $sKey );
00417 $sKey = $aFiletype[1];
00418 $sType = $aFiletype[0];
00419
00420 $sValue = strtolower( $sValue );
00421 $sImagePath = $this->_getImagePath( $sType );
00422
00423
00424 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sType, $blDemo, $sImagePath, $blUnique ) ) ) {
00425
00426
00427 $sProcessPath = $sTmpFolder . basename( $sSource );
00428
00429 if ( $sProcessPath ) {
00430
00431 if ( $blUseMasterImage ) {
00432
00433 $blMoved = $this->_copyFile( $sSource, $sImagePath . $sValue );
00434 } else {
00435 $blMoved = $this->_moveImage( $sSource, $sImagePath . $sValue );
00436 }
00437
00438 if ( $blMoved ) {
00439
00440 if ( $oObject && isset( $oObject->$sKey ) ) {
00441 $oObject->{$sKey}->setValue( $sValue );
00442 }
00443 }
00444 }
00445 }
00446 }
00447 }
00448
00449 return $oObject;
00450 }
00451
00460 function checkFile( $sFile )
00461 {
00462 $aCheckCache = oxSession::getVar("checkcache");
00463
00464 if ( isset( $aCheckCache[$sFile] ) ) {
00465 return $aCheckCache[$sFile];
00466 }
00467
00468 $blRet = false;
00469
00470 if (is_readable( $sFile)) {
00471 $blRet = true;
00472 } else {
00473
00474 $blRet = $this->urlValidate( $sFile );
00475 }
00476
00477 $aCheckCache[$sFile] = $blRet;
00478 oxSession::setVar( "checkcache", $aCheckCache );
00479
00480 return $blRet;
00481 }
00482
00490 function urlValidate( $sLink )
00491 {
00492 $aUrlParts = @parse_url( $sLink );
00493 $sHost = ( isset( $aUrlParts["host"] ) && $aUrlParts["host"] ) ? $aUrlParts["host"] : null;
00494
00495 $blValid = false;
00496 if ( $sHost ) {
00497 $sDocumentPath = ( isset( $aUrlParts["path"] ) && $aUrlParts["path"] ) ? $aUrlParts["path"] : '/';
00498 $sDocumentPath .= ( isset( $aUrlParts["query"] ) && $aUrlParts["query"] ) ? '?' . $aUrlParts["query"] : '';
00499
00500 $sPort = ( isset( $aUrlParts["port"] ) && $aUrlParts["port"] ) ? $aUrlParts["port"] : '80';
00501
00502
00503 if ( ( $oConn = @fsockopen( $sHost, $sPort, $iErrNo, $sErrStr, 30 ) ) ) {
00504 fwrite ( $oConn, "HEAD {$sDocumentPath} HTTP/1.0\r\nHost: {$sHost}\r\n\r\n" );
00505 $sResponse = fgets( $oConn, 22 );
00506 fclose( $oConn );
00507
00508 if ( preg_match( "/200 OK/", $sResponse ) ) {
00509 $blValid = true;
00510 }
00511 }
00512 }
00513
00514 return $blValid;
00515 }
00516
00529 public function handleUploadedFile($aFileInfo, $sUploadPath)
00530 {
00531 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00532
00533
00534 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00535 throw new oxException( 'EXCEPTION_NOFILE' );
00536 }
00537
00538
00539 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00540 throw new oxException( 'EXCEPTION_FILENAMEINVALIDCHARS' );
00541 }
00542
00543
00544 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00545 throw new oxException( 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00546 }
00547
00548 $aPathInfo = pathinfo($aFileInfo['name']);
00549
00550 $sExt = $aPathInfo['extension'];
00551 $sFileName = $aPathInfo['filename'];
00552
00553 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00554 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00555 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00556 throw new oxException( 'EXCEPTION_NOTALLOWEDTYPE' );
00557 }
00558
00559 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00560 $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName );
00561
00562 $sUrl = $this->getConfig()->getShopUrl() . $sUploadPath . "/" . $sFileName;
00563
00564
00565 $sUrl = str_replace('//', '/', $sUrl);
00566 $sUrl = str_replace(array('http:/', 'https:/'), array('http://', 'https://'), $sUrl);
00567
00568 return $sUrl;
00569 }
00570
00581 public function processFile( $sFileName, $sUploadPath )
00582 {
00583 $aFileInfo = $_FILES[$sFileName];
00584
00585 $sBasePath = $this->getConfig()->getConfigParam('sShopDir');
00586
00587
00588 if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00589 throw new oxException( 'EXCEPTION_NOFILE' );
00590 }
00591
00592
00593 if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00594 throw new oxException( 'EXCEPTION_FILENAMEINVALIDCHARS' );
00595 }
00596
00597
00598 if ( isset( $aFileInfo['error'] ) && $aFileInfo['error'] ) {
00599 throw new oxException( 'EXCEPTION_FILEUPLOADERROR_'.( (int) $aFileInfo['error'] ) );
00600 }
00601
00602 $aPathInfo = pathinfo($aFileInfo['name']);
00603
00604 $sExt = $aPathInfo['extension'];
00605 $sFileName = $aPathInfo['filename'];
00606
00607 $aAllowedUploadTypes = (array) $this->getConfig()->getConfigParam( 'aAllowedUploadTypes' );
00608 $aAllowedUploadTypes = array_map( "strtolower", $aAllowedUploadTypes );
00609
00610 if ( !in_array( strtolower( $sExt ), $aAllowedUploadTypes ) ) {
00611 throw new oxException( 'EXCEPTION_NOTALLOWEDTYPE' );
00612 }
00613
00614 $sFileName = $this->_getUniqueFileName( $sBasePath . $sUploadPath, $sFileName, $sExt );
00615
00616 if ( $this->_moveImage( $aFileInfo['tmp_name'], $sBasePath . $sUploadPath . "/" . $sFileName ) ) {
00617 return $sFileName ;
00618 } else {
00619 return false;
00620 }
00621 }
00622
00635 protected function _getUniqueFileName( $sFilePath, $sFileName, $sFileExt, $sSufix = "", $blUnique = true )
00636 {
00637 $sFilePath = $this->normalizeDir( $sFilePath );
00638 $iFileCounter = 0;
00639 $sTempFileName = $sFileName;
00640 $oStr = getStr();
00641
00642
00643 while ( $blUnique && file_exists( $sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt ) ) {
00644 $iFileCounter++;
00645
00646
00647 $sTempFileName = $oStr->preg_replace("/\(".$iFileCounter."\)/", "", $sTempFileName );
00648
00649 $sFileName = $sTempFileName . "($iFileCounter)";
00650 }
00651
00652 return $sFileName . $sSufix . "." . $sFileExt;
00653 }
00654
00662 public function getImageDirByType( $sType )
00663 {
00664 $sFolder = array_key_exists( $sType, $this->_aTypeToPath ) ? $this->_aTypeToPath[ $sType ] : '0';
00665 return $this->normalizeDir( $sFolder );
00666 }
00667 }