Fixed bug #14771: Updates for taskcenter, sys_action, impexp (Thanks to Georg Ringer)
[Packages/TYPO3.CMS.git] / t3lib / tceforms / class.t3lib_tceforms_suggest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2007-2010 Andreas Wolf <andreas.wolf@ikt-werk.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * TCEforms wizard for rendering an AJAX selector for records
29 *
30 * $Id$
31 *
32 * @author Andreas Wolf <andreas.wolf@ikt-werk.de>
33 * @author Benjamin Mack <benni@typo3.org>
34 */
35
36 class t3lib_TCEforms_Suggest {
37 // count the number of ajax selectors used
38 public $suggestCount = 0;
39 public $cssClass = 'typo3-TCEforms-suggest';
40 public $TCEformsObj; // reference to t3lib_tceforms
41
42
43 /**
44 * Initialize an instance of t3lib_TCEforms_suggest
45 *
46 * @param t3lib_TCEforms $tceForms Reference to an TCEforms instance
47 * @return void
48 */
49 public function init(&$tceForms) {
50 $this->TCEformsObj =& $tceForms;
51 }
52
53 /**
54 * Renders an ajax-enabled text field. Also adds required JS
55 *
56 * @param string $fieldname The fieldname in the form
57 * @param string $table The table we render this selector for
58 * @param string $field The field we render this selector for
59 * @param array $row The row which is currently edited
60 * @param array $config The TSconfig of the field
61 * @return string The HTML code for the selector
62 */
63 public function renderSuggestSelector($fieldname, $table, $field, array $row, array $config) {
64 $this->suggestCount++;
65
66 $containerCssClass = $this->cssClass . ' ' . $this->cssClass . '-position-right';
67 $suggestId = 'suggest-' . $table . '-' . $field . '-' . $row['uid'];
68
69 $selector = '
70 <div class="' . $containerCssClass . '" id="' . $suggestId . '">
71 <input type="text" id="' . $fieldname . 'Suggest" value="' .
72 $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.findRecord') . '" class="' . $this->cssClass . '-search" />
73 <div class="' . $this->cssClass . '-indicator" style="display: none;" id="' . $fieldname . 'SuggestIndicator">
74 <img src="' . $GLOBALS['BACK_PATH'] . 'gfx/spinner.gif" alt="' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:alttext.suggestSearching') . '" />
75 </div>
76 <div class="' . $this->cssClass . '-choices" style="display: none;" id="' . $fieldname . 'SuggestChoices"></div>
77
78 </div>';
79
80 // get minimumCharacters from TCA
81 if (isset($config['fieldConf']['config']['wizards']['suggest']['default']['minimumCharacters'])) {
82 $minChars = intval($config['fieldConf']['config']['wizards']['suggest']['default']['minimumCharacters']);
83 }
84 // overwrite it with minimumCharacters from TSConfig (TCEFORM) if given
85 if (isset($config['fieldTSConfig']['suggest.']['default.']['minimumCharacters'])) {
86 $minChars = intval($config['fieldTSConfig']['suggest.']['default.']['minimumCharacters']);
87 }
88 $minChars = ($minChars > 0 ? $minChars : 2);
89
90 // replace "-" with ucwords for the JS object name
91 $jsObj = str_replace(' ', '', ucwords(str_replace('-', ' ', t3lib_div::strtolower($suggestId))));
92 $this->TCEformsObj->additionalJS_post[] = '
93 var ' . $jsObj . ' = new TCEForms.Suggest("' . $fieldname . '", "' . $table . '", "' . $field .
94 '", "' . $row['uid'] . '", ' . $row['pid'] . ', ' . $minChars . ');
95 ' . $jsObj . '.defaultValue = "' . t3lib_div::slashJS($GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.findRecord')) . '";
96 ';
97
98 return $selector;
99 }
100
101 /**
102 * Ajax handler for the "suggest" feature in TCEforms.
103 *
104 * @param array $params The parameters from the AJAX call
105 * @param TYPO3AJAX $ajaxObj The AJAX object representing the AJAX call
106 * @return void
107 */
108 public function processAjaxRequest($params, &$ajaxObj) {
109
110 // get parameters from $_GET/$_POST
111 $search = t3lib_div::_GP('value');
112 $table = t3lib_div::_GP('table');
113 $field = t3lib_div::_GP('field');
114 $uid = t3lib_div::_GP('uid');
115 $pageId = t3lib_div::_GP('pid');
116
117 t3lib_div::loadTCA($table);
118
119 // If the $uid is numeric, we have an already existing element, so get the
120 // TSconfig of the page itself or the element container (for non-page elements)
121 // otherwise it's a new element, so use given id of parent page (i.e., don't modify it here)
122 if (is_numeric($uid)) {
123 if ($table == 'pages') {
124 $pageId = $uid;
125 } else {
126 $row = t3lib_BEfunc::getRecord($table, $uid);
127 $pageId = $row['pid'];
128 }
129 }
130
131 $TSconfig = t3lib_BEfunc::getPagesTSconfig($pageId);
132 $queryTables = array();
133 $foreign_table_where = '';
134 $wizardConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config']['wizards']['suggest'];
135 if (isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['allowed'])) {
136 $queryTables = t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$field]['config']['allowed']);
137 } elseif (isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table'])) {
138 $queryTables = array($GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table']);
139 $foreign_table_where = $GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table_where'];
140 // strip ORDER BY clause
141 $foreign_table_where = trim(preg_replace('/ORDER[[:space:]]+BY.*/i', '', $foreign_table_where));
142 }
143 $resultRows = array();
144
145 // fetch the records for each query table. A query table is a table from which records are allowed to
146 // be added to the TCEForm selector, originally fetched from the "allowed" config option in the TCA
147 foreach ($queryTables as $queryTable) {
148 t3lib_div::loadTCA($queryTable);
149
150 // if the table does not exist, skip it
151 if (!is_array($GLOBALS['TCA'][$queryTable]) || !count($GLOBALS['TCA'][$queryTable])) {
152 continue;
153 }
154 $config = (array)$wizardConfig['default'];
155
156 if (is_array($wizardConfig[$queryTable])) {
157 $config = t3lib_div::array_merge_recursive_overrule($config, $wizardConfig[$queryTable]);
158 }
159
160
161 // merge the configurations of different "levels" to get the working configuration for this table and
162 // field (i.e., go from the most general to the most special configuration)
163 if (is_array($TSconfig['TCEFORM.']['suggest.']['default.'])) {
164 $config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.']['default.']);
165 }
166
167 if (is_array($TSconfig['TCEFORM.']['suggest.'][$queryTable.'.'])) {
168 $config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.'][$queryTable.'.']);
169 }
170
171 // use $table instead of $queryTable here because we overlay a config
172 // for the input-field here, not for the queried table
173 if (is_array($TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.']['default.'])) {
174 $config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.']['default.']);
175 }
176 if (is_array($TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.'][$queryTable.'.'])) {
177 $config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.'][$queryTable.'.']);
178 }
179
180 //process addWhere
181 if (!isset($config['addWhere']) && $foreign_table_where) {
182 $config['addWhere'] = $foreign_table_where;
183 }
184 if (isset($config['addWhere'])) {
185 $config['addWhere'] = strtr(' ' . $config['addWhere'], array(
186 '###THIS_UID###' => intval($uid),
187 '###CURRENT_PID###' => intval($pageId),
188 ));
189 }
190 // instantiate the class that should fetch the records for this $queryTable
191 $receiverClassName = $config['receiverClass'];
192 if (!class_exists($receiverClassName)) {
193 $receiverClassName = 't3lib_TCEforms_Suggest_DefaultReceiver';
194 }
195 $receiverObj = t3lib_div::makeInstance($receiverClassName, $queryTable, $config);
196
197 $params = array('value' => $search);
198 $rows = $receiverObj->queryTable($params);
199
200 if (empty($rows)) {
201 continue;
202 }
203 $resultRows = t3lib_div::array_merge($resultRows, $rows);
204 unset($rows);
205 }
206
207 $listItems = array();
208 if (count($resultRows) > 0) {
209 // traverse all found records and sort them
210 $rowsSort = array();
211 foreach ($resultRows as $key => $row) {
212 $rowsSort[$key] = $row['text'];
213 }
214 asort($rowsSort);
215 $rowsSort = array_keys($rowsSort);
216
217 // Limit the number of items in the result list
218 $maxItems = $config['maxItemsInResultList'] ? $config['maxItemsInResultList'] : 10;
219 $maxItems = min(count($resultRows), $maxItems);
220
221 // put together the selector entry
222 for ($i = 0; $i < $maxItems; $i++) {
223 $row = $resultRows[$rowsSort[$i]];
224 $rowId = $row['table'] . '-' . $row['uid'] . '-' . $table . '-' . $uid . '-' . $field;
225 $listItems[] = '<li' . ($row['class'] != '' ? ' class="' . $row['class'] . '"' : '') .
226 ' id="' . $rowId . '" style="' . $row['style'] . '">' . $row['text'] . '</li>';
227 }
228 }
229
230 if (count($listItems) > 0) {
231 $list = implode('', $listItems);
232 } else {
233 $list = '<li class="suggest-noresults"><i>' . $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:labels.noRecordFound') . '</i></li>';
234 }
235
236 $list = '<ul class="' . $this->cssClass . '-resultlist">' . $list . '</ul>';
237 $ajaxObj->addContent(0, $list);
238 }
239 }
240
241
242 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_suggest.php']) {
243 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['classes/t3lib/tceforms/class.t3lib_tceforms_suggest.php']);
244 }
245
246 ?>