|
eZ Publish
[4.0]
|
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 ?>