eZ Publish  [trunk]
ezcodepagemapper.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZCodePageMapper class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package lib
00009  */
00010 
00011 /*!
00012   \class eZCodePageMapper ezcodepagemapper.php
00013   \brief The class eZCodePageMapper does
00014 
00015 */
00016 
00017 class eZCodePageMapper
00018 {
00019     const CACHE_CODE_DATE = 1026316422;
00020 
00021     /*!
00022      Constructor
00023     */
00024     function eZCodePageMapper( $input_charset_code, $output_charset_code, $use_cache = true )
00025     {
00026         $this->RequestedInputCharsetCode = $input_charset_code;
00027         $this->InputCharsetCode = eZCharsetInfo::realCharsetCode( $input_charset_code );
00028         $this->RequestedOutputCharsetCode = $output_charset_code;
00029         $this->OutputCharsetCode = eZCharsetInfo::realCharsetCode( $output_charset_code );
00030         $this->Valid = false;
00031         $this->load( $use_cache );
00032         $this->setSubstituteCharacter( 63 ); // ?
00033     }
00034 
00035     function isValid()
00036     {
00037         return $this->Valid;
00038     }
00039 
00040     function &mapInputCode( $in_code )
00041     {
00042         if ( isset( $this->InputOutputMap[$in_code] ) )
00043             return $this->InputOutputMap[$in_code];
00044         $retValue = null;
00045         return $retValue;
00046     }
00047 
00048     function &mapOutputCode( $out_code )
00049     {
00050         if ( isset( $this->OutputInputMap[$out_code] ) )
00051             return $this->OutputInputMap[$out_code];
00052         $retValue = null;
00053         return $retValue;
00054     }
00055 
00056     function mapInputChar( $in_char )
00057     {
00058         $in_code = ord( $in_char );
00059         if ( isset( $this->InputOutputMap[$in_code] ) )
00060             return chr( $this->InputOutputMap[$in_code] );
00061         return $this->SubstituteOutputChar;
00062     }
00063 
00064     function mapOutputChar( $out_char )
00065     {
00066         $out_code = ord( $out_char );
00067         if ( isset( $this->OutputInputMap[$out_code] ) )
00068             return chr( $this->OutputInputMap[$out_code] );
00069         return $this->SubstituteInputChar;
00070     }
00071 
00072     function substituteCharacterFor( $char )
00073     {
00074     }
00075 
00076     function substituteCharacter()
00077     {
00078         return $this->SubstituteCharValue;
00079     }
00080 
00081     function convertString( $str )
00082     {
00083         $out = "";
00084         $len = strlen( $str );
00085         for ( $i = 0; $i < $len; ++$i )
00086         {
00087             $char = $str[$i];
00088             $out .= $this->mapInputChar( $char );
00089         }
00090         return $out;
00091     }
00092 
00093     function strlen( $str )
00094     {
00095         return strlen( $str );
00096     }
00097 
00098     function strpos( $haystack, $needle, $offset = 0 )
00099     {
00100         return strpos( $haystack, $needle, $offset );
00101     }
00102 
00103     function strrpos( $haystack, $needle )
00104     {
00105         return strrpos( $haystack, $needle );
00106     }
00107 
00108     function substr( $str, $start, $length )
00109     {
00110         return substr( $str, $start, $length );
00111     }
00112 
00113     function setSubstituteCharacter( $char_code )
00114     {
00115         $this->SubstituteCharValue = $char_code;
00116         $input_codepage = eZCodePage::instance( $this->InputCharsetCode );
00117         $output_codepage = eZCodePage::instance( $this->OutputCharsetCode );
00118         if ( !$input_codepage->isValid() )
00119         {
00120             eZDebug::writeError( "Input codepage for " . $this->InputCharsetCode . " is not valid", "eZCodePageMapper" );
00121             return false;
00122         }
00123         if ( !$output_codepage->isValid() )
00124         {
00125             eZDebug::writeError( "Output codepage for " . $this->OutputCharsetCode . " is not valid", "eZCodePageMapper" );
00126             return false;
00127         }
00128         $this->SubstituteInputChar = chr( $input_codepage->unicodeToCode( $char_code ) );
00129         $this->SubstituteOutputChar = chr( $output_codepage->unicodeToCode( $char_code ) );
00130     }
00131 
00132     function load( $use_cache = true )
00133     {
00134         // temporarely hide the cache display problem
00135         // http://ez.no/community/bugs/char_transform_cache_file_is_not_valid_php
00136         //$use_cache = false;
00137         $cache_dir = "var/cache/codepages/";
00138         $cache_filename = md5( $this->InputCharsetCode . $this->OutputCharsetCode );
00139         $cache = $cache_dir . $cache_filename . ".php";
00140 
00141         if ( !eZCodePage::exists( $this->InputCharsetCode ) )
00142         {
00143             $input_file = eZCodePage::fileName( $this->InputCharsetCode );
00144             eZDebug::writeWarning( "Couldn't load input codepage file $input_file", "eZCodePageMapper" );
00145             return false;
00146         }
00147         if ( !eZCodePage::exists( $this->OutputCharsetCode ) )
00148         {
00149             $output_file = eZCodePage::fileName( $this->OutputCharsetCode );
00150             eZDebug::writeWarning( "Couldn't load output codepage file $output_file", "eZCodePageMapper" );
00151             return false;
00152         }
00153 
00154         $this->Valid = false;
00155         if ( file_exists( $cache ) and $use_cache )
00156         {
00157             $cache_m = filemtime( $cache );
00158             if ( eZCodePage::fileModification( $this->InputCharsetCode ) <= $cache_m and
00159                  eZCodePage::fileModification( $this->OutputCharsetCode ) <= $cache_m )
00160             {
00161                 unset( $eZCodePageMapperCacheCodeDate );
00162                 $in_out_map =& $this->InputOutputMap;
00163                 $out_in_map =& $this->OutputInputMap;
00164                 eZDebug::writeDebug( 'loading cache from: ' . $cache, __METHOD__ );
00165                 include( $cache );
00166                 if ( isset( $eZCodePageMapperCacheCodeDate ) or
00167                      $eZCodePageMapperCacheCodeDate == self::CACHE_CODE_DATE )
00168                 {
00169                     $this->Valid = true;
00170                     return;
00171                 }
00172             }
00173         }
00174 
00175         $this->InputOutputMap = array();
00176         $this->OutputInputMap = array();
00177 
00178         $input_codepage = eZCodePage::instance( $this->InputCharsetCode );
00179         $output_codepage = eZCodePage::instance( $this->OutputCharsetCode );
00180 
00181         if ( !$input_codepage->isValid() )
00182         {
00183             eZDebug::writeError( "Input codepage for " . $this->InputCharsetCode . " is not valid", "eZCodePageMapper" );
00184             return false;
00185         }
00186         if ( !$output_codepage->isValid() )
00187         {
00188             eZDebug::writeError( "Output codepage for " . $this->OutputCharsetCode . " is not valid", "eZCodePageMapper" );
00189             return false;
00190         }
00191 
00192         $min = max( $input_codepage->minCharValue(),
00193                     $output_codepage->minCharValue() );
00194         $max = min( $input_codepage->maxCharValue(),
00195                     $output_codepage->maxCharValue() );
00196 
00197         for ( $i = $min; $i <= $max; ++$i )
00198         {
00199             $code = $i;
00200             $unicode = $input_codepage->codeToUnicode( $code );
00201             if ( $unicode !== null )
00202             {
00203                 $output_code = $output_codepage->unicodeToCode( $unicode );
00204                 if ( $output_code !== null )
00205                 {
00206                     $this->InputOutputMap[$code] = $output_code;
00207                     $this->OutputInputMap[$output_code] = $code;
00208                 }
00209             }
00210         }
00211     }
00212 
00213     /**
00214      * Returns a shared instance of the eZCodePageMapper pr the
00215      * $input_charset_code and $output_charset_code params.
00216      *
00217      * @param string $input_charset_code
00218      * @param string $output_charset_code
00219      * @param bool $use_cache
00220      * @return eZCodePageMapper
00221      */
00222     static function instance( $input_charset_code, $output_charset_code, $use_cache = true )
00223     {
00224         $globalsKey = "eZCodePageMapper-$input_charset_code-$output_charset_code";
00225 
00226         if ( !isset( $GLOBALS[$globalsKey] ) ||
00227              !( $GLOBALS[$globalsKey] instanceof eZCodePageMapper ) )
00228         {
00229             $GLOBALS[$globalsKey] = new eZCodePageMapper( $input_charset_code, $output_charset_code, $use_cache );
00230         }
00231 
00232         return $GLOBALS[$globalsKey];
00233     }
00234 
00235 }
00236 
00237 ?>