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