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