oxutilsfile.php

Go to the documentation of this file.
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         // disable caching for test modules
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                     // recursive
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                     //do not copy files within dyn_images
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             // add type to name
00249             $aFilename = explode( ".", $sValue );
00250             $sFileType = trim( $aFilename[count( $aFilename )-1] );
00251 
00252             if ( isset( $sFileType ) ) {
00253 
00254                 $oStr = getStr();
00255 
00256                 // unallowed files ?
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                 // removing file type
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                 // removing sufix from main pictures, only zoom pictures, thumbnails
00272                 // and icons will have it.
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         // picture type
00344         $sPicType = $oStr->preg_replace( "/\d*$/", "", $sType );
00345 
00346         // numper of processable picture
00347         $iPicNum  = (int) $oStr->preg_replace( "/^\D*/", "", $sType );
00348         $iPicNum = $iPicNum ? abs( $iPicNum ) : 1;
00349 
00350         $aSize = false;
00351         $blResize = false;
00352 
00353         // add file process here
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                 // pictures count is limited to 12
00367                 $iPicNum = ( $iPicNum > $this->_iMaxPicImgCount ) ? $this->_iMaxPicImgCount : $iPicNum;
00368 
00369                 //make an icon
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                 // just copy non image file to target folder
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             // A. protection for demoshops - strictly defining allowed file extensions
00475             $blDemo = (bool) $oConfig->isDemoShop();
00476 
00477             // folder where images will be processed
00478             $sTmpFolder = $oConfig->getConfigParam( "sCompileDir" );
00479 
00480             // process all files
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                 //if uplading master image, master image name will be with
00491                 //sufics "p" (eg. image_p1.jpg). This is because of compatibility
00492                 //with previous versions
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                 // checking file type and building final file name
00503                 if ( $sSource && ( $sValue = $this->_prepareImageName( $sValue, $sImageNameType, $blDemo, $sImagePath ) ) ) {
00504                     // moving to tmp folder for processing as safe mode or spec. open_basedir setup
00505                     // usually does not allow file modification in php's temp folder
00506                     $sProcessPath = $sTmpFolder . basename( $sSource );
00507                     if ( $sProcessPath ) {
00508 
00509                         if ( $blUseMasterImage ) {
00510                             //using master image as source, so only copying it to
00511                             //temp dir for processing
00512                             $blMoved = $this->_copyFile( $sSource, $sProcessPath );
00513                         } else {
00514                             $blMoved = $this->_moveImage( $sSource, $sProcessPath );
00515                         }
00516 
00517                         if ( $blMoved ) {
00518                             // finding final image path
00519                             if ( ( $sTarget = $sImagePath . $sValue ) ) {
00520                                 // processing image and moving to final location
00521                                 $this->_prepareImage( $sType, $sProcessPath, $sTarget );
00522 
00523                                 // assign the name
00524                                 if ( $oObject ) {
00525                                     $oObject->{$sKey}->setValue( $sValue );
00526                                 }
00527                             }
00528                         }
00529 
00530                         // removing temporary file
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             // try again via socket
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             // Now (HTTP-)GET $documentpath at $sHost";
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         //checking params
00620         if ( !isset( $aFileInfo['name'] ) || !isset( $aFileInfo['tmp_name'] ) ) {
00621             throw new oxException( 'EXCEPTION_NOFILE' );
00622         }
00623 
00624         //wrong chars in file name?
00625         if ( !getStr()->preg_match('/^[\-_a-z0-9\.]+$/i', $aFileInfo['name'] ) ) {
00626             throw new oxException( 'EXCEPTION_FILENAMEINVALIDCHARS' );
00627         }
00628 
00629         // error uploading file ?
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         //removing dublicate slashes
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         //file exists ?
00676         while ( file_exists( $sFilePath . "/" . $sFileName . $sSufix . "." . $sFileExt ) ) {
00677             $iFileCounter++;
00678 
00679             //removing "(any digit)" from file name end
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 }

Generated by  doxygen 1.6.2