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