eZ Publish  [4.0]
ezserializedobjectnamelist.php
Go to the documentation of this file.
00001 <?php
00002 //
00003 // Created on: <02-Oct-2006 13:37:23 dl>
00004 //
00005 // ## BEGIN COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00006 // SOFTWARE NAME: eZ Publish
00007 // SOFTWARE RELEASE: 4.0.x
00008 // COPYRIGHT NOTICE: Copyright (C) 1999-2008 eZ Systems AS
00009 // SOFTWARE LICENSE: GNU General Public License v2.0
00010 // NOTICE: >
00011 //   This program is free software; you can redistribute it and/or
00012 //   modify it under the terms of version 2.0  of the GNU General
00013 //   Public License as published by the Free Software Foundation.
00014 //
00015 //   This program is distributed in the hope that it will be useful,
00016 //   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 //   GNU General Public License for more details.
00019 //
00020 //   You should have received a copy of version 2.0 of the GNU General
00021 //   Public License along with this program; if not, write to the Free
00022 //   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00023 //   MA 02110-1301, USA.
00024 //
00025 //
00026 // ## END COPYRIGHT, LICENSE AND WARRANTY NOTICE ##
00027 //
00028 
00029 //include_once( 'kernel/classes/ezcontentlanguage.php' );
00030 
00031 class eZSerializedObjectNameList
00032 {
00033     const ALWAYS_AVAILABLE_STR = 'always-available';
00034 
00035     function eZSerializedObjectNameList( $serializedNamesString = false )
00036     {
00037         $this->DefaultLanguage = null;
00038 
00039         if ( $serializedNamesString )
00040             $this->initFromSerializedList( $serializedNamesString );
00041     }
00042 
00043     function initFromSerializedList( $serializedNamesString )
00044     {
00045         $this->HasDirtyData = false;
00046         $this->unserializeNames( $serializedNamesString );
00047     }
00048 
00049     function initFromString( $nameString, $languageLocale = false )
00050     {
00051         if ( !$languageLocale )
00052             $languageLocale = $this->defaultLanguageLocale();
00053 
00054         $serializedNameList = serialize( array( $languageLocale => $nameString,
00055                                                 eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR => $languageLocale ) );
00056         $this->initFromSerializedList( $serializedNameList );
00057     }
00058 
00059     function initDefault()
00060     {
00061         $this->initFromString( '' );
00062     }
00063 
00064     function create( $serializedNamesString = false )
00065     {
00066         $object = new eZSerializedObjectNameList( $serializedNamesString );
00067         return $object;
00068     }
00069 
00070     function __clone()
00071     {
00072     }
00073 
00074     function copy( $serializedObjectNameListObject )
00075     {
00076         $serializedObjectNameListObject->setNameList( $this->nameList() );
00077         $serializedObjectNameListObject->setHasDirtyData( $this->hasDirtyData() );
00078         $serializedObjectNameListObject->setDefaultLanguage( $this->defaultLanguage() );
00079     }
00080 
00081     function mergeNameList( $inNameList )
00082     {
00083         foreach ( $inNameList as $languageLocale => $name )
00084             $this->setNameByLanguageLocale( $name, $languageLocale );
00085 
00086         $this->setHasDirtyData();
00087     }
00088 
00089     function serializeNames()
00090     {
00091         return serialize( $this->NameList );
00092     }
00093 
00094     function isEmpty()
00095     {
00096         return ( count( $this->NameList ) == 0 );
00097     }
00098 
00099     function unserializeNames( $serializedNamesString )
00100     {
00101         $this->NameList = array();
00102         if ( $serializedNamesString )
00103         {
00104             $this->NameList = @unserialize( $serializedNamesString );
00105             if ( $this->NameList === false || !is_array( $this->NameList ) )
00106                 $this->NameList = array();
00107         }
00108 
00109         $this->setHasDirtyData( false );
00110     }
00111 
00112     function alwaysAvailableLanguageID()
00113     {
00114         $languageLocale = $this->alwaysAvailableLanguageLocale();
00115         $languageID = $languageLocale ? eZContentLanguage::idByLocale( $languageLocale ) : false;
00116 
00117         return $languageID;
00118     }
00119 
00120     function alwaysAvailableLanguageLocale()
00121     {
00122         $languageLocale = isset( $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] ) ? $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] : false;
00123         return $languageLocale;
00124     }
00125 
00126     function alwaysAvailableLanguage()
00127     {
00128         $language = false;
00129         if ( isset( $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] ) )
00130             $language = eZContentLanguage::fetchByLocale( $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] );
00131 
00132         return $language;
00133     }
00134 
00135     function languageMask()
00136     {
00137         $mask = 0;
00138         foreach ( $this->NameList as $languageLocale => $name )
00139         {
00140             if ( $languageLocale == eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR )
00141             {
00142                 $mask += 1;
00143             }
00144             else
00145             {
00146                 $languageID = eZContentLanguage::idByLocale( $languageLocale );
00147                 $mask += $languageID;
00148             }
00149         }
00150 
00151         return $mask;
00152     }
00153 
00154     function name( $languageLocale = false )
00155     {
00156         return ( ( $languageLocale === false ) ? $this->nameByPrioritizedLanguages() : $this->nameByLanguageLocale( $languageLocale ) );
00157     }
00158 
00159     function nameByPrioritizedLanguages()
00160     {
00161         $name = $this->alwaysAvailableName();
00162         $languageList = eZContentLanguage::prioritizedLanguages();
00163         foreach ( $languageList as $language )
00164         {
00165             if ( $this->hasNameInLocale( $language->attribute( 'locale' ) ) )
00166             {
00167                 $name = $this->nameByLanguageLocale( $language->attribute( 'locale' ) );
00168                 break;
00169             }
00170         }
00171 
00172         return $name;
00173     }
00174 
00175     function nameByLanguageLocale( $languageLocale )
00176     {
00177         $name = '';
00178         if ( $this->hasNameInLocale( $languageLocale ) )
00179             $name = $this->NameList[$languageLocale];
00180 
00181         return $name;
00182     }
00183 
00184     function alwaysAvailableName()
00185     {
00186         $name = '';
00187         if ( isset( $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] ) )
00188         {
00189             $name = $this->nameByLanguageLocale( $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] );
00190         }
00191 
00192         return $name;
00193     }
00194 
00195     function setAlwaysAvailableLanguage( $languageLocale )
00196     {
00197         if ( $languageLocale )
00198         {
00199             $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] = $languageLocale;
00200         }
00201         else
00202         {
00203             unset( $this->NameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] );
00204         }
00205 
00206         $this->setHasDirtyData();
00207     }
00208 
00209     function updateAlwaysAvailable( $alwaysAvailableLocale = false )
00210     {
00211         if ( !$alwaysAvailableLocale )
00212             $alwaysAvailableLocale = $this->alwaysAvailableLanguageLocale();
00213 
00214         if ( !$this->hasNameInLocale( $alwaysAvailableLocale ) )
00215         {
00216             $languageLocaleList = array_keys( $this->nameList() );
00217             $alwaysAvailableLocale = $languageLocaleList[0];
00218         }
00219 
00220         $this->setAlwaysAvailableLanguage( $alwaysAvailableLocale );
00221     }
00222 
00223     function hasNameInLocale( $languageLocale )
00224     {
00225         $hasName = false;
00226         if ( is_array ( $this->NameList ) )
00227         {
00228             if ( $languageLocale && isset( $this->NameList[$languageLocale] ) )
00229             {
00230                 $hasName = true;
00231             }
00232         }
00233         else
00234         {
00235             eZDebug::writeWarning( "Trying to get name for language '$languageLocale' without initialized name list.", 'eZSerializedObjectNameList::hasNameInLocale' );
00236         }
00237 
00238         return $hasName;
00239     }
00240 
00241     function setName( $name, $languageLocale = false )
00242     {
00243         if ( !$languageLocale )
00244             $languageLocale = $this->topPriorityLanguageLocale();
00245 
00246         $this->setNameByLanguageLocale( $name, $languageLocale );
00247     }
00248 
00249     function setNameByLanguageLocale( $name, $languageLocale )
00250     {
00251         if ( is_array( $this->NameList ) )
00252         {
00253             if ( $languageLocale )
00254             {
00255                 $this->NameList[$languageLocale] = $name;
00256                 $this->setHasDirtyData();
00257             }
00258             else
00259             {
00260                 eZDebug::writeWarning( "Language locale is not specified while setting name '$name'", 'eZSerializedObjectNameList::setNameByLanguageLocale' );
00261             }
00262         }
00263         else
00264         {
00265             eZDebug::writeWarning( "Trying to set name '$name' for language '$languageLocale' without initialized name list.", 'eZSerializedObjectNameList::setNameByLanguageLocale' );
00266         }
00267     }
00268 
00269     /*!
00270      Appends \a $appendString string to each name in NameList.
00271     */
00272     function appendGroupName( $appendString )
00273     {
00274         foreach ( array_keys( $this->NameList ) as $languageLocale )
00275         {
00276             if ( $languageLocale != eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR )
00277                 $this->NameList[$languageLocale] .= $appendString;
00278         }
00279     }
00280 
00281     /*!
00282      \static
00283     */
00284     static function nameFromSerializedString( $serializedNames, $languageLocale = false )
00285     {
00286         $nameList = new eZSerializedObjectNameList( $serializedNames );
00287         return $nameList->name( $languageLocale );
00288     }
00289 
00290 
00291     /*!
00292      \return true if the data is considered dirty(e.g. names were changed)
00293     */
00294     function hasDirtyData()
00295     {
00296         return $this->HasDirtyData;
00297     }
00298 
00299     /*!
00300      Sets whether the object has dirty data or not.
00301      \sa hasDirtyData, sync
00302     */
00303     function setHasDirtyData( $hasDirtyData = true )
00304     {
00305         $this->HasDirtyData = $hasDirtyData;
00306     }
00307 
00308     function nameList()
00309     {
00310         return $this->NameList;
00311     }
00312 
00313     /*!
00314      Same as 'nameList()' but without 'always-available' entry.
00315      */
00316     function cleanNameList()
00317     {
00318         $nameList = $this->nameList();
00319         unset( $nameList[eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR] );
00320         return $nameList;
00321     }
00322 
00323     function nameListCount()
00324     {
00325         return count( $this->nameList );
00326     }
00327 
00328     function setNameList( $nameListArray )
00329     {
00330         $this->NameList = $nameListArray;
00331     }
00332 
00333     function resetNameList()
00334     {
00335         $this->setNameList( array() );
00336     }
00337 
00338     function removeName( $languageLocale )
00339     {
00340         if ( isset( $this->NameList[$languageLocale] ) )
00341         {
00342             unset( $this->NameList[$languageLocale] );
00343             $this->setHasDirtyData();
00344         }
00345     }
00346 
00347     /*!
00348     */
00349     function defaultLanguageLocale()
00350     {
00351         $languageLocale = false;
00352         $language = $this->defaultLanguage();
00353 
00354         if ( is_object( $language ) )
00355             $languageLocale = $language->attribute( 'locale' );
00356 
00357         return $languageLocale;
00358     }
00359 
00360     /*!
00361     */
00362     function defaultLanguage()
00363     {
00364         if ( !is_object( $this->DefaultLanguage ) )
00365         {
00366             $this->DefaultLanguage = eZContentLanguage::topPriorityLanguage();
00367         }
00368 
00369         return $this->DefaultLanguage;
00370     }
00371 
00372     function setDefaultLanguage( $language )
00373     {
00374         $this->DefaultLanguage = $language;
00375     }
00376 
00377     function setDefaultLanguageByLocale( $languageLocale, $createIfNotExist = true )
00378     {
00379         $language = eZContentLanguage::fetchByLocale( $languageLocale, $createIfNotExist );
00380 
00381         if ( is_object( $language ) )
00382         {
00383             $this->setDefaultLanguage( $language );
00384         }
00385         else
00386         {
00387             eZDebug::writeWarning( "Can't set '$languageLocale' as default language. '$languageLocale' language doesn't exist in system", "eZSerializedObjectNameList::setDefaultLanguageByLocale" );
00388         }
00389 
00390         return $language;
00391     }
00392 
00393     /*!
00394      The same as 'topPriorityLanguage' but returns language locale.
00395 
00396      \return language locale.
00397     */
00398     function topPriorityLanguageLocale()
00399     {
00400         $languageLocale = false;
00401 
00402         $language = $this->topPriorityLanguage();
00403         if ( $language )
00404             $languageLocale = $language->attribute( 'locale' );
00405 
00406         return $languageLocale;
00407     }
00408 
00409     /*!
00410      Returns top prioriry language for which there is translation according to
00411      siteaccess's available language list.
00412      If there is no translations for languages listed in siteaccess's available language list
00413      it returns 'always available' language.
00414 
00415      \return language object.
00416     */
00417     function topPriorityLanguage()
00418     {
00419         $language = false;
00420 
00421         $languageLocaleList = $this->languageLocaleList();
00422 
00423         $language = eZContentLanguage::topPriorityLanguageByLocaleList( $languageLocaleList );
00424 
00425         if ( !$language )
00426             $language = $this->alwaysAvailableLanguage();
00427 
00428         return $language;
00429     }
00430 
00431     /*!
00432      Returns an array of languages in which contentclass has translations.
00433      However, if there is a name in language which is not
00434      listed as 'available' for siteaccess, that langugese will not be returned
00435      (except of 'always available' language).
00436 
00437      \return an array of language's locales.
00438     */
00439     function prioritizedLanguages()
00440     {
00441         $languageLocaleList = $this->languageLocaleList();
00442         $languages = eZContentLanguage::prioritizedLanguagesByLocaleList( $languageLocaleList );
00443 
00444         $alwaysAvailableLanguage = $this->alwaysAvailableLanguage();
00445         if ( $alwaysAvailableLanguage )
00446         {
00447             $alwaysAvailableLanguageLocale = $alwaysAvailableLanguage->attribute( 'locale' );
00448             if ( !isset( $languages[$alwaysAvailableLanguageLocale] ) )
00449             {
00450                 $languages[$alwaysAvailableLanguageLocale] = $alwaysAvailableLanguage;
00451             }
00452         }
00453 
00454         return $languages;
00455     }
00456 
00457     function prioritizedLanguagesJsArray()
00458     {
00459         $languages = $this->prioritizedLanguages();
00460 
00461         $jsArray = array();
00462 
00463         foreach ( $languages as $key => $language )
00464         {
00465             $jsArray[] = "{ locale: '".$language->attribute( 'locale' ).
00466                 "', name: '".$language->attribute( 'name' )."' }";
00467         }
00468 
00469         if ( count( $jsArray ) > 0 )
00470         {
00471             $jsArray = '[ '.implode( ', ', $jsArray ).' ]';
00472         }
00473 
00474         return $jsArray;
00475     }
00476 
00477     function languageLocaleList()
00478     {
00479         $languageLocaleList = array();
00480 
00481         if ( is_array( $this->NameList ) && count( $this->NameList ) > 0 )
00482         {
00483             foreach ( array_keys( $this->NameList ) as $languageLocale )
00484             {
00485                 if ( $languageLocale != eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR )
00486                     $languageLocaleList[] = $languageLocale;
00487             }
00488         }
00489 
00490         return $languageLocaleList;
00491     }
00492 
00493     /*!
00494      The same as 'languageLocaleList' but returns a list of 'eZContentLanguage' objects.
00495 
00496      \return array of language objects.
00497     */
00498     function languages()
00499     {
00500         $languages = array();
00501 
00502         $languageLocaleList = $this->languageLocaleList();
00503         foreach( $languageLocaleList as $languageLocale )
00504             $languages[$languageLocale] = eZContentLanguage::fetchByLocale( $languageLocale );
00505 
00506         return $languages;
00507     }
00508 
00509     /*!
00510      Returns an array of languages for which translations don't exist.
00511 
00512      \return an array of languages. Each key in this array is 'language locale'.
00513     */
00514     function untranslatedLanguages()
00515     {
00516         $availableLanguages = $this->prioritizedLanguages();
00517         $availableLanguagesCodes = array_keys( $availableLanguages );
00518 
00519         $languages = array();
00520         foreach ( eZContentLanguage::prioritizedLanguages() as $language )
00521         {
00522             $languageCode = $language->attribute( 'locale' );
00523             if ( !in_array( $languageCode, $availableLanguagesCodes ) )
00524             {
00525                 $languages[$languageCode] = $language;
00526             }
00527         }
00528 
00529         return $languages;
00530     }
00531 
00532     /*!
00533      \param $languageInfo. languageInfo = array( 'map_table' => array( [<lang> => <to_lang>],
00534                                                                        [<lang> => 'skip_language'],
00535                                                                        .... ) );
00536 
00537      Note: it's probably needed to call 'validate' after 'normalize'.
00538            'normialize' doesnt' check whether language exist or not, cause you can have names in languages which are not
00539            in 'map_table', so you need to call 'validate' anyway.
00540     */
00541     function normalize( $languageInfo )
00542     {
00543         if ( is_array( $languageInfo ) && isset( $languageInfo['map_table'] ) )
00544         {
00545             // do normalization on new 'nameList' to avoid dependence on the order
00546             // of <lang>s in 'map_table'. Normailzation on $this->nameList directly
00547             // can lead to unwanted behaviour, like
00548             //      'map_table' => array( 'ger-DE' => 'skip_language',
00549             //                            'eng-GB' => 'ger-DE' )
00550             // and
00551             //      'map_table' => array( 'eng-GB' => 'get-DE',
00552             //                            'ger-DE' => 'skip_language' )
00553             // will produce different results.
00554             $nameList = clone $this;
00555             $this->resetNameList();
00556 
00557             foreach ( $languageInfo['map_table'] as $fromLanguageLocale => $toLanguageLocale )
00558             {
00559                 $name = $nameList->nameByLanguageLocale( $fromLanguageLocale );
00560 
00561                 if ( $tolanguageLocale == 'skip_language' )
00562                 {
00563                     // do nothing;
00564                 }
00565                 else
00566                 {
00567                     $this->setNameByLanguageLocale( $name, $toLanguageLocale );
00568                 }
00569 
00570                 // exclude 'processed' name.
00571                 $nameList->removeName( $fromLanguageLocale );
00572             }
00573 
00574             // copy names which were not transformed
00575             $this->mergeNameList( $nameList );
00576 
00577             // update always-available(probably original 'always-available' was skiped)
00578             $this->updateAlwaysAvailable();
00579         }
00580     }
00581 
00582     /*!
00583      Make sure that languages namelist corresponds to languages in the system.
00584      \param $param. TRUE - create languages if they don't exist in the system.
00585                     FALSE - remove names form namelist if corresponding language doesn't exist in the system.
00586                     array - language map. The name will be removed if its language is not in the map.
00587                             Ex: array( 'language_locale_1' => 'map_to_language_locale',
00588                                        'language_locale_2' => 'skip' );
00589                                 will map name in 'language_locale_1' language to 'map_to_language_locale' and
00590                                 remove name in 'language_locale_2'. 'map_to_language_locale' language will be
00591                                 created If it doesn't exist in the system.
00592     */
00593     function validate( $param = true )
00594     {
00595         $languageMap = ( is_array( $param ) && (count( $param ) > 0) ) ? $param : false;
00596         $createLanguageIfNotExist = ( $param === true ) ? true : false;
00597         $nameList = $this->nameList();
00598         foreach ( $nameList as $nameLanguageLocale => $name )
00599         {
00600             if ( $nameLanguageLocale != eZSerializedObjectNameList::ALWAYS_AVAILABLE_STR )
00601             {
00602                 $language = false;
00603 
00604                 if( $createLanguageIfNotExist )
00605                 {
00606                     $language = eZContentLanguage::fetchByLocale( $nameLanguageLocale, true );
00607                 }
00608                 else
00609                 {
00610                     if ( is_array( $languageMap ) )
00611                     {
00612                         $languageLocale = isset( $languageMap[$nameLanguageLocale] ) ? $languageMap[$nameLanguageLocale] : false;
00613 
00614                         if( $languageLocale && $languageLocale != 'skip' )
00615                         {
00616                             $language = eZContentLanguage::fetchByLocale( $languageLocale, true );
00617                         }
00618                     }
00619                     else
00620                     {
00621                         // just check '$nameLanguageLocale' language if '$languageMap' is not specified.
00622                         $language = eZContentLanguage::fetchByLocale( $nameLanguageLocale, false );
00623                     }
00624                 }
00625 
00626                 $languageLocale = is_object( $language ) ? $language->attribute( 'locale' ) : false;
00627 
00628                 if( $languageLocale != $nameLanguageLocale )
00629                 {
00630                     if( $languageLocale )
00631                     {
00632                         // map name's language.
00633                         $this->removeName( $nameLanguageLocale );
00634                         $this->setName( $name, $languageLocale );
00635                     }
00636                     else
00637                     {
00638                         $this->removeName( $nameLanguageLocale );
00639                     }
00640                 }
00641             }
00642         }
00643         // update always-available(probably original 'always-available' was skiped)
00644         $this->updateAlwaysAvailable();
00645     }
00646 
00647     public $NameList;
00648     public $HasDirtyData;
00649     public $DefaultLanguage;
00650 }
00651 
00652 ?>