|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2007-2011 Andreas Wolf <andreas.wolf@ikt-werk.de> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00027 00028 /** 00029 * Default implementation of a handler class for an ajax record selector. 00030 * 00031 * Normally other implementations should be inherited from this one. 00032 * queryTable() should not be overwritten under normal circumstances. 00033 * 00034 * @author Andreas Wolf <andreas.wolf@ikt-werk.de> 00035 * @author Benjamin Mack <benni@typo3.org> 00036 * 00037 */ 00038 class t3lib_TCEforms_Suggest_DefaultReceiver { 00039 /** 00040 * The name of the table to query 00041 * 00042 * @var string 00043 */ 00044 protected $table = ''; 00045 00046 /** 00047 * The name of the foreign table to query (records from this table will be used for displaying instead of the ones 00048 * from $table) 00049 * 00050 * @var string 00051 */ 00052 protected $mmForeignTable = ''; 00053 00054 /** 00055 * The select-clause to use when selecting the records (is manipulated and used by different functions, so it has to 00056 * be a global var) 00057 * 00058 * @var string 00059 */ 00060 protected $selectClause = ''; 00061 00062 /** 00063 * The statement by which records will be ordered 00064 * 00065 * @var string 00066 */ 00067 protected $orderByStatement = ''; 00068 00069 /** 00070 * Additional WHERE clause to be appended to the SQL 00071 * 00072 * @var string 00073 */ 00074 protected $addWhere = ''; 00075 00076 /** 00077 * Configuration for this selector from TSconfig 00078 * 00079 * @var array 00080 */ 00081 protected $config = array(); 00082 00083 /** 00084 * The list of pages that are allowed to perform the search for records on 00085 * 00086 * @var array of PIDs 00087 */ 00088 protected $allowedPages = array(); 00089 00090 /** 00091 * The maximum number of items to select. 00092 * 00093 * @var integer 00094 */ 00095 protected $maxItems = 10; 00096 00097 00098 /** 00099 * The constructor of this class 00100 * 00101 * @param string $table The table to query 00102 * @param array $config The configuration (TCA overlayed with TSconfig) to use for this selector 00103 * @return void 00104 */ 00105 public function __construct($table, $config) { 00106 $this->table = $table; 00107 $this->config = $config; 00108 00109 // get a list of all the pages that should be looked on 00110 if (isset($config['pidList'])) { 00111 $allowedPages = $pageIds = t3lib_div::trimExplode(',', $config['pidList']); 00112 $depth = intval($config['pidDepth']); 00113 foreach ($pageIds as $pageId) { 00114 if ($pageId > 0) { 00115 $allowedPages = t3lib_div::array_merge_recursive_overrule($allowedPages, $this->getAllSubpagesOfPage($pageId, $depth)); 00116 } 00117 } 00118 $this->allowedPages = array_unique($allowedPages); 00119 } 00120 00121 if (isset($config['maxItemsInResultList'])) { 00122 $this->maxItems = $config['maxItemsInResultList']; 00123 } 00124 00125 if ($this->table == 'pages') { 00126 $this->addWhere = ' AND ' . $GLOBALS['BE_USER']->getPagePermsClause(1); 00127 } 00128 00129 // if table is versionized, only get the records from the Live Workspace 00130 // the overlay itself of WS-records is done below 00131 if ($GLOBALS['TCA'][$this->table]['ctrl']['versioningWS'] == TRUE) { 00132 $this->addWhere .= ' AND t3ver_wsid = 0'; 00133 } 00134 00135 if (isset($config['addWhere'])) { 00136 $this->addWhere .= ' ' . $config['addWhere']; 00137 } 00138 } 00139 00140 /** 00141 * Queries a table for records and completely processes them 00142 * 00143 * Returns a two-dimensional array of almost finished records; the only need to be put into a <li>-structure 00144 * 00145 * If you subclass this class, you will most likely only want to overwrite the functions called from here, but not 00146 * this function itself 00147 * 00148 * @param array $params 00149 * @param object $ref The parent object 00150 * @return mixed array of rows or false if nothing found 00151 */ 00152 public function queryTable(&$params, $recursionCounter = 0) { 00153 $rows = array(); 00154 00155 $this->params = &$params; 00156 $start = $recursionCounter * 50; 00157 00158 $this->prepareSelectStatement(); 00159 $this->prepareOrderByStatement(); 00160 $res = $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00161 '*', 00162 $this->table, 00163 $this->selectClause, 00164 '', 00165 $this->orderByStatement, 00166 $start . ', 50'); 00167 00168 $allRowsCount = $GLOBALS['TYPO3_DB']->sql_num_rows($res); 00169 00170 if ($allRowsCount) { 00171 while (($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res))) { 00172 00173 // check if we already have collected the maximum number of records 00174 if (count($rows) > $this->maxItems) { 00175 break; 00176 } 00177 00178 $this->manipulateRecord($row); 00179 $this->makeWorkspaceOverlay($row); 00180 00181 // check if the user has access to the record 00182 if (!$this->checkRecordAccess($row, $row['uid'])) { 00183 continue; 00184 } 00185 00186 $iconPath = $this->getIcon($row); 00187 $uid = ($row['t3ver_oid'] > 0 ? $row['t3ver_oid'] : $row['uid']); 00188 00189 $path = $this->getRecordPath($row, $uid); 00190 if (strlen($path) > 30) { 00191 $croppedPath = '<abbr title="' . htmlspecialchars($path) . '">' . 00192 htmlspecialchars($GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet, $path, 10) . 00193 '...' . $GLOBALS['LANG']->csConvObj->crop($GLOBALS['LANG']->charSet, $path, -20) 00194 ) . '</abbr>'; 00195 } else { 00196 $croppedPath = htmlspecialchars($path); 00197 } 00198 00199 $label = $this->getLabel($row); 00200 $entry = array( 00201 'text' => '<span class="suggest-label">' . $label . '</span><span class="suggest-uid">[' . $uid . ']</span><br /> 00202 <span class="suggest-path">' . $croppedPath . '</span>', 00203 'table' => ($this->mmForeignTable ? $this->mmForeignTable : $this->table), 00204 'label' => $label, 00205 'path' => $path, 00206 'uid' => $uid, 00207 'icon' => $iconPath, 00208 'style' => 'background-image:url(' . $iconPath . ');', 00209 'class' => (isset($this->config['cssClass']) ? $this->config['cssClass'] : ''), 00210 ); 00211 00212 $rows[$this->table . '_' . $uid] = $this->renderRecord($row, $entry); 00213 } 00214 00215 $GLOBALS['TYPO3_DB']->sql_free_result($res); 00216 00217 // if there are less records than we need, call this function again to get more records 00218 if (count($rows) < $this->maxItems && 00219 $allRowsCount >= 50 && $recursionCounter < $this->maxItems) { 00220 $tmp = self::queryTable($params, ++$recursionCounter); 00221 $rows = array_merge($tmp, $rows); 00222 } 00223 } 00224 return $rows; 00225 } 00226 00227 /** 00228 * Prepare the statement for selecting the records which will be returned to the selector. May also return some 00229 * other records (e.g. from a mm-table) which will be used later on to select the real records 00230 * 00231 * @return void 00232 */ 00233 protected function prepareSelectStatement() { 00234 $searchWholePhrase = $this->config['searchWholePhrase']; 00235 00236 $searchString = $this->params['value']; 00237 $searchUid = intval($searchString); 00238 if (strlen($searchString)) { 00239 $searchString = $GLOBALS['TYPO3_DB']->quoteStr($searchString, $this->table); 00240 $likeCondition = ' LIKE \'' . ($searchWholePhrase ? '%' : '') . 00241 $GLOBALS['TYPO3_DB']->escapeStrForLike($searchString, $this->table) . '%\''; 00242 00243 // Search in all fields given by label or label_alt 00244 $selectFieldsList = $GLOBALS['TCA'][$this->table]['ctrl']['label'] . ',' . $GLOBALS['TCA'][$this->table]['ctrl']['label_alt']; 00245 $selectFields = t3lib_div::trimExplode(',', $selectFieldsList, TRUE); 00246 00247 $selectParts = array(); 00248 foreach ($selectFields as $field) { 00249 $selectParts[] = $field . $likeCondition; 00250 } 00251 $this->selectClause = '(' . implode(' OR ', $selectParts) . ')'; 00252 00253 if ($searchUid > 0 && $searchUid == $searchString) { 00254 $this->selectClause = '(' . $this->selectClause . ' OR uid = ' . $searchUid . ')'; 00255 } 00256 } 00257 if (isset($GLOBALS['TCA'][$this->table]['ctrl']['delete'])) { 00258 $this->selectClause .= ' AND ' . $GLOBALS['TCA'][$this->table]['ctrl']['delete'] . ' = 0'; 00259 } 00260 00261 if (count($this->allowedPages)) { 00262 $pidList = $GLOBALS['TYPO3_DB']->cleanIntArray($this->allowedPages); 00263 if (count($pidList)) { 00264 $this->selectClause .= ' AND pid IN (' . implode(', ', $pidList) . ') '; 00265 } 00266 } 00267 00268 // add an additional search condition comment 00269 if (isset($this->config['searchCondition']) && strlen($this->config['searchCondition']) > 0) { 00270 $this->selectClause .= ' AND ' . $this->config['searchCondition']; 00271 } 00272 00273 // add the global clauses to the where-statement 00274 $this->selectClause .= $this->addWhere; 00275 } 00276 00277 /** 00278 * Selects all subpages of one page, optionally only upto a certain level 00279 * 00280 * @param integer $uid The uid of the page 00281 * @param integer $depth The depth to select upto. Defaults to 99 00282 * @return array of page IDs 00283 */ 00284 protected function getAllSubpagesOfPage($uid, $depth = 99) { 00285 $pageIds = array($uid); 00286 $level = 0; 00287 00288 $pages = array($uid); 00289 00290 // fetch all 00291 while (($depth - $level) > 0 && !empty($pageIds)) { 00292 ++$level; 00293 00294 $pidList = $GLOBALS['TYPO3_DB']->cleanIntArray($pageIds); 00295 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', 'pages', 'pid IN (' . implode(', ', $pidList) . ')', '', '', '', 'uid'); 00296 if (count($rows) > 0) { 00297 $pageIds = array_keys($rows); 00298 00299 $pages = array_merge($pages, $pageIds); 00300 } else { 00301 break; 00302 } 00303 } 00304 00305 return $pages; 00306 } 00307 00308 /** 00309 * Prepares the clause by which the result elements are sorted. See description of ORDER BY in 00310 * SQL standard for reference. 00311 * 00312 * @return void 00313 */ 00314 protected function prepareOrderByStatement() { 00315 if ($GLOBALS['TCA'][$this->table]['ctrl']['label']) { 00316 $this->orderByStatement = $GLOBALS['TCA'][$this->table]['ctrl']['label']; 00317 } 00318 } 00319 00320 /** 00321 * Manipulate a record before using it to render the selector; may be used to replace a MM-relation etc. 00322 * 00323 * @param array $row 00324 */ 00325 protected function manipulateRecord(&$row) { 00326 } 00327 00328 /** 00329 * Selects whether the logged in Backend User is allowed to read a specific record 00330 */ 00331 protected function checkRecordAccess($row, $uid) { 00332 $retValue = TRUE; 00333 $table = ($this->mmForeignTable ? $this->mmForeignTable : $this->table); 00334 if ($table == 'pages') { 00335 if (!t3lib_BEfunc::readPageAccess($uid, $GLOBALS['BE_USER']->getPagePermsClause(1))) { 00336 $retValue = FALSE; 00337 } 00338 } else { 00339 if (!is_array(t3lib_BEfunc::readPageAccess($row['pid'], $GLOBALS['BE_USER']->getPagePermsClause(1)))) { 00340 $retValue = FALSE; 00341 } 00342 } 00343 return $retValue; 00344 } 00345 00346 /** 00347 * Overlay the given record with its workspace-version, if any 00348 * 00349 * @param array The record to get the workspace version for 00350 * @return void (passed by reference) 00351 */ 00352 protected function makeWorkspaceOverlay(&$row) { 00353 // check for workspace-versions 00354 if ($GLOBALS['BE_USER']->workspace != 0 && $GLOBALS['TCA'][$this->table]['ctrl']['versioningWS'] == TRUE) { 00355 t3lib_BEfunc::workspaceOL(($this->mmForeignTable ? $this->mmForeignTable : $this->table), $row); 00356 } 00357 } 00358 00359 /** 00360 * Return the icon for a record - just a wrapper for two functions from t3lib_iconWorks 00361 * 00362 * @param array $row The record to get the icon for 00363 * @return string The path to the icon 00364 */ 00365 protected function getIcon($row) { 00366 $icon = t3lib_iconWorks::getIcon(($this->mmForeignTable ? $this->mmForeignTable : $this->table), $row); 00367 return t3lib_iconWorks::skinImg('', $icon, '', 1); 00368 } 00369 00370 /** 00371 * Returns the path for a record. Is the whole path for all records except pages - for these the last part is cut 00372 * off, because it contains the pagetitle itself, which would be double information 00373 * 00374 * The path is returned uncut, cutting has to be done by calling function. 00375 * 00376 * @param array $row The row 00377 * @param array $record The record 00378 * @return string The record-path 00379 */ 00380 protected function getRecordPath(&$row, $uid) { 00381 $titleLimit = max($this->config['maxPathTitleLength'], 0); 00382 00383 if (($this->mmForeignTable ? $this->mmForeignTable : $this->table) == 'pages') { 00384 $path = t3lib_BEfunc::getRecordPath($uid, '', $titleLimit); 00385 // for pages we only want the first (n-1) parts of the path, because the n-th part is the page itself 00386 $path = substr($path, 0, strrpos($path, '/', -2)) . '/'; 00387 } else { 00388 $path = t3lib_BEfunc::getRecordPath($row['pid'], '', $titleLimit); 00389 } 00390 00391 return $path; 00392 } 00393 00394 /** 00395 * Returns a label for a given record; usually only a wrapper for t3lib_BEfunc::getRecordTitle 00396 * 00397 * @param array $row The record to get the label for 00398 * @return string The label 00399 */ 00400 protected function getLabel($row) { 00401 return t3lib_BEfunc::getRecordTitle(($this->mmForeignTable ? $this->mmForeignTable : $this->table), $row, TRUE); 00402 } 00403 00404 /** 00405 * Calls a user function for rendering the page. 00406 * 00407 * This user function should manipulate $entry, especially $entry['text']. 00408 * 00409 * @param array $row The row 00410 * @param array $entry The entry to render 00411 * @return array The rendered entry (will be put into a <li> later on 00412 */ 00413 protected function renderRecord($row, $entry) { 00414 // call renderlet if available (normal pages etc. usually don't have one) 00415 if ($this->config['renderFunc'] != '') { 00416 $params = array( 00417 'table' => $this->table, 00418 'uid' => $row['uid'], 00419 'row' => $row, 00420 'entry' => &$entry 00421 ); 00422 t3lib_div::callUserFunction($this->config['renderFunc'], $params, $this, ''); 00423 } 00424 00425 return $entry; 00426 } 00427 } 00428 00429 ?>
1.8.0