eZ Publish  [trunk]
ezplanguageswitcher.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the ezpLanguageSwitcher 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 /**
00012  * Utility class for transforming URLs between siteaccesses.
00013  *
00014  * This class will generate URLs for various siteaccess, and translate
00015  * URL-aliases into other languages as necessary.
00016  */
00017 class ezpLanguageSwitcher implements ezpLanguageSwitcherCapable
00018 {
00019     protected $origUrl;
00020     protected $userParamString;
00021 
00022     protected $destinationSiteAccess;
00023     protected $destinationLocale;
00024 
00025     protected $baseDestinationUrl;
00026 
00027     protected $destinationSiteAccessIni;
00028 
00029     function __construct( $params = null )
00030     {
00031         if ( $params === null )
00032         {
00033             return $this;
00034         }
00035 
00036         // Removing the first part, which is the SA param.
00037         array_shift( $params['Parameters'] );
00038         $this->origUrl = join( $params['Parameters'] , '/' );
00039 
00040         $this->userParamString = '';
00041         $userParams = $params['UserParameters'];
00042         foreach ( $userParams as $key => $value )
00043         {
00044             $this->userParamString .= "/($key)/$value";
00045         }
00046     }
00047 
00048     /**
00049      * Get instance siteaccess specific site.ini
00050      *
00051      * @param string $sa
00052      * @return void
00053      */
00054     protected function getSiteAccessIni()
00055     {
00056         if ( $this->destinationSiteAccessIni === null )
00057         {
00058             $this->destinationSiteAccessIni = eZSiteAccess::getIni( $this->destinationSiteAccess, 'site.ini' );
00059         }
00060         return $this->destinationSiteAccessIni;
00061     }
00062 
00063     /**
00064      * Checks if the given $url points to a module.
00065      *
00066      * We use this method to check whether we should pass on the original URL
00067      * to the destination translation siteaccess.
00068      *
00069      * @param string $url
00070      * @return bool
00071      */
00072     protected function isUrlPointingToModule( $url )
00073     {
00074         // Grab the first URL element, representing the possible module name
00075         $urlElements = explode( '/', $url );
00076         $moduleName = $urlElements[0];
00077 
00078         // Look up for a match in the module list
00079         $moduleIni = eZINI::instance( 'module.ini' );
00080         $availableModules = $moduleIni->variable( 'ModuleSettings', 'ModuleList' );
00081         return in_array( $moduleName, $availableModules, true );
00082     }
00083 
00084     /**
00085      * Checks if the current content object locale is available in destination siteaccess.
00086      *
00087      * This is used to check whether we should pass on the original URL to the
00088      * destination translation siteaccess, when no translation of an object
00089      * exists in the destination locale.
00090      *
00091      * If the current content object locale exists as a fallback in the
00092      * destination siteaccess, the original URL should be available there as
00093      * well.
00094      *
00095      * @return bool
00096      */
00097     protected function isLocaleAvailableAsFallback()
00098     {
00099         $currentContentObjectLocale = eZINI::instance()->variable( 'RegionalSettings', 'ContentObjectLocale' );
00100         $saIni = $this->getSiteAccessIni();
00101         $siteLanguageList = $saIni->variable( 'RegionalSettings', 'SiteLanguageList' );
00102         return in_array( $currentContentObjectLocale, $siteLanguageList, true );
00103     }
00104 
00105     /**
00106      * Returns URL alias for the specified <var>$locale</var>
00107      *
00108      * @param string $url
00109      * @param string $locale
00110      * @return void
00111      */
00112     public function destinationUrl()
00113     {
00114         $nodeId = $this->origUrl;
00115         if ( !is_numeric( $this->origUrl ) )
00116         {
00117             $nodeId = eZURLAliasML::fetchNodeIDByPath( $this->origUrl );
00118         }
00119         $destinationElement = eZURLAliasML::fetchByAction( 'eznode', $nodeId, $this->destinationLocale, false );
00120 
00121         if ( empty( $destinationElement ) || ( !isset( $destinationElement[0] ) && !( $destinationElement[0] instanceof eZURLAliasML ) ) )
00122         {
00123             // If the return of fetchByAction is empty, it can mean a couple
00124             // of different things:
00125             // Either we are looking at a module, and we should pass the
00126             // original URL on
00127             //
00128             // Or we are looking at URL which does not exist in the
00129             // destination siteaccess, for instance an untranslated object. In
00130             // which case we will point to the root of the site, unless it is
00131             // available as a fallback.
00132 
00133             if ( $this->isUrlPointingToModule( $this->origUrl ) ||
00134                  $this->isLocaleAvailableAsFallback() )
00135             {
00136                 // We have a module, we're keeping the orignal url.
00137                 $urlAlias = $this->origUrl;
00138             }
00139             else
00140             {
00141                 // We probably have an untranslated object, which is not
00142                 // available with SiteLanguageList setting, we direct to root.
00143                 $urlAlias = '';
00144             }
00145         }
00146         else
00147         {
00148             // Translated object found, forwarding to new URL.
00149 
00150             $saIni = $this->getSiteAccessIni();
00151             $siteLanguageList = $saIni->variable( 'RegionalSettings', 'SiteLanguageList' );
00152 
00153             $urlAlias = $destinationElement[0]->getPath( $this->destinationLocale, $siteLanguageList );
00154             $urlAlias .= $this->userParamString;
00155         }
00156 
00157         $this->baseDestinationUrl = rtrim( $this->baseDestinationUrl, '/' );
00158 
00159         if ( $GLOBALS['eZCurrentAccess']['type'] === eZSiteAccess::TYPE_URI )
00160         {
00161             $finalUrl = $this->baseDestinationUrl . '/' . $this->destinationSiteAccess . '/' . $urlAlias;
00162         }
00163         else
00164         {
00165             $finalUrl = $this->baseDestinationUrl . '/' . $urlAlias;
00166         }
00167         return $finalUrl;
00168     }
00169 
00170     /**
00171      * Sets the siteaccess name, $saName, we want to redirect to.
00172      *
00173      * @param string $saName
00174      * @return void
00175      */
00176     public function setDestinationSiteAccess( $saName )
00177     {
00178         $this->destinationSiteAccess = $saName;
00179     }
00180 
00181     /**
00182      * This is a hook which is called by the language switcher module on
00183      * implementation classes.
00184      *
00185      * In this implementation it is doing initialisation as an example.
00186      *
00187      * @return void
00188      */
00189     public function process()
00190     {
00191         $saIni = $this->getSiteAccessIni();
00192         $this->destinationLocale = $saIni->variable( 'RegionalSettings', 'ContentObjectLocale' );
00193 
00194         // Detect the type of siteaccess we are dealing with. Initially URI and Host are supported.
00195         // We don't want the siteaccess part here, since we are inserting our siteaccess name.
00196         $indexFile = trim( eZSys::indexFile( false ), '/' );
00197         switch ( $GLOBALS['eZCurrentAccess']['type'] )
00198         {
00199             case eZSiteAccess::TYPE_URI:
00200                 eZURI::transformURI( $host, true, 'full' );
00201                 break;
00202 
00203             default:
00204                 $host = $saIni->variable( 'SiteSettings', 'SiteURL' );
00205                 $host = eZSys::serverProtocol()."://".$host;
00206                 break;
00207         }
00208         $this->baseDestinationUrl = "{$host}{$indexFile}";
00209     }
00210 
00211     /**
00212      * Creates an array of corresponding language switcher links and logical names.
00213      *
00214      * This mapping is set up in site.ini.[RegionalSettings].TranslationSA.
00215      * The purpose of this method is to assist creation of language switcher
00216      * links into the available translation siteaccesses on the system.
00217      *
00218      * This is used by the language_switcher template operator.
00219      *
00220      * @param string $url
00221      * @return void
00222      */
00223     public static function setupTranslationSAList( $url = null )
00224     {
00225         $ini = eZINI::instance();
00226         if ( !$ini->hasVariable( 'RegionalSettings', 'TranslationSA' ) )
00227         {
00228             return array();
00229         }
00230 
00231         $ret = array();
00232         $translationSiteAccesses = $ini->variable( 'RegionalSettings', 'TranslationSA' );
00233         foreach ( $translationSiteAccesses as $siteAccessName => $translationName )
00234         {
00235             $switchLanguageLink = "/switchlanguage/to/{$siteAccessName}/";
00236             if ( $url !== null && ( is_string( $url ) || is_numeric( $url ) ) )
00237             {
00238                 $switchLanguageLink .= $url;
00239             }
00240             $ret[$siteAccessName] = array(
00241                 'url' => $switchLanguageLink,
00242                 'text' => $translationName,
00243                 'locale' => eZSiteAccess::getIni( $siteAccessName )->variable( 'RegionalSettings', 'ContentObjectLocale' )
00244              );
00245         }
00246         return $ret;
00247     }
00248 }
00249 
00250 ?>