Fixed bug #9046: Nested domain linking
authorTobias Liebig <mail@etobi.de>
Fri, 6 Nov 2009 16:44:31 +0000 (16:44 +0000)
committerTobias Liebig <mail@etobi.de>
Fri, 6 Nov 2009 16:44:31 +0000 (16:44 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/trunk@6359 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
typo3/sysext/cms/ext_tables.sql
typo3/sysext/cms/locallang_tca.xml
typo3/sysext/cms/tbl_cms.php
typo3/sysext/cms/tslib/class.tslib_content.php
typo3/sysext/cms/tslib/class.tslib_fe.php

index 612ab46..621b106 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2009-11-06  Tobias Liebig <mail_typo3@etobi.de>
+
+       * Fixed bug #9046: Nested domain linking
+
 2009-11-06  Francois Suter  <francois@typo3.org>
 
        * Follow-up to #12215: Scheduler: Added GMT time difference to server time display for improved clarity
@@ -32,7 +36,7 @@
 
        * Fixed bug #12420: Log deprecated method calls (to be removed in TYPO3 4.5) (thanks to Xavier Perseguers)
 
-2009-11-05  Tobias Liebi <mail_typo3@etobi.de>
+2009-11-05  Tobias Liebig <mail_typo3@etobi.de>
 
        * Cleanup/Bugfix #11838: Hardcoded labels in t3editor
 
index 151f083..bda00f3 100755 (executable)
@@ -310,6 +310,7 @@ CREATE TABLE sys_domain (
   redirectHttpStatusCode int(4) unsigned DEFAULT '301' NOT NULL,
   sorting int(10) unsigned DEFAULT '0' NOT NULL,
   prepend_params int(10) DEFAULT '0' NOT NULL,
+  forced int(10) DEFAULT '0' NOT NULL,
 
   PRIMARY KEY (uid),
   KEY parent (pid)
index 3c10820..d17766f 100755 (executable)
                        <label index="sys_domain.redirectHttpStatusCode.303">See other (303)</label>
                        <label index="sys_domain.redirectHttpStatusCode.307">Moved temporarily (307)</label>
                        <label index="sys_domain.prepend_params">Transfer parameters to Redirect URL:</label>
+                       <label index="sys_domain.forced">Always prepend this domain in links:</label>
                        <label index="sys_template">Template</label>
                        <label index="sys_template.title">Template title:</label>
                        <label index="sys_template.root">Rootlevel:</label>
index a4b1b7e..2458617 100755 (executable)
@@ -453,10 +453,18 @@ $TCA['sys_domain'] = array(
                                'type' => 'check',
                                'default' => '0'
                        )
+               ),
+               'forced' => array(
+                       'label' => 'LLL:EXT:cms/locallang_tca.php:sys_domain.forced',
+                       'exclude' => 1,
+                       'config' => array(
+                               'type' => 'check',
+                               'default' => '1'
+                       )
                )
        ),
        'types' => array(
-               '1' => array('showitem' => 'hidden;;;;1-1-1,domainName;;1;;3-3-3,prepend_params')
+               '1' => array('showitem' => 'hidden;;;;1-1-1,domainName;;1;;3-3-3,prepend_params,forced;;;;4-4-4')
        ),
        'palettes' => array(
                '1' => array('showitem' => 'redirectTo, redirectHttpStatusCode')
index 0c69b69..c5f8380 100644 (file)
@@ -6028,7 +6028,8 @@ class tslib_cObj {
                                                        $addQueryParams .= '&cHash=' . t3lib_div::generateCHash($addQueryParams . $GLOBALS['TSFE']->linkVars);
                                                }
 
-                                               $tCR_domain = '';
+                                               $targetDomain = '';
+                                               $currentDomain = t3lib_div::getIndpEnv('HTTP_HOST');
                                                // Mount pages are always local and never link to another domain
                                                if (count($MPvarAcc))   {
                                                        // Add "&MP" var:
@@ -6056,33 +6057,56 @@ class tslib_cObj {
                                                                }
                                                        }
 
-                                                       // This checks if the linked id is in the rootline of this site and if not it will find the domain for that ID and prefix it:
-                                                       $tCR_rootline = $GLOBALS['TSFE']->sys_page->getRootLine($page['uid']);  // Gets rootline of linked-to page
-                                                       $tCR_flag = 0;
-                                                       foreach ($tCR_rootline as $tCR_data)    {
-                                                               if ($tCR_data['uid'] == $GLOBALS['TSFE']->tmpl->rootLine[0]['uid'])     {
-                                                                       $tCR_flag = 1;  // OK, it was in rootline!
-                                                                       break;
+                                                       // Find all domain records in the rootline of the target page
+                                                       $targetPageRootline = $GLOBALS['TSFE']->sys_page->getRootLine($page['uid']);
+                                                       $foundDomains = array();
+                                                       $foundForcedDomains = array();
+                                                       $targetPageRootlinePids = array();
+                                                       foreach ($targetPageRootline as $data)  {
+                                                               $targetPageRootlinePids[] = intval($data['uid']);
+                                                       }
+                                                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
+                                                               'pid, domainName, forced',
+                                                               'sys_domain',
+                                                               'pid IN (' . implode(',', $targetPageRootlinePids) . ') ' .
+                                                                       ' AND redirectTo=\'\' ' . $this->enableFields('sys_domain'),
+                                                               '',
+                                                               'sorting ASC'
+                                                       );
+                                                       // TODO maybe it makes sense to hold all sys_domain records in a cache to save additional DB querys on each typolink
+                                                       while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
+                                                               if (!isset($foundDomains[$row['pid']])) {
+                                                                       $foundDomains[$row['pid']] = preg_replace('/\/$/', '', $row['domainName']);
                                                                }
-                                                               if ($tCR_data['is_siteroot']) {
-                                                                       // Possibly subdomain inside main domain. In any case we must stop now because site root is reached.
-                                                                       break;
+                                                               if ($row['forced'] && !isset($foundForcedDomains[$row['pid']])) {
+                                                                       $foundForcedDomains[$row['pid']] = preg_replace('/\/$/', '', $row['domainName']);
                                                                }
                                                        }
-                                                       if (!$tCR_flag) {
-                                                               foreach ($tCR_rootline as $tCR_data)    {
-                                                                       $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('domainName', 'sys_domain', 'pid='.intval($tCR_data['uid']).' AND redirectTo=\'\''.$this->enableFields('sys_domain'), '', 'sorting');
-                                                                       $row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res);
-                                                                       $GLOBALS['TYPO3_DB']->sql_free_result($res);
-                                                                       if ($row)       {
-                                                                               $tCR_domain = preg_replace('/\/$/','',$row['domainName']);
+                                                       $GLOBALS['TYPO3_DB']->sql_free_result($res);
+                                                       
+                                                       // Set targetDomain to first found domain record if the target page cannot be reached within the current domain
+                                                       if (count($foundDomains) > 0 
+                                                         && (!in_array($currentDomain, $foundDomains) || count($foundForcedDomains) > 0)) {
+                                                               foreach ($targetPageRootlinePids as $pid) {
+                                                                       // Always use the 'forced' domain if we found one
+                                                                       if (isset($foundForcedDomains[$pid])) {
+                                                                               $targetDomain = $foundForcedDomains[$pid];
                                                                                break;
                                                                        }
+                                                                       // Use the first found domain record
+                                                                       if ($targetDomain === '' && isset($foundDomains[$pid])) {
+                                                                               $targetDomain = $foundDomains[$pid];
+                                                                       }
+                                                               }
+                                                               // Do not prepend the domain if its the current hostname
+                                                               if ($targetDomain === $currentDomain) {
+                                                                       $targetDomain = '';
                                                                }
                                                        }
                                                }
-                                                       // If other domain, overwrite
-                                               if (strlen($tCR_domain) && !$enableLinksAcrossDomains) {
+                                               
+                                               // If target page has a different domain and the current domain's linking scheme (e.g. simulateStaticDocuments/RealURL/...) should not be used
+                                               if (strlen($targetDomain) && !$enableLinksAcrossDomains) {
                                                        $target = isset($conf['extTarget']) ? $conf['extTarget'] : $GLOBALS['TSFE']->extTarget;
                                                        if ($conf['extTarget.']) {
                                                                $target = $this->stdWrap($target, $conf['extTarget.']);
@@ -6091,13 +6115,13 @@ class tslib_cObj {
                                                                $target = $forceTarget;
                                                        }
                                                        $LD['target'] = $target;
-                                                       $this->lastTypoLinkUrl = $this->URLqMark('http://'.$tCR_domain.'/index.php?id='.$page['uid'],$addQueryParams).$sectionMark;
-                                               } else {        // Internal link:
+                                                       $this->lastTypoLinkUrl = $this->URLqMark('http://' . $targetDomain . '/index.php?id=' . $page['uid'], $addQueryParams) . $sectionMark;
+                                               } else {        // Internal link or current domain's linking scheme should be used
                                                        if ($forceTarget) {
                                                                $target = $forceTarget;
                                                        }
-                                                       $LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $conf['no_cache'], '', '', $addQueryParams, $theTypeP, $tCR_domain);
-                                                       if (strlen($tCR_domain)) {
+                                                       $LD = $GLOBALS['TSFE']->tmpl->linkData($page, $target, $conf['no_cache'], '', '', $addQueryParams, $theTypeP, $targetDomain);
+                                                       if (strlen($targetDomain)) {
                                                                // We will add domain only if URL does not have it already.
 
                                                                if ($enableLinksAcrossDomains) {
@@ -6112,7 +6136,7 @@ class tslib_cObj {
                                                                }
                                                                $urlParts = parse_url($LD['totalURL']);
                                                                if ($urlParts['host'] == '') {
-                                                                       $LD['totalURL'] = 'http://' . $tCR_domain . ($LD['totalURL']{0} == '/' ? '' : '/') . $LD['totalURL'];
+                                                                       $LD['totalURL'] = 'http://' . $targetDomain . ($LD['totalURL']{0} == '/' ? '' : '/') . $LD['totalURL'];
                                                                }
                                                        }
                                                        $this->lastTypoLinkUrl = $this->URLqMark($LD['totalURL'],'').$sectionMark;
index 075e94c..cfdf34a 100644 (file)
                                'type' => intval($this->type),
                                'gr_list' => (string)$this->gr_list,
                                'MP' => (string)$this->MP,
-                               'cHash' => $this->cHash_array
+                               'cHash' => $this->cHash_array,
+                               'domainStartPage' => $this->domainStartPage,
                        )
                );
 
                                'type' => intval($this->type),
                                'gr_list' => (string)$this->gr_list,
                                'MP' => (string)$this->MP,
-                               'cHash' => $this->cHash_array
+                               'cHash' => $this->cHash_array,
+                               'domainStartPage' => $this->domainStartPage,
                        )
                );