|
eZ Publish
[trunk]
|
00001 <?php 00002 /** 00003 * File containing the eZContentLanguage 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 eZContentLanguage extends eZPersistentObject 00012 { 00013 const MAX_COUNT = 30; 00014 00015 /** 00016 * Constructor. 00017 * 00018 * \param row Parameter passed to the constructor of eZPersistentObject. 00019 */ 00020 function eZContentLanguage( $row = array() ) 00021 { 00022 $this->eZPersistentObject( $row ); 00023 } 00024 00025 /** 00026 * Persistent object's definition. 00027 */ 00028 static function definition() 00029 { 00030 static $definition = array( 'fields' => array( 'id' => array( 'name' => 'ID', 00031 'datatype' => 'integer', 00032 'required' => true ), 00033 'name' => array( 'name' => 'Name', 00034 'datatype' => 'string', 00035 'required' => true ), 00036 'locale' => array( 'name' => 'Locale', 00037 'datatype' => 'string', 00038 'required' => true ), 00039 'disabled' => array( 'name' => 'Disabled', /* disabled is reserved for the future */ 00040 'datatype' => 'integer', 00041 'default' => 0, 00042 'required' => false ) ), 00043 'keys' => array( 'id' ), 00044 'function_attributes' => array( 'translation' => 'translation', 00045 'locale_object' => 'localeObject', 00046 'class_count' => 'classCount', 00047 'object_count' => 'objectCount' ), 00048 'sort' => array( 'name' => 'asc' ), 00049 'class_name' => 'eZContentLanguage', 00050 'name' => 'ezcontent_language' ); 00051 return $definition; 00052 } 00053 00054 /** 00055 * Adds new language to the site. 00056 * 00057 * \param locale Locale code (e.g. 'slk-SK') of language to add. 00058 * \param name Optional. Name of the language. If not specified, the international language name for the $locale locale 00059 * will be used. 00060 * \return eZContentLanguage object of the added language (or the existing one if specified language has been already used) 00061 * or false in case of any error (invalid locale code or already reached eZContentLanguage::MAX_COUNT languages). 00062 * \static 00063 */ 00064 static function addLanguage( $locale, $name = null ) 00065 { 00066 $localeObject = eZLocale::instance( $locale ); 00067 if ( !$localeObject ) 00068 { 00069 eZDebug::writeError( "No such locale $locale!", __METHOD__ ); 00070 return false; 00071 } 00072 00073 if ( $name === null ) 00074 { 00075 $name = $localeObject->attribute( 'intl_language_name' ); 00076 } 00077 00078 $db = eZDB::instance(); 00079 00080 $languages = eZContentLanguage::fetchList( true ); 00081 00082 if ( ( $existingLanguage = eZContentLanguage::fetchByLocale( $locale ) ) ) 00083 { 00084 eZDebug::writeWarning( "Language '$locale' already exists!", __METHOD__ ); 00085 return $existingLanguage; 00086 } 00087 00088 if ( count( $languages ) >= eZContentLanguage::MAX_COUNT ) 00089 { 00090 eZDebug::writeError( 'Too many languages, cannot add more!', __METHOD__ ); 00091 return false; 00092 } 00093 00094 $db->lock( 'ezcontent_language' ); 00095 00096 $idSum = 0; 00097 foreach( $languages as $language ) 00098 { 00099 $idSum += $language->attribute( 'id' ); 00100 } 00101 00102 // ID 1 is reserved 00103 $candidateId = 2; 00104 while ( $idSum & $candidateId ) 00105 { 00106 $candidateId *= 2; 00107 } 00108 00109 $newLanguage = new eZContentLanguage( array( 00110 'id' => $candidateId, 00111 'locale' => $locale, 00112 'name' => $name, 00113 'disabled' => 0 ) ); 00114 $newLanguage->store(); 00115 00116 $db->unlock(); 00117 00118 eZContentLanguage::fetchList( true ); 00119 00120 // clear the cache 00121 eZContentCacheManager::clearAllContentCache(); 00122 00123 return $newLanguage; 00124 } 00125 00126 /** 00127 * Removes the language specified by ID. 00128 * 00129 * \param id ID of the language to be removed. 00130 * \return True if the language was removed from the site, false otherwise. 00131 * \static 00132 */ 00133 static function removeLanguage( $id ) 00134 { 00135 $language = eZContentLanguage::fetch( $id ); 00136 if ( $language ) 00137 { 00138 return $language->removeThis(); 00139 } 00140 else 00141 { 00142 return false; 00143 } 00144 } 00145 00146 /** 00147 * Removes the language if there is no object having translation in it. 00148 * 00149 * \return True if the language was removed from the site, false otherwise. 00150 */ 00151 function removeThis() 00152 { 00153 if ( ($this->objectCount() > 0) or ($this->classCount() > 0) ) 00154 { 00155 return false; 00156 } 00157 00158 eZPersistentObject::remove(); 00159 00160 eZContentCacheManager::clearAllContentCache(); 00161 00162 eZContentLanguage::fetchList( true ); 00163 00164 return true; 00165 } 00166 00167 /** 00168 * Fetches the list of the languages used on the site. 00169 * 00170 * \param forceReloading Optional. If true, the list will be fetched from database even if it is cached in memory. 00171 * Default value is false. 00172 * \return Array of the eZContentLanguage objects of languages used on the site. 00173 * \static 00174 */ 00175 static function fetchList( $forceReloading = false ) 00176 { 00177 if( isset( $GLOBALS['eZContentLanguageList'] ) && $forceReloading === false ) 00178 return $GLOBALS['eZContentLanguageList']; 00179 00180 $cachePath = eZSys::cacheDirectory() . '/ezcontentlanguage_cache.php'; 00181 $clusterFileHandler = eZClusterFileHandler::instance( $cachePath ); 00182 00183 if( $forceReloading || !$clusterFileHandler->fileExists( $cachePath ) ) 00184 { 00185 $languages = eZPersistentObject::fetchObjectList( eZContentLanguage::definition() ); 00186 $clusterFileHandler->fileStoreContents( $cachePath, serialize( $languages ), 'content', 'php' ); 00187 } 00188 else 00189 { 00190 $languages = unserialize( $clusterFileHandler->fetchContents() ); 00191 // If for some reason unserialize operation fails, we force the cache file to regenerate 00192 // See http://issues.ez.no/18613 00193 if ( $languages === false ) 00194 { 00195 eZDebug::writeError( 00196 "An error occurred while reading content language cache file $cachePath. File is being re-generated", 00197 __METHOD__ 00198 ); 00199 return self::fetchList( true ); 00200 } 00201 } 00202 00203 unset( $GLOBALS['eZContentLanguageList'] ); 00204 unset( $GLOBALS['eZContentLanguageMask'] ); 00205 $GLOBALS['eZContentLanguageList'] = array(); 00206 $mask = 1; // we want have 0-th bit set too! 00207 foreach ( $languages as $language ) 00208 { 00209 $GLOBALS['eZContentLanguageList'][$language->attribute( 'id' )] = $language; 00210 $mask += $language->attribute( 'id' ); 00211 } 00212 00213 $GLOBALS['eZContentLanguageMask'] = $mask; 00214 00215 return $GLOBALS['eZContentLanguageList']; 00216 } 00217 00218 /** 00219 * Fetches the array with names and IDs of the languages used on the site. This method is used by the permission system. 00220 * 00221 * \param forceReloading Optional. If true, the list will be fetched from database even if it is cached in memory. 00222 * Default value is false. 00223 * \return Array with names and IDs of the languages used on the site. 00224 * \static 00225 */ 00226 static function fetchLimitationList( $forceReloading = false ) 00227 { 00228 $languages = array(); 00229 foreach ( eZContentLanguage::fetchList( $forceReloading ) as $language ) 00230 { 00231 $languages[] = array( 'name' => $language->attribute( 'name' ), 00232 'id' => $language->attribute( 'locale' ) ); 00233 } 00234 return $languages; 00235 } 00236 00237 /** 00238 * Fetches the array of locale codes of the languages used on the site. 00239 * 00240 * \return Array of locale codes of the languages used on the site. 00241 * \static 00242 */ 00243 static function fetchLocaleList() 00244 { 00245 $languages = eZContentLanguage::fetchList(); 00246 $localeList = array(); 00247 00248 foreach ( $languages as $language ) 00249 { 00250 $localeList[] = $language->attribute( 'locale' ); 00251 } 00252 00253 return $localeList; 00254 } 00255 00256 /** 00257 * Fetches the language identified by ID. 00258 * 00259 * \param id Identifier of the language to fetch. 00260 * \return eZContentLanguage object of language identified by ID $id. 00261 * \static 00262 */ 00263 static function fetch( $id ) 00264 { 00265 $languages = eZContentLanguage::fetchList(); 00266 00267 return isset( $languages[$id] )? $languages[$id]: false; 00268 } 00269 00270 /** 00271 * Fetches the language identified by locale code. 00272 * 00273 * \param locale Locale of the language to fetch, e. g. 'slk-SK'. 00274 * \return eZContentLanguage object identified by locale code $locale. 00275 */ 00276 static function fetchByLocale( $locale, $createIfNotExist = false ) 00277 { 00278 $languages = eZContentLanguage::fetchList(); 00279 00280 foreach ( $languages as $language ) 00281 { 00282 if ( $language->attribute( 'locale' ) == $locale ) 00283 { 00284 return $language; 00285 } 00286 } 00287 00288 $language = false; 00289 if ( $createIfNotExist ) 00290 { 00291 $language = eZContentLanguage::addLanguage( $locale ); 00292 } 00293 00294 return $language; 00295 } 00296 00297 /** 00298 * Fetches the list of the prioritized languages (in the correct order). 00299 * 00300 * \param languageList Optional. If specified, this array of locale codes with will override the INI 00301 * settings. Usage of this parameter is restricted to methods of this class! 00302 * See eZContentLanguage::setPrioritizedLanguages(). 00303 * \return Array of the eZContentLanguage objects of the prioritized languages. 00304 * \static 00305 */ 00306 static function prioritizedLanguages( $languageList = false ) 00307 { 00308 if ( !isset( $GLOBALS['eZContentLanguagePrioritizedLanguages'] ) ) 00309 { 00310 $GLOBALS['eZContentLanguagePrioritizedLanguages'] = array(); 00311 00312 $ini = eZINI::instance(); 00313 00314 $languageListAsParameter = false; 00315 if ( $languageList ) 00316 { 00317 $languageListAsParameter = true; 00318 } 00319 00320 if ( !$languageList && $ini->hasVariable( 'RegionalSettings', 'SiteLanguageList' ) ) 00321 { 00322 $languageList = $ini->variable( 'RegionalSettings', 'SiteLanguageList' ); 00323 } 00324 00325 if ( !$languageList ) 00326 { 00327 $languageList = array( $ini->variable( 'RegionalSettings', 'ContentObjectLocale' ) ); 00328 } 00329 00330 $processedLocaleCodes = array(); 00331 foreach ( $languageList as $localeCode ) 00332 { 00333 if ( in_array( $localeCode, $processedLocaleCodes ) ) 00334 { 00335 continue; 00336 } 00337 $processedLocaleCodes[] = $localeCode; 00338 $language = eZContentLanguage::fetchByLocale( $localeCode ); 00339 if ( $language ) 00340 { 00341 $GLOBALS['eZContentLanguagePrioritizedLanguages'][] = $language; 00342 } 00343 else 00344 { 00345 eZDebug::writeWarning( "Language '$localeCode' does not exist or is not used!", __METHOD__ ); 00346 } 00347 } 00348 00349 if ( ( !$languageListAsParameter && $ini->variable( 'RegionalSettings', 'ShowUntranslatedObjects' ) == 'enabled' ) || 00350 ( isset( $GLOBALS['eZContentLanguageCronjobMode'] ) && $GLOBALS['eZContentLanguageCronjobMode'] ) ) 00351 { 00352 $completeList = eZContentLanguage::fetchList(); 00353 foreach ( $completeList as $language ) 00354 { 00355 if ( !in_array( $language->attribute( 'locale' ), $languageList ) ) 00356 { 00357 $GLOBALS['eZContentLanguagePrioritizedLanguages'][] = $language; 00358 } 00359 } 00360 } 00361 } 00362 00363 return $GLOBALS['eZContentLanguagePrioritizedLanguages']; 00364 } 00365 00366 /** 00367 * Returns the array of the locale codes of the prioritized languages (in the correct order). 00368 * 00369 * \return Array of the locale codes of the prioritized languages (in the correct order). 00370 * \see eZContentLanguage::prioritizedLanguages() 00371 * \static 00372 */ 00373 static function prioritizedLanguageCodes() 00374 { 00375 $languages = eZContentLanguage::prioritizedLanguages(); 00376 $localeList = array(); 00377 00378 foreach ( $languages as $language ) 00379 { 00380 $localeList[] = $language->attribute( 'locale' ); 00381 } 00382 00383 return $localeList; 00384 } 00385 00386 /** 00387 * Overrides the prioritized languages set by INI settings with the specified languages. 00388 * 00389 * \param languages Locale codes of the languages which will override the prioritized languages 00390 * (the order is relevant). 00391 * \static 00392 */ 00393 static function setPrioritizedLanguages( $languages ) 00394 { 00395 unset( $GLOBALS['eZContentLanguagePrioritizedLanguages'] ); 00396 eZContentLanguage::prioritizedLanguages( $languages ); 00397 } 00398 00399 /** 00400 * Clears the prioritized language list set by eZContentLanguage::setPrioritizedLanguages and reloading 00401 * the list from INI settings. 00402 * 00403 * \static 00404 */ 00405 static function clearPrioritizedLanguages() 00406 { 00407 eZContentLanguage::setPrioritizedLanguages( false ); 00408 } 00409 00410 /** 00411 * Returns the most prioritized language. 00412 * 00413 * \return eZContentLanguage object for the most prioritized language. 00414 * \static 00415 */ 00416 static function topPriorityLanguage() 00417 { 00418 $prioritizedLanguages = eZContentLanguage::prioritizedLanguages(); 00419 if ( $prioritizedLanguages ) 00420 { 00421 return $prioritizedLanguages[0]; 00422 } 00423 else 00424 { 00425 return false; 00426 } 00427 } 00428 00429 /** 00430 * \return Locale object for this language. 00431 */ 00432 function localeObject() 00433 { 00434 $locale = eZLocale::instance( $this->Locale ); 00435 return $locale; 00436 } 00437 00438 /** 00439 * Returns array of languages which have set the corresponding bit in the mask. 00440 * 00441 * \param mask Bitmap specifying which languages should be returned. 00442 * \return Array of eZContentLanguage objects of languages which have set the corresponding bit in $mask. 00443 */ 00444 static function languagesByMask( $mask ) 00445 { 00446 $result = array(); 00447 00448 $languages = eZContentLanguage::fetchList(); 00449 foreach ( $languages as $key => $language ) 00450 { 00451 if ( (int) $key & (int) $mask ) 00452 { 00453 $result[$language->attribute( 'locale' )] = $language; 00454 } 00455 } 00456 00457 return $result; 00458 } 00459 00460 /** 00461 * Returns array of prioritized languages which have set the corresponding bit in the mask. 00462 * 00463 * \param mask Bitmap specifying which languages should be returned. 00464 * \return Array of eZContentLanguage objects of prioritized languages which have set the corresponding bit in $mask. 00465 */ 00466 static function prioritizedLanguagesByMask( $mask ) 00467 { 00468 $result = array(); 00469 00470 $languages = eZContentLanguage::prioritizedLanguages(); 00471 foreach ( $languages as $language ) 00472 { 00473 if ( ( (int) $language->attribute( 'id' ) & (int) $mask ) > 0 ) 00474 { 00475 $result[$language->attribute( 'locale' )] = $language; 00476 } 00477 } 00478 00479 return $result; 00480 } 00481 00482 /** 00483 * Returns array of prioritized languages which are listed in \a $languageLocaleList. 00484 * The function does the same as 'prioritizedLanguagesByMask' but uses language locale list instead of language mask. 00485 * 00486 * \param languageLocaleList List of language locales to choose from. 00487 * \return Array of eZContentLanguage objects of prioritized languages which have set the corresponding bit in $mask. 00488 */ 00489 static function prioritizedLanguagesByLocaleList( $languageLocaleList ) 00490 { 00491 $result = array(); 00492 00493 if ( is_array( $languageLocaleList ) && count( $languageLocaleList ) > 0 ) 00494 { 00495 $languages = eZContentLanguage::prioritizedLanguages(); 00496 foreach ( $languages as $language ) 00497 { 00498 if ( in_array( $language->attribute( 'locale' ), $languageLocaleList ) ) 00499 { 00500 $result[$language->attribute( 'locale' )] = $language; 00501 } 00502 } 00503 } 00504 00505 return $result; 00506 } 00507 00508 /** 00509 * Returns the most prioritized language which has set the corresponding bit in the mask. 00510 * 00511 * \param mask Bitmap specifying which languages should be checked. 00512 * \return eZContentLanguage object of the most prioritized language which have set the corresponding bit in $mask. 00513 */ 00514 static function topPriorityLanguageByMask( $mask ) 00515 { 00516 $languages = eZContentLanguage::prioritizedLanguages(); 00517 foreach ( $languages as $language ) 00518 { 00519 if ( ( (int) $language->attribute( 'id' ) & (int) $mask ) > 0 ) 00520 { 00521 return $language; 00522 } 00523 } 00524 return false; 00525 } 00526 00527 /** 00528 * Returns the most prioritized language from specified by \a $languageLocaleList list of language locales. 00529 * The function does the same as 'topPriorityLanguageByMask' but uses language locale list instead of language mask. 00530 * 00531 * \param languageLocaleList List of language locales to choose from. 00532 * \return eZContentLanguage object of the most prioritized language. 00533 */ 00534 static function topPriorityLanguageByLocaleList( $languageLocaleList ) 00535 { 00536 if ( is_array( $languageLocaleList ) && count( $languageLocaleList ) > 0 ) 00537 { 00538 $languages = eZContentLanguage::prioritizedLanguages(); 00539 foreach ( $languages as $language ) 00540 { 00541 if ( in_array( $language->attribute( 'locale' ), $languageLocaleList ) ) 00542 { 00543 return $language; 00544 } 00545 } 00546 } 00547 00548 return false; 00549 } 00550 00551 /** 00552 * Returns bitmap mask for the specified languages. 00553 * 00554 * \param locales Array of strings or a string specifying locale codes of the languages, e. g. 'slk-SK' or array( 'eng-GB', 'nor-NO' ) 00555 * \param setZerothBit Optional. Specifies if the 0-th bit of mask should be set. False by default. 00556 * \return Bitmap mask having set the corresponding bits for the specified languages. 00557 */ 00558 static function maskByLocale( $locales, $setZerothBit = false ) 00559 { 00560 if ( !$locales ) 00561 { 00562 return 0; 00563 } 00564 00565 if ( !is_array( $locales ) ) 00566 { 00567 $locales = array( $locales ); 00568 } 00569 00570 $mask = 0; 00571 if ( $setZerothBit ) 00572 { 00573 $mask = 1; 00574 } 00575 00576 foreach( $locales as $locale ) 00577 { 00578 $language = eZContentLanguage::fetchByLocale( $locale ); 00579 if ( $language ) 00580 { 00581 $mask += $language->attribute( 'id' ); 00582 } 00583 } 00584 00585 return (int) $mask; 00586 } 00587 00588 /** 00589 * Decodes $langMask into all languages it comprises and whether or not 00590 * the language mask signifies always available or not. 00591 * 00592 * The constituent languages are returned as an array of language ids. If 00593 * the second parameter, $returnLanguageLocale is set to TRUE, locale-codes 00594 * are used instead of language ids. 00595 * 00596 * @param int $langMask 00597 * @param boolean $returnLanguageLocale 00598 * @return array 00599 */ 00600 public static function decodeLanguageMask( $langMask, $returnLanguageLocale = false ) 00601 { 00602 $maxNumberOfLanguges = eZContentLanguage::MAX_COUNT; 00603 $maxInteger = pow( 2, $maxNumberOfLanguges ); 00604 00605 $list = array(); 00606 00607 // Applying this bit-logic on negative numbers, or numbers out of bounds 00608 // will have unexpected results. 00609 if ( $langMask < 0 or $langMask > $maxInteger or $langMask == 1 ) 00610 { 00611 // We use the default language if the situation above occurs 00612 $defaultLanguage = eZContentLanguage::topPriorityLanguage(); 00613 $langMask = $defaultLanguage->attribute( 'id' ); 00614 } 00615 00616 $alwaysAvailable = $langMask % 2; 00617 $mask = $langMask & ~1; 00618 00619 // Calculating which translations are present in the current version 00620 for ( $i = 1; $i < $maxNumberOfLanguges; ++$i ) 00621 { 00622 $newMask = 1 << $i; 00623 if ( ($newMask & $mask) > 0 ) 00624 { 00625 if ( $returnLanguageLocale ) 00626 { 00627 $list[] = eZContentLanguage::fetch( $newMask )->attribute( 'locale' ); 00628 } 00629 else 00630 { 00631 $list[] = $newMask; 00632 } 00633 } 00634 } 00635 00636 return array( 00637 'always_available' => $alwaysAvailable, 00638 'language_list' => $list 00639 ); 00640 } 00641 00642 /** 00643 * \static 00644 * Returns id of the language specified. 00645 * 00646 * \param locale String specifying locale code of the language, e. g. 'slk-SK' 00647 * \return ID of the language specified by locale or false if the language is not set on the site. 00648 */ 00649 static function idByLocale( $locale ) 00650 { 00651 $language = eZContentLanguage::fetchByLocale( $locale ); 00652 if ( $language ) 00653 { 00654 return (int)$language->attribute( 'id' ); 00655 } 00656 else 00657 { 00658 return false; 00659 } 00660 } 00661 00662 /** 00663 * Returns the SQL where-condition for selecting the rows (objects, object versions) which exist in any 00664 * of prioritized languages or are always available. 00665 * 00666 * \param languageListTable Name of the table 00667 * \param languageListAttributeName Optional. Name of the attribute in the table which contains the bitmap mask. 'language_mask' by default. 00668 * \return SQL where-condition described above. 00669 * \static 00670 */ 00671 static function languagesSQLFilter( $languageListTable, $languageListAttributeName = 'language_mask' ) 00672 { 00673 $prioritizedLanguages = eZContentLanguage::prioritizedLanguages(); 00674 $mask = 1; // 1 - always available objects 00675 foreach( $prioritizedLanguages as $language ) 00676 { 00677 $mask += $language->attribute( 'id' ); 00678 } 00679 00680 $db = eZDB::instance(); 00681 if ( $db->databaseName() == 'oracle' ) 00682 { 00683 return "\n bitand( $languageListTable.$languageListAttributeName, $mask ) > 0 \n"; 00684 } 00685 else 00686 { 00687 return "\n $languageListTable.$languageListAttributeName & $mask > 0 \n"; 00688 } 00689 } 00690 00691 /** 00692 * Returns the SQL where-condition for selecting the rows (with object names, attributes etc.) in the correct language, 00693 * i. e. in the most prioritized language from those in which an object exists. 00694 * 00695 * \param languageTable Name of the table containing the attribute with the language id. 00696 * \param languageListTable Name of the table containing the attribute with the available languages bitmap. 00697 * \param languageAttributeName Optional. Name of the attribute in $languageTable which contains 00698 * the language id. 'language_id' by default. 00699 * \param languageListAttributeName Optional. Name of the attribute in $languageListTable which contains 00700 * the bitmap mask. 'language_mask' by default. 00701 * \return SQL where-condition described above. 00702 */ 00703 static function sqlFilter( $languageTable, $languageListTable = null, $languageAttributeName = 'language_id', $languageListAttributeName = 'language_mask' ) 00704 { 00705 $db = eZDB::instance(); 00706 00707 if ( $languageListTable === null ) 00708 { 00709 $languageListTable = $languageTable; 00710 } 00711 00712 $prioritizedLanguages = eZContentLanguage::prioritizedLanguages(); 00713 if ( $db->databaseName() == 'oracle' ) 00714 { 00715 $leftSide = "bitand( $languageListTable.$languageListAttributeName - bitand( $languageListTable.$languageListAttributeName, $languageTable.$languageAttributeName ), 1 )\n"; 00716 $rightSide = "bitand( $languageTable.$languageAttributeName, 1 )\n"; 00717 } 00718 else 00719 { 00720 $leftSide = " ( ( $languageListTable.$languageListAttributeName - ( $languageListTable.$languageListAttributeName & $languageTable.$languageAttributeName ) ) & 1 )\n"; 00721 $rightSide = " ( $languageTable.$languageAttributeName & 1 )\n"; 00722 } 00723 00724 for ( $index = count( $prioritizedLanguages ) - 1, $multiplier = 2; $index >= 0; $index--, $multiplier *= 2 ) 00725 { 00726 $id = $prioritizedLanguages[$index]->attribute( 'id' ); 00727 00728 if ( $db->databaseName() == 'oracle' ) 00729 { 00730 $leftSide .= " + bitand( $languageListTable.$languageListAttributeName - bitand( $languageListTable.$languageListAttributeName, $languageTable.$languageAttributeName ), $id )"; 00731 $rightSide .= " + bitand( $languageTable.$languageAttributeName, $id )"; 00732 } 00733 else 00734 { 00735 $leftSide .= " + ( ( ( $languageListTable.$languageListAttributeName - ( $languageListTable.$languageListAttributeName & $languageTable.$languageAttributeName ) ) & $id )"; 00736 $rightSide .= " + ( ( $languageTable.$languageAttributeName & $id )"; 00737 } 00738 00739 if ( $multiplier > $id ) 00740 { 00741 $factor = $multiplier / $id; 00742 if ( $db->databaseName() == 'oracle' ) 00743 { 00744 $factorTerm = ' * ' . $factor; 00745 } 00746 else 00747 { 00748 for ( $shift = 0; $factor > 1; $factor = $factor / 2, $shift++ ) ; 00749 $factorTerm = ' << '. $shift; 00750 } 00751 $leftSide .= $factorTerm; 00752 $rightSide .= $factorTerm; 00753 } 00754 else if ( $multiplier < $id ) 00755 { 00756 $factor = $id / $multiplier; 00757 if ( $db->databaseName() == 'oracle' ) 00758 { 00759 $factorTerm = ' / ' . $factor; 00760 } 00761 else 00762 { 00763 for ( $shift = 0; $factor > 1; $factor = $factor / 2, $shift++ ) ; 00764 $factorTerm = ' >> '. $shift; 00765 } 00766 $leftSide .= $factorTerm; 00767 $rightSide .= $factorTerm; 00768 } 00769 if ( $db->databaseName() != 'oracle' ) 00770 { 00771 $leftSide .= " )\n"; 00772 $rightSide .= " )\n"; 00773 } 00774 } 00775 00776 if ( $db->databaseName() == 'oracle' ) 00777 { 00778 $sql = "bitand( $languageTable.$languageAttributeName, $languageListTable.$languageListAttributeName ) > 0"; 00779 } 00780 else 00781 { 00782 $sql = "$languageTable.$languageAttributeName & $languageListTable.$languageListAttributeName > 0"; 00783 } 00784 00785 return "\n ( $sql AND\n $leftSide <\n $rightSide ) \n"; 00786 } 00787 00788 /** 00789 * \return The count of objects containing the translation in this language. 00790 */ 00791 function objectCount() 00792 { 00793 $db = eZDB::instance(); 00794 00795 $languageID = $this->ID; 00796 if ( $db->databaseName() == 'oracle' ) 00797 { 00798 $whereSQL = "bitand( language_mask, $languageID ) > 0"; 00799 } 00800 else 00801 { 00802 $whereSQL = "language_mask & $languageID > 0"; 00803 } 00804 00805 $count = $db->arrayQuery( "SELECT COUNT(*) AS count FROM ezcontentobject WHERE $whereSQL" ); 00806 return $count[0]['count']; 00807 } 00808 00809 /** 00810 * \return The count of classes containing the translation in this language. 00811 */ 00812 function classCount() 00813 { 00814 $db = eZDB::instance(); 00815 00816 $languageID = $this->ID; 00817 if ( $db->databaseName() == 'oracle' ) 00818 { 00819 $whereSQL = "bitand( language_mask, $languageID ) > 0"; 00820 } 00821 else 00822 { 00823 $whereSQL = "language_mask & $languageID > 0"; 00824 } 00825 00826 $count = $db->arrayQuery( "SELECT COUNT(*) AS count FROM ezcontentclass WHERE $whereSQL" ); 00827 $count = $count[0]['count']; 00828 00829 return $count; 00830 } 00831 00832 00833 /** 00834 * \return The count of objects having this language as the initial/main one. 00835 */ 00836 function objectInitialCount() 00837 { 00838 $db = eZDB::instance(); 00839 00840 $languageID = $this->ID; 00841 $count = $db->arrayQuery( "SELECT COUNT(*) AS count FROM ezcontentobject WHERE initial_language_id = '$languageID'" ); 00842 $count = $count[0]['count']; 00843 00844 return $count; 00845 } 00846 00847 /** 00848 * \return Reference to itself. Kept because of the backward compatibility. 00849 */ 00850 function translation() 00851 { 00852 return $this; 00853 } 00854 00855 /** 00856 * \deprecated 00857 */ 00858 function updateObjectNames() 00859 { 00860 } 00861 00862 /** 00863 * Switches on the cronjob mode. In this mode, the languages which are not in the list of the prioritized languages 00864 * will be automatically added to it. 00865 * 00866 * \param enable Optional. If false, it will switch off the cronjob mode. True by default. 00867 */ 00868 static function setCronjobMode( $enable = true ) 00869 { 00870 $GLOBALS['eZContentLanguageCronjobMode'] = true; 00871 unset( $GLOBALS['eZContentLanguagePrioritizedLanguages'] ); 00872 } 00873 00874 /** 00875 * Switches off the cronjob mode. 00876 * 00877 * \see eZContentLanguage::setCronjobMode() 00878 */ 00879 static function clearCronjobMode() 00880 { 00881 eZContentLanguage::setCronjobMode( false ); 00882 } 00883 00884 /** 00885 * Returns the Javascript array with locale codes and names of the languages which have set the corresponding 00886 * bit in specified mask. 00887 * 00888 * \param mask Bitmap mask specifying which languages should be considered. 00889 * \return JavaScript array described above. 00890 */ 00891 static function jsArrayByMask( $mask ) 00892 { 00893 $localList = array(); 00894 $languages = eZContentLanguage::prioritizedLanguagesByMask( $mask ); 00895 foreach ( $languages as $key => $language ) 00896 { 00897 $localList[] = array( 'locale' => $language->attribute( 'locale' ), 00898 'name' => $language->attribute( 'name' ) ); 00899 } 00900 00901 if ( $localList ) 00902 { 00903 return json_encode( $localList ); 00904 } 00905 else 00906 { 00907 return false; 00908 } 00909 } 00910 00911 /** 00912 * \return The bitmap mask containing all languages, i. e. the sum of the IDs of all languages. (The 0-th bit is set.) 00913 */ 00914 static function maskForRealLanguages() 00915 { 00916 if ( !isset( $GLOBALS['eZContentLanguageMask'] ) ) 00917 { 00918 eZContentLanguage::fetchList( true ); 00919 } 00920 return $GLOBALS['eZContentLanguageMask']; 00921 } 00922 00923 /** 00924 * Removes all memory cache forcing it to read from database again for next method calls. 00925 * 00926 * \static 00927 */ 00928 static function expireCache() 00929 { 00930 unset( $GLOBALS['eZContentLanguageList'], 00931 $GLOBALS['eZContentLanguagePrioritizedLanguages'], 00932 $GLOBALS['eZContentLanguageMask'], 00933 $GLOBALS['eZContentLanguageCronjobMode'] ); 00934 00935 // With the solution to #14227 we also need to clear the cached 00936 // list of languages 00937 $cachePath = eZSys::cacheDirectory() . '/ezcontentlanguage_cache.php'; 00938 eZClusterFileHandler::instance()->fileDelete( $cachePath ); 00939 } 00940 } 00941 00942 ?>