[TASK] Use arrays in str_replace() calls
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / ContentObject / SearchResultContentObject.php
index 4f654e8..81c9b4e 100644 (file)
@@ -4,7 +4,7 @@ namespace TYPO3\CMS\Frontend\ContentObject;
 /***************************************************************
  *  Copyright notice
  *
- *  (c) 1999-2011 Kasper Skårhøj (kasperYYYY@typo3.com)
+ *  (c) 1999-2013 Kasper Skårhøj (kasperYYYY@typo3.com)
  *  All rights reserved
  *
  *  This script is part of the TYPO3 project. The TYPO3 project is
@@ -27,25 +27,12 @@ namespace TYPO3\CMS\Frontend\ContentObject;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 /**
- * Searching in database tables, typ. "pages" and "tt_content"
+ * Search class used for the content object SEARCHRESULT
+ * and searching in database tables, typ. "pages" and "tt_content"
  * Used to generate search queries for TypoScript.
  * The class is included from "class.tslib_pagegen.php" based on whether there has been detected content in the GPvar "sword"
- *
- * Revised for TYPO3 3.6 June/2003 by Kasper Skårhøj
- *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- * @author René Fritz <r.fritz@colorcube.de>
- */
-/**
- * Search class used for the content object SEARCHRESULT
- *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
- * @package TYPO3
- * @subpackage tslib
- * @see        tslib_cObj::SEARCHRESULT()
  */
-class SearchResultContentObject {
-
+class SearchResultContentObject extends \TYPO3\CMS\Frontend\ContentObject\AbstractContentObject {
        /**
         * @todo Define visibility
         */
@@ -137,6 +124,182 @@ class SearchResultContentObject {
        public $listOfSearchFields = '';
 
        /**
+        * Override default constructor to make it possible to instantiate this
+        * class for indexed_search
+        *
+        * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj
+        */
+       public function __construct(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $cObj = NULL) {
+               if (!is_null($cObj)) {
+                       $this->cObj = $cObj;
+                       $this->fileFactory = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance();
+               }
+       }
+
+       /**
+        * Rendering the cObject, SEARCHRESULT
+        *
+        * @param array $conf Array of TypoScript properties
+        * @return string Output
+        */
+       public function render($conf = array()) {
+               if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('sword') && \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scols')) {
+                       $this->register_and_explode_search_string(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('sword'));
+                       $this->register_tables_and_columns(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scols'), $conf['allowedCols']);
+                       // Depth
+                       $depth = 100;
+                       // The startId is found
+                       $theStartId = 0;
+                       if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype'))) {
+                               $temp_theStartId = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype');
+                               $rootLine = $GLOBALS['TSFE']->sys_page->getRootLine($temp_theStartId);
+                               // The page MUST have a rootline with the Level0-page of the current site inside!!
+                               foreach ($rootLine as $val) {
+                                       if ($val['uid'] == $GLOBALS['TSFE']->tmpl->rootLine[0]['uid']) {
+                                               $theStartId = $temp_theStartId;
+                                       }
+                               }
+                       } elseif (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype')) {
+                               if (substr(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype'), 0, 1) == 'L') {
+                                       $pointer = intval(substr(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype'), 1));
+                                       $theRootLine = $GLOBALS['TSFE']->tmpl->rootLine;
+                                       // location Data:
+                                       $locDat_arr = explode(':', \TYPO3\CMS\Core\Utility\GeneralUtility::_POST('locationData'));
+                                       $pId = intval($locDat_arr[0]);
+                                       if ($pId) {
+                                               $altRootLine = $GLOBALS['TSFE']->sys_page->getRootLine($pId);
+                                               ksort($altRootLine);
+                                               if (count($altRootLine)) {
+                                                       // Check if the rootline has the real Level0 in it!!
+                                                       $hitRoot = 0;
+                                                       $theNewRoot = array();
+                                                       foreach ($altRootLine as $val) {
+                                                               if ($hitRoot || $val['uid'] == $GLOBALS['TSFE']->tmpl->rootLine[0]['uid']) {
+                                                                       $hitRoot = 1;
+                                                                       $theNewRoot[] = $val;
+                                                               }
+                                                       }
+                                                       if ($hitRoot) {
+                                                               // Override the real rootline if any thing
+                                                               $theRootLine = $theNewRoot;
+                                                       }
+                                               }
+                                       }
+                                       $key = $this->cObj->getKey($pointer, $theRootLine);
+                                       $theStartId = $theRootLine[$key]['uid'];
+                               }
+                       }
+                       if (!$theStartId) {
+                               // If not set, we use current page
+                               $theStartId = $GLOBALS['TSFE']->id;
+                       }
+                       // Generate page-tree
+                       $this->pageIdList .= $this->cObj->getTreeList(-1 * $theStartId, $depth);
+                       $endClause = 'pages.uid IN (' . $this->pageIdList . ')
+                               AND pages.doktype in (' . $GLOBALS['TYPO3_CONF_VARS']['FE']['content_doktypes'] . ($conf['addExtUrlsAndShortCuts'] ? ',3,4' : '') . ')
+                               AND pages.no_search=0' . $this->cObj->enableFields($this->fTable) . $this->cObj->enableFields('pages');
+                       if ($conf['languageField.'][$this->fTable]) {
+                               // (using sys_language_uid which is the ACTUAL language of the page.
+                               // sys_language_content is only for selecting DISPLAY content!)
+                               $endClause .= ' AND ' . $this->fTable . '.' . $conf['languageField.'][$this->fTable] . ' = ' . intval($GLOBALS['TSFE']->sys_language_uid);
+                       }
+                       // Build query
+                       $this->build_search_query($endClause);
+                       // Count...
+                       if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scount'))) {
+                               $this->res_count = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scount');
+                       } else {
+                               $this->count_query();
+                       }
+                       // Range
+                       $spointer = intval(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('spointer'));
+                       $range = isset($conf['range.']) ? $this->cObj->stdWrap($conf['range'], $conf['range.']) : $conf['range'];
+                       if ($range) {
+                               $theRange = intval($range);
+                       } else {
+                               $theRange = 20;
+                       }
+                       // Order By:
+                       $noOrderBy = isset($conf['noOrderBy.']) ? $this->cObj->stdWrap($conf['noOrderBy'], $conf['noOrderBy.']) : $conf['noOrderBy'];
+                       if (!$noOrderBy) {
+                               $this->queryParts['ORDERBY'] = 'pages.lastUpdated, pages.tstamp';
+                       }
+                       $this->queryParts['LIMIT'] = $spointer . ',' . $theRange;
+                       // Search...
+                       $this->execute_query();
+                       if ($GLOBALS['TYPO3_DB']->sql_num_rows($this->result)) {
+                               $GLOBALS['TSFE']->register['SWORD_PARAMS'] = $this->get_searchwords();
+                               $total = $this->res_count;
+                               $rangeLow = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($spointer + 1, 1, $total);
+                               $rangeHigh = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($spointer + $theRange, 1, $total);
+                               // prev/next url:
+                               $target = isset($conf['target.']) ? $this->cObj->stdWrap($conf['target'], $conf['target.']) : $conf['target'];
+                               $LD = $GLOBALS['TSFE']->tmpl->linkData($GLOBALS['TSFE']->page, $target, 1, '', '', $this->cObj->getClosestMPvalueForPage($GLOBALS['TSFE']->page['uid']));
+                               $targetPart = $LD['target'] ? ' target="' . htmlspecialchars($LD['target']) . '"' : '';
+                               $urlParams = $this->cObj->URLqMark($LD['totalURL'], '&sword=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('sword')) . '&scols=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('scols')) . '&stype=' . rawurlencode(\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('stype')) . '&scount=' . $total);
+                               // substitution:
+                               $result = str_replace(
+                                       array(
+                                               '###RANGELOW###',
+                                               '###RANGEHIGH###',
+                                               '###TOTAL###'
+                                       ),
+                                       array(
+                                               $rangeLow,
+                                               $rangeHigh,
+                                               $total
+                                       ),
+                                       $this->cObj->cObjGetSingle($conf['layout'], $conf['layout.'], 'layout')
+                               );
+                               if ($rangeHigh < $total) {
+                                       $next = $this->cObj->cObjGetSingle($conf['next'], $conf['next.'], 'next');
+                                       $next = '<a href="' . htmlspecialchars(($urlParams . '&spointer=' . ($spointer + $theRange))) . '"' . $targetPart . $GLOBALS['TSFE']->ATagParams . '>' . $next . '</a>';
+                               } else {
+                                       $next = '';
+                               }
+                               $result = str_replace('###NEXT###', $next, $result);
+                               if ($rangeLow > 1) {
+                                       $prev = $this->cObj->cObjGetSingle($conf['prev'], $conf['prev.'], 'prev');
+                                       $prev = '<a href="' . htmlspecialchars(($urlParams . '&spointer=' . ($spointer - $theRange))) . '"' . $targetPart . $GLOBALS['TSFE']->ATagParams . '>' . $prev . '</a>';
+                               } else {
+                                       $prev = '';
+                               }
+                               $result = str_replace('###PREV###', $prev, $result);
+                               // Searching result
+                               $theValue = $this->cObj->cObjGetSingle($conf['resultObj'], $conf['resultObj.'], 'resultObj');
+                               $cObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectRenderer');
+                               $cObj->setParent($this->cObj->data, $this->cObj->currentRecord);
+                               $renderCode = '';
+                               while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($this->result)) {
+                                       // versionOL() here? This is search result displays, is that possible to preview anyway?
+                                       // Or are records selected here already future versions?
+                                       $cObj->start($row);
+                                       $renderCode .= $cObj->cObjGetSingle($conf['renderObj'], $conf['renderObj.'], 'renderObj');
+                               }
+                               $renderWrap = isset($conf['renderWrap.']) ? $this->cObj->stdWrap($conf['renderWrap'], $conf['renderWrap.']) : $conf['renderWrap'];
+                               $theValue .= $this->cObj->wrap($renderCode, $renderWrap);
+                               $theValue = str_replace('###RESULT###', $theValue, $result);
+                       } else {
+                               $theValue = $this->cObj->cObjGetSingle($conf['noResultObj'], $conf['noResultObj.'], 'noResultObj');
+                       }
+                       $GLOBALS['TT']->setTSlogMessage('Search in fields:   ' . $this->listOfSearchFields);
+                       // Wrapping
+                       $content = $theValue;
+                       $wrap = isset($conf['wrap.']) ? $this->cObj->stdWrap($conf['wrap'], $conf['wrap.']) : $conf['wrap'];
+                       if ($wrap) {
+                               $content = $this->cObj->wrap($content, $wrap);
+                       }
+                       if (isset($conf['stdWrap.'])) {
+                               $content = $this->cObj->stdWrap($content, $conf['stdWrap.']);
+                       }
+                       // Returning, do not cache the result of the search
+                       $GLOBALS['TSFE']->set_no_cache('Search result page');
+                       return $content;
+               }
+               return '';
+       }
+
+       /**
         * Creates the $this->tables-array.
         * The 'pages'-table is ALWAYS included as the search is page-based. Apart from this there may be one and only one table, joined with the pages-table. This table is the first table mentioned in the requested-list. If any more tables are set here, they are ignored.
         *
@@ -161,7 +324,7 @@ class SearchResultContentObject {
                foreach ($aCols as $k => $v) {
                        $aCols[$k] = trim($v);
                        $parts = explode('.', $aCols[$k]);
-                       $this->tables[$parts[0]]['resultfields'][] = ($parts[1] . ' AS ') . str_replace('.', '_', $aCols[$k]);
+                       $this->tables[$parts[0]]['resultfields'][] = $parts[1] . ' AS ' . str_replace('.', '_', $aCols[$k]);
                        $this->tables[$parts[0]]['fkey'] = 'pid';
                }
                $this->fTable = '';
@@ -195,7 +358,7 @@ class SearchResultContentObject {
                                foreach ($subparts as $piece) {
                                        $piece = trim($piece);
                                        if ($piece) {
-                                               $out[] = ($parts[0] . '.') . $piece;
+                                               $out[] = $parts[0] . '.' . $piece;
                                        }
                                }
                        }
@@ -249,7 +412,7 @@ class SearchResultContentObject {
         */
        public function split($origSword, $specchars = '+-', $delchars = '+.,-') {
                $sword = $origSword;
-               $specs = ('[' . preg_quote($specchars, '/')) . ']';
+               $specs = '[' . preg_quote($specchars, '/') . ']';
                // As long as $sword is TRUE (that means $sword MUST be reduced little by little until its empty inside the loop!)
                while ($sword) {
                        // There was a double-quote and we will then look for the ending quote.
@@ -260,13 +423,13 @@ class SearchResultContentObject {
                                preg_match('/^[^"]*/', $sword, $reg);
                                // reg[0] is the value, should not be trimmed
                                $value[] = $reg[0];
-                               $sword = preg_replace(('/^' . preg_quote($reg[0], '/')) . '/', '', $sword);
+                               $sword = preg_replace('/^' . preg_quote($reg[0], '/') . '/', '', $sword);
                                // Removes last double-quote
                                $sword = trim(preg_replace('/^"/', '', $sword));
-                       } elseif (preg_match(('/^' . $specs) . '/', $sword, $reg)) {
+                       } elseif (preg_match('/^' . $specs . '/', $sword, $reg)) {
                                $value[] = $reg[0];
                                // Removes = sign
-                               $sword = trim(preg_replace(('/^' . $specs) . '/', '', $sword));
+                               $sword = trim(preg_replace('/^' . $specs . '/', '', $sword));
                        } elseif (preg_match('/[\\+\\-]/', $sword)) {
                                // Check if $sword contains + or -
                                // + and - shall only be interpreted as $specchars when there's whitespace before it
@@ -283,11 +446,11 @@ class SearchResultContentObject {
                                $sword = implode(' ', $a_sword);
                        } else {
                                // There are no double-quotes around the value. Looking for next (space) or special char.
-                               preg_match(('/^[^ ' . preg_quote($specchars, '/')) . ']*/', $sword, $reg);
+                               preg_match('/^[^ ' . preg_quote($specchars, '/') . ']*/', $sword, $reg);
                                // Delete $delchars at end of string
                                $word = rtrim(trim($reg[0]), $delchars);
                                $value[] = $word;
-                               $sword = trim(preg_replace(('/^' . preg_quote($reg[0], '/')) . '/', '', $sword));
+                               $sword = trim(preg_replace('/^' . preg_quote($reg[0], '/') . '/', '', $sword));
                        }
                }
                return $value;
@@ -301,7 +464,7 @@ class SearchResultContentObject {
         * @param string $endClause Some extra conditions that the search must match.
         * @return boolean Returns TRUE no matter what - sweet isn't it!
         * @access private
-        * @see         tslib_cObj::SEARCHRESULT()
+        * @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::SEARCHRESULT()
         * @todo Define visibility
         */
        public function build_search_query($endClause) {
@@ -332,7 +495,7 @@ class SearchResultContentObject {
                                        $resultfields = $tables[$key]['resultfields'];
                                        if (is_array($resultfields)) {
                                                foreach ($resultfields as $key2 => $val2) {
-                                                       $fieldArray[] = ($key . '.') . $val2;
+                                                       $fieldArray[] = $key . '.' . $val2;
                                                }
                                        }
                                }
@@ -340,16 +503,16 @@ class SearchResultContentObject {
                                $this->queryParts['FROM'] = implode(',', $tableArray);
                                // Set join WHERE parts:
                                $whereArray = array();
-                               $primary_table_and_key = ($primary_table . '.') . $tables[$primary_table]['primary_key'];
+                               $primary_table_and_key = $primary_table . '.' . $tables[$primary_table]['primary_key'];
                                $primKeys = array();
                                foreach ($tables as $key => $val) {
                                        $fkey = $tables[$key]['fkey'];
                                        if ($fkey) {
-                                               $primKeys[] = ((($key . '.') . $fkey) . '=') . $primary_table_and_key;
+                                               $primKeys[] = $key . '.' . $fkey . '=' . $primary_table_and_key;
                                        }
                                }
                                if (count($primKeys)) {
-                                       $whereArray[] = ('(' . implode(' OR ', $primKeys)) . ')';
+                                       $whereArray[] = '(' . implode(' OR ', $primKeys) . ')';
                                }
                                // Additional where clause:
                                if (trim($endClause)) {
@@ -360,7 +523,7 @@ class SearchResultContentObject {
                                if (!$query_part) {
                                        $query_part = '(0!=0)';
                                }
-                               $whereArray[] = ('(' . $query_part) . ')';
+                               $whereArray[] = '(' . $query_part . ')';
                                // Implode where clauses:
                                $this->queryParts['WHERE'] = implode(' AND ', $whereArray);
                                // Group by settings:
@@ -394,14 +557,14 @@ class SearchResultContentObject {
                                        $searchfields = $this->tables[$key3]['searchfields'];
                                        if (is_array($searchfields)) {
                                                foreach ($searchfields as $key2 => $val2) {
-                                                       $this->listOfSearchFields .= (($key3 . '.') . $val2) . ',';
-                                                       $sub_query_part[] = (((($key3 . '.') . $val2) . ' LIKE \'%') . $GLOBALS['TYPO3_DB']->quoteStr($s_sword, $key3)) . '%\'';
+                                                       $this->listOfSearchFields .= $key3 . '.' . $val2 . ',';
+                                                       $sub_query_part[] = $key3 . '.' . $val2 . ' LIKE \'%' . $GLOBALS['TYPO3_DB']->quoteStr($s_sword, $key3) . '%\'';
                                                }
                                        }
                                }
                                if (count($sub_query_part)) {
                                        $main_query_part[] = $this->sword_array[$key]['oper'];
-                                       $main_query_part[] = ('(' . implode(' OR ', $sub_query_part)) . ')';
+                                       $main_query_part[] = '(' . implode(' OR ', $sub_query_part) . ')';
                                }
                        }
                        if (count($main_query_part)) {
@@ -500,6 +663,3 @@ class SearchResultContentObject {
        }
 
 }
-
-
-?>
\ No newline at end of file