eZ Publish  [4.0]
ezcodepagemapper.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Definition of eZCodePageMapper class
00004 //
00005 // Created on: <11-Jul-2002 15:39:41 amos>
00006 //
00007 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00008 // SOFTWARE NAME: eZ Publish
00009 // SOFTWARE RELEASE: 4.0.x
00010 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00011 // SOFTWARE LICENSE: GNU General Public License v2.0
00012 // NOTICE: >
00013 //   This program is free software; you can redistribute it and/or
00014 //   modify it under the terms of version 2.0  of the GNU General
00015 //   Public License as published by the Free Software Foundation.
00016 //
00017 //   This program is distributed in the hope that it will be useful,
00018 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020 //   GNU General Public License for more details.
00021 //
00022 //   You should have received a copy of version 2.0 of the GNU General
00023 //   Public License along with this program; if not, write to the Free
00024 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00025 //   MA 02110-1301, USA.
00026 //
00027 //
00028 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00029 //
00030 
00031 /*! \file ezcodepagemapper.php
00032 */
00033 
00034 /*!
00035   \class eZCodePageMapper ezcodepagemapper.php
00036   \brief The class eZCodePageMapper does
00037 
00038 */
00039 
00040 require_once( "lib/ezutils/classes/ezdebug.php" );
00041 //include_once( "lib/ezi18n/classes/ezcodepage.php" );
00042 
00043 class eZCodePageMapper
00044 {
00045     const CACHE_CODE_DATE = 1026316422;
00046 
00047     /*!
00048      Constructor
00049     */
00050     function eZCodePageMapper( $input_charset_code, $output_charset_code, $use_cache = true )
00051     {
00052         $this->RequestedInputCharsetCode = $input_charset_code;
00053         $this->InputCharsetCode = eZCharsetInfo::realCharsetCode( $input_charset_code );
00054         $this->RequestedOutputCharsetCode = $output_charset_code;
00055         $this->OutputCharsetCode = eZCharsetInfo::realCharsetCode( $output_charset_code );
00056         $this->Valid = false;
00057         $this->load( $use_cache );
00058         $this->setSubstituteCharacter( 63 ); // ?
00059     }
00060 
00061     function isValid()
00062     {
00063         return $this->Valid;
00064     }
00065 
00066     function &mapInputCode( $in_code )
00067     {
00068         if ( isset( $this->InputOutputMap[$in_code] ) )
00069             return $this->InputOutputMap[$in_code];
00070         $retValue = null;
00071         return $retValue;
00072     }
00073 
00074     function &mapOutputCode( $out_code )
00075     {
00076         if ( isset( $this->OutputInputMap[$out_code] ) )
00077             return $this->OutputInputMap[$out_code];
00078         $retValue = null;
00079         return $retValue;
00080     }
00081 
00082     function mapInputChar( $in_char )
00083     {
00084         $in_code = ord( $in_char );
00085         if ( isset( $this->InputOutputMap[$in_code] ) )
00086             return chr( $this->InputOutputMap[$in_code] );
00087         return $this->SubstituteOutputChar;
00088     }
00089 
00090     function mapOutputChar( $out_char )
00091     {
00092         $out_code = ord( $out_char );
00093         if ( isset( $this->OutputInputMap[$out_code] ) )
00094             return chr( $this->OutputInputMap[$out_code] );
00095         return $this->SubstituteInputChar;
00096     }
00097 
00098     function substituteCharacterFor( $char )
00099     {
00100     }
00101 
00102     function substituteCharacter()
00103     {
00104         return $this->SubstituteCharValue;
00105     }
00106 
00107     function convertString( $str )
00108     {
00109         $out = "";
00110         $len = strlen( $str );
00111         for ( $i = 0; $i < $len; ++$i )
00112         {
00113             $char = $str[$i];
00114             $out .= $this->mapInputChar( $char );
00115         }
00116         return $out;
00117     }
00118 
00119     function strlen( $str )
00120     {
00121         return strlen( $str );
00122     }
00123 
00124     function strpos( $haystack, $needle, $offset = 0 )
00125     {
00126         return strpos( $haystack, $needle, $offset );
00127     }
00128 
00129     function strrpos( $haystack, $needle )
00130     {
00131         return strrpos( $haystack, $needle );
00132     }
00133 
00134     function substr( $str, $start, $length )
00135     {
00136         return substr( $str, $start, $length );
00137     }
00138 
00139     function setSubstituteCharacter( $char_code )
00140     {
00141         $this->SubstituteCharValue = $char_code;
00142         $input_codepage = eZCodePage::instance( $this->InputCharsetCode );
00143         $output_codepage = eZCodePage::instance( $this->OutputCharsetCode );
00144         if ( !$input_codepage->isValid() )
00145         {
00146             eZDebug::writeError( "Input codepage for " . $this->InputCharsetCode . " is not valid", "eZCodePageMapper" );
00147             return false;
00148         }
00149         if ( !$output_codepage->isValid() )
00150         {
00151             eZDebug::writeError( "Output codepage for " . $this->OutputCharsetCode . " is not valid", "eZCodePageMapper" );
00152             return false;
00153         }
00154         $this->SubstituteInputChar = chr( $input_codepage->unicodeToCode( $char_code ) );
00155         $this->SubstituteOutputChar = chr( $output_codepage->unicodeToCode( $char_code ) );
00156     }
00157 
00158     function load( $use_cache = true )
00159     {
00160         // temporarely hide the cache display problem
00161         // http://ez.no/community/bugs/char_transform_cache_file_is_not_valid_php
00162         //$use_cache = false;
00163         $cache_dir = "var/cache/codepages/";
00164         $cache_filename = md5( $this->InputCharsetCode . $this->OutputCharsetCode );
00165         $cache = $cache_dir . $cache_filename . ".php";
00166 
00167         if ( !eZCodePage::exists( $this->InputCharsetCode ) )
00168         {
00169             $input_file = eZCodePage::fileName( $this->InputCharsetCode );
00170             eZDebug::writeWarning( "Couldn't load input codepage file $input_file", "eZCodePageMapper" );
00171             return false;
00172         }
00173         if ( !eZCodePage::exists( $this->OutputCharsetCode ) )
00174         {
00175             $output_file = eZCodePage::fileName( $this->OutputCharsetCode );
00176             eZDebug::writeWarning( "Couldn't load output codepage file $output_file", "eZCodePageMapper" );
00177             return false;
00178         }
00179 
00180         $this->Valid = false;
00181         if ( file_exists( $cache ) and $use_cache )
00182         {
00183             $cache_m = filemtime( $cache );
00184             if ( eZCodePage::fileModification( $this->InputCharsetCode ) <= $cache_m and
00185                  eZCodePage::fileModification( $this->OutputCharsetCode ) <= $cache_m )
00186             {
00187                 unset( $eZCodePageMapperCacheCodeDate );
00188                 $in_out_map =& $this->InputOutputMap;
00189                 $out_in_map =& $this->OutputInputMap;
00190                 eZDebug::writeDebug( 'loading cache from: ' . $cache, 'eZCodePageMapper::load' );
00191                 include( $cache );
00192                 if ( isset( $eZCodePageMapperCacheCodeDate ) or
00193                      $eZCodePageMapperCacheCodeDate == self::CACHE_CODE_DATE )
00194                 {
00195                     $this->Valid = true;
00196                     return;
00197                 }
00198             }
00199         }
00200 
00201         $this->InputOutputMap = array();
00202         $this->OutputInputMap = array();
00203 
00204         $input_codepage = eZCodePage::instance( $this->InputCharsetCode );
00205         $output_codepage = eZCodePage::instance( $this->OutputCharsetCode );
00206 
00207         if ( !$input_codepage->isValid() )
00208         {
00209             eZDebug::writeError( "Input codepage for " . $this->InputCharsetCode . " is not valid", "eZCodePageMapper" );
00210             return false;
00211         }
00212         if ( !$output_codepage->isValid() )
00213         {
00214             eZDebug::writeError( "Output codepage for " . $this->OutputCharsetCode . " is not valid", "eZCodePageMapper" );
00215             return false;
00216         }
00217 
00218         $min = max( $input_codepage->minCharValue(),
00219                     $output_codepage->minCharValue() );
00220         $max = min( $input_codepage->maxCharValue(),
00221                     $output_codepage->maxCharValue() );
00222 
00223         for ( $i = $min; $i <= $max; ++$i )
00224         {
00225             $code = $i;
00226             $unicode = $input_codepage->codeToUnicode( $code );
00227             if ( $unicode !== null )
00228             {
00229                 $output_code = $output_codepage->unicodeToCode( $unicode );
00230                 if ( $output_code !== null )
00231                 {
00232                     $this->InputOutputMap[$code] = $output_code;
00233                     $this->OutputInputMap[$output_code] = $code;
00234                 }
00235             }
00236         }
00237     }
00238 
00239     /*!
00240      Returns the only instance of the codepage mapper for $input_charset_code and $output_charset_code.
00241     */
00242     static function instance( $input_charset_code, $output_charset_code, $use_cache = true )
00243     {
00244         $globalsKey = "eZCodePageMapper-$input_charset_code-$output_charset_code";
00245 
00246         if ( !isset( $GLOBALS[$globalsKey] ) ||
00247              !( $GLOBALS[$globalsKey] instanceof eZCodePageMapper ) )
00248         {
00249             $GLOBALS[$globalsKey] = new eZCodePageMapper( $input_charset_code, $output_charset_code, $use_cache );
00250         }
00251 
00252         return $GLOBALS[$globalsKey];
00253     }
00254 
00255 }
00256 
00257 ?>