16432_v3.diff

Administrator Admin, 2010-11-17 19:07

Download (49.5 KB)

View differences:

t3lib/config_default.php (working copy)
393 393
			)
394 394
		),
395 395
		'ExtDirect' => array(	// array of key value pairs (provider -> location:className) that holds the classes for the ExtDirect functionality
396
			'TYPO3.CSH.ExtDirect' => 't3lib/extjs/dataprovider/class.extdirect_dataprovider_contexthelp.php:extDirect_DataProvider_ContextHelp'
396
			'TYPO3.CSH.ExtDirect' => 't3lib/extjs/dataprovider/class.extdirect_dataprovider_contexthelp.php:extDirect_DataProvider_ContextHelp',
397
			'TYPO3.LiveSearchActions.ExtDirect' => 't3lib/extjs/dataprovider/class.extdirect_dataprovider_backendlivesearch.php:extDirect_DataProvider_BackendLiveSearch'
397 398
		),
398 399
	),
399 400
	'EXTCONF' => array(		// Here you may add manually set configuration options for your extensions. Eg. $TYPO3_CONF_VARS['EXTCONF']['my_extension_key']['my_option'] = 'my_value';
t3lib/search/class.t3lib_search_livesearch.php (revision 0)
1
<?php
2
/***************************************************************
3
 *  Copyright notice
4
 *
5
 *  (c) 2009-2010 Michael Klapper <michael.klapper@aoemedia.de>
6
 *  (c) 2010 Jeff Segars <jeff@webempoweredchurch.org>
7
 *  All rights reserved
8
 *
9
 *  This script is part of the TYPO3 project. The TYPO3 project is
10
 *  free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  The GNU General Public License can be found at
16
 *  http://www.gnu.org/copyleft/gpl.html.
17
 *  A copy is found in the textfile GPL.txt and important notices to the license
18
 *  from the author is found in LICENSE.txt distributed with these scripts.
19
 *
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28

  
29
/**
30
 * Class for handling backend live search.
31
 *
32
 * @author Michael Klapper <michael.klapper@aoemedia.de>
33
 * @author Jeff Segars <jeff@webempoweredchurch.org>
34
 * @package TYPO3
35
 * @subpackage t3lib
36
 */
37
class t3lib_search_livesearch {
38

  
39
	/**
40
	 * @var string
41
	 */
42
	const PAGE_JUMP_TABLE = 'pages';
43

  
44
	/**
45
	 * @var integer
46
	 */
47
	const RECURSIVE_PAGE_LEVEL = 99;
48

  
49
	/**
50
	 * @var integer
51
	 */
52
	const GROUP_TITLE_MAX_LENGTH = 15;
53

  
54
	/**
55
	 * @var integer
56
	 */
57
	const RECORD_TITLE_MAX_LENGTH = 37;
58

  
59
	/**
60
	 * @var string
61
	 */
62
	private $queryString = '';
63

  
64
	/**
65
	 * @var integer
66
	 */
67
	private $startCount = 0;
68

  
69
	/**
70
	 * @var integer
71
	 */
72
	private $limitCount = 5;
73

  
74
	/**
75
	 * @var string
76
	 */
77
	protected $userPermissions = '';
78

  
79
	/**
80
	 * @var t3lib_search_livesearch_queryParser
81
	 */
82
	protected $queryParser = null;
83

  
84
	/**
85
	 * Initialize access settings.
86
	 *
87
	 * @return void
88
	 */
89
	public function __construct() {
90
		$this->userPermissions = $GLOBALS['BE_USER']->getPagePermsClause(1);
91
		$this->queryParser = t3lib_div::makeInstance('t3lib_search_livesearch_queryParser');
92
	}
93

  
94
	/**
95
	 * Find records from database based on the given $searchQuery.
96
	 *
97
	 * @param string $searchQuery
98
	 * @return string Edit link to an page record if exists. Otherwise an empty string will returned
99
	 */
100
	public function findPage($searchQuery) {
101
		$link = '';
102
		$pageId = $this->queryParser->getId($searchQuery);
103
		$pageRecord = $this->findPageById($pageId);
104

  
105
		if (!empty($pageRecord)) {
106
			$link = $this->getEditLink(self::PAGE_JUMP_TABLE, $this->findPageById($pageId));
107
		}
108

  
109
		return $link;
110
	}
111

  
112
	/**
113
	 * Find records from database based on the given $searchQuery.
114
	 *
115
	 * @param string $searchQuery
116
	 * @return array Result list of database search.
117
	 */
118
	public function find($searchQuery) {
119
		$recordArray = array();
120
		$pageIdList = $this->getAvailablePageIds (
121
			implode(',', $GLOBALS['BE_USER']->returnWebmounts()),
122
			self::RECURSIVE_PAGE_LEVEL
123
		);
124
		$limit = $this->startCount . ',' . $this->limitCount;
125

  
126
		if ($this->queryParser->isValidCommand($searchQuery)) {
127
			$this->setQueryString($this->queryParser->getSearchQueryValue($searchQuery));
128
			$tableName = $this->queryParser->getTableNameFromCommand($searchQuery);
129
			if ($tableName) {
130
				$recordArray[] = $this->findByTable($tableName, $pageIdList, $limit);
131
			}
132
		} else {
133
			$this->setQueryString($searchQuery);
134
			$recordArray = $this->findByGlobalTableList($pageIdList, $limit);
135
		}
136

  
137
		// @todo Need to make sure we don't return too many records. How do we handle this when querying across multiple tables?
138
		$recordArray = array_slice($recordArray, 0, $this->limitCount);
139

  
140
		return $recordArray;
141
	}
142

  
143
	/**
144
	 * Retrieve the page record from given $id.
145
	 *
146
	 * @param integer $id
147
	 * @return array
148
	 */
149
	protected function findPageById($id) {
150
		$pageRecord = array();
151
		$row = t3lib_BEfunc::getRecord(self::PAGE_JUMP_TABLE, $id);
152

  
153
		if (is_array($row)) {
154
			$pageRecord = $row;
155
		}
156

  
157
		return $pageRecord;
158
	}
159

  
160
	/**
161
	 * Find records from all registered TCA table & column values.
162
	 *
163
	 * @param string $pageIdList Comma seperated list of page IDs
164
	 * @param string $limit MySql Limit notation
165
	 * @return array Records found in the database matching the searchQuery
166
	 */
167
	protected function findByGlobalTableList($pageIdList, $limit) {
168
		$getRecordArray = array();
169
		foreach ($GLOBALS['TCA'] as $tableName => $value) {
170
			$getRecordArray[] = $this->findByTable($tableName, $pageIdList, $limit);
171
		}
172

  
173
		return $getRecordArray;
174
	}
175

  
176
	/**
177
	 * Find records by given table name.
178
	 *
179
	 * @param string $tableName Database table name
180
	 * @param string $pageIdList Comma seperated list of page IDs
181
	 * @param string $limit MySql Limit notation
182
	 * @return array Records found in the database matching the searchQuery
183
	 *
184
	 * @see getRecordArray()
185
	 * @see makeOrderByTable()
186
	 * @see makeQuerySearchByTable()
187
	 * @see extractSearchableFieldsFromTable()
188
	 */
189
	protected function findByTable($tableName, $pageIdList, $limit) {
190
		$getRecordArray = array();
191
		$fieldsToSearchWithin = $this->extractSearchableFieldsFromTable($tableName);
192
		$pageBasedPermission = ($tableName == 'pages' && $this->userPermissions) ? $this->userPermissions : '1=1 ' ;
193
		$where = 'pid IN(' . $pageIdList . ')' . $pageBasedPermission . $this->makeQuerySearchByTable($tableName, $fieldsToSearchWithin);
194
		$orderBy = $this->makeOrderByTable($tableName);
195
		$getRecordArray = $this->getRecordArray(
196
			$tableName,
197
			$pageBasedPermission . $this->makeQuerySearchByTable($tableName, $fieldsToSearchWithin),
198
			$this->makeOrderByTable($tableName),
199
			$limit
200
		);
201

  
202
		return $getRecordArray;
203
	}
204

  
205
	/**
206
	 * Process the Database operation to get the search result.
207
	 *
208
	 * @param string $tableName Database table name
209
	 * @param string $where
210
	 * @param string $orderBy
211
	 * @param string $limit MySql Limit notation
212
	 * @return array
213
	 *
214
	 * @see t3lib_db::exec_SELECT_queryArray()
215
	 * @see t3lib_db::sql_num_rows()
216
	 * @see t3lib_db::sql_fetch_assoc()
217
	 * @see t3lib_iconWorks::getSpriteIconForRecord()
218
	 * @see getTitleFromCurrentRow()
219
	 * @see getEditLink()
220
	 */
221
	protected function getRecordArray($tableName, $where, $orderBy, $limit) {
222
		$collect = array();
223
		$isFirst = true;
224
		$queryParts = array(
225
			'SELECT'  => '*',
226
			'FROM'	  => $tableName,
227
			'WHERE'	  => $where,
228
			'ORDERBY' => $orderBy,
229
			'LIMIT'	  => $limit
230
		);
231
		$result	 = $GLOBALS['TYPO3_DB']->exec_SELECT_queryArray($queryParts);
232
		$dbCount = $GLOBALS['TYPO3_DB']->sql_num_rows($result);
233

  
234
		while($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($result)) {
235
			$collect[] = array (
236
				'id' => $tableName . ':' . $row['uid'],
237
				'recordTitle' => ($isFirst) ? $this->getRecordTitlePrep($this->getTitleOfCurrentRecordType($tableName), self::GROUP_TITLE_MAX_LENGTH) : '',
238
				'iconHTML' => t3lib_iconWorks::getSpriteIconForRecord($tableName, $row),
239
				'title' => $this->getRecordTitlePrep($this->getTitleFromCurrentRow($tableName, $row), self::RECORD_TITLE_MAX_LENGTH),
240
				'editLink' => $this->getEditLink($tableName, $row),
241
			);
242
			$isFirst = false;
243
		}
244

  
245
		return $collect;
246
	}
247

  
248
	/**
249
	 * Build a backend edit link based on given record.
250
	 *
251
	 * @param string $tableName Record table name
252
	 * @param array	 $row  Current record row from database.
253
	 * @return string Link to open an edit window for record.
254
	 *
255
	 * @see t3lib_BEfunc::readPageAccess()
256
	 */
257
	protected function getEditLink($tableName, $row) {
258
		$pageInfo = t3lib_BEfunc::readPageAccess($row['pid'], $this->userPermissions);
259
		$calcPerms = $GLOBALS['BE_USER']->calcPerms($pageInfo);
260
		$editLink = '';
261

  
262
		if ($tableName == 'pages') {
263
			$localCalcPerms = $GLOBALS['BE_USER']->calcPerms(t3lib_BEfunc::getRecord('pages',$row['uid']));
264
			$permsEdit = $localCalcPerms&2;
265
		} else {
266
			$permsEdit = $calcPerms&16;
267
		}
268

  
269
			// "Edit" link: ( Only if permissions to edit the page-record of the content of the parent page ($this->id)
270
			// @todo Is there an existing function to generate this link?
271
		if ($permsEdit) {
272
			$editLink = 'alt_doc.php?' . '&edit['.$tableName.']['.$row['uid'].']=edit';
273
		}
274

  
275
		return $editLink;
276
	}
277

  
278
	/**
279
	 * Retrieve the record name
280
	 *
281
	 * @param string $tableName Record table name
282
	 * @return string
283
	 */
284
	protected function getTitleOfCurrentRecordType($tableName) {
285
		return $GLOBALS['LANG']->sL($GLOBALS['TCA'][$tableName]['ctrl']['title']);
286
	}
287

  
288
	/**
289
	 * Crops a title string to a limited lenght and if it really was cropped, wrap it in a <span title="...">|</span>,
290
	 * which offers a tooltip with the original title when moving mouse over it.
291
	 *
292
	 * @param	string		$title: The title string to be cropped
293
	 * @param	integer		$titleLength: Crop title after this length - if not set, BE_USER->uc['titleLen'] is used
294
	 * @return	string		The processed title string, wrapped in <span title="...">|</span> if cropped
295
	 */
296
	public function getRecordTitlePrep($title, $titleLength = 0) {
297
			// If $titleLength is not a valid positive integer, use BE_USER->uc['titleLen']:
298
		if (!$titleLength || !t3lib_div::testInt($titleLength) || $titleLength < 0) {
299
			$titleLength = $GLOBALS['BE_USER']->uc['titleLen'];
300
		}
301

  
302
		return htmlspecialchars(t3lib_div::fixed_lgd_cs($title, $titleLength));;
303
	}
304

  
305
	/**
306
	 * Retrieve the column name which contains the title value
307
	 *
308
	 * @param string $tableName Record table name
309
	 * @param array $row Current record row from database.
310
	 * @return string
311
	 *
312
	 * @todo Use the backend function to get the calculated label instead.
313
	 */
314
	protected function getTitleFromCurrentRow($tableName, $row) {
315
		$titleColumnName = $GLOBALS['TCA'][$tableName]['ctrl']['label'];
316
		return $row[$titleColumnName];
317
	}
318

  
319
	/**
320
	 * Build the MySql where clause by table.
321
	 *
322
	 * @param string $tableName Record table name
323
	 * @param array $fieldsToSearchWithin User right based visible fields where we can search within.
324
	 * @return string
325
	 */
326
	protected function makeQuerySearchByTable($tableName, $fieldsToSearchWithin) {
327
			// free text search
328
		$queryLikeStatement = ' LIKE \'%' . $this->getQueryString() . '%\'';
329
		$queryPart			= ' AND (' . implode($queryLikeStatement . ' OR ', $fieldsToSearchWithin) . $queryLikeStatement . ')';
330
		$queryPart		   .= t3lib_BEfunc::deleteClause($tableName);
331
		$queryPart		   .= t3lib_BEfunc::versioningPlaceholderClause($tableName);
332

  
333
		return $queryPart;
334
	}
335

  
336
	/**
337
	 * Build the MySql ORDER BY statement.
338
	 *
339
	 *
340
	 * @param string $tableName Record table name
341
	 * @return string
342
	 * @see t3lib_db::stripOrderBy()
343
	 */
344
	protected function makeOrderByTable($tableName) {
345
		$orderBy = '';
346

  
347
		if (is_array($GLOBALS['TCA'][$tableName]['ctrl']) && array_key_exists('sortby', $GLOBALS['TCA'][$tableName]['ctrl'])) {
348
			$orderBy = 'ORDER BY '.$GLOBALS['TCA'][$tableName]['ctrl']['sortby'];
349
		} else {
350
			$orderBy = $GLOBALS['TCA'][$tableName]['ctrl']['default_sortby'];
351
		}
352

  
353
		return $GLOBALS['TYPO3_DB']->stripOrderBy($orderBy);
354
	}
355

  
356
	/**
357
	 * Get all fields from given table where we can search for.
358
	 *
359
	 * @param string $tableName
360
	 * @return array
361
	 */
362
	protected function extractSearchableFieldsFromTable($tableName) {
363
		$fieldListArray = array();
364

  
365
			// Traverse configured columns and add them to field array, if available for user.
366
		foreach((array) $GLOBALS['TCA'][$tableName]['columns'] as $fieldName => $fieldValue) {
367
			// @todo Reformat
368
			if (
369
					(!$fieldValue['exclude'] || $GLOBALS['BE_USER']->check('non_exclude_fields', $tableName . ':' . $fieldName)) // does current user have access to the field
370
				&&
371
					($fieldValue['config']['type'] != 'passthrough') // field type is not searchable
372
				&&
373
					(!preg_match('/date|time|int/', $fieldValue['config']['eval'])) // field can't be of type date, time, int
374
				&&
375
					(
376
							($fieldValue['config']['type'] == 'text')
377
						||
378
							($fieldValue['config']['type'] == 'input')
379
					)
380
				) {
381
				$fieldListArray[] = $fieldName;
382
			}
383
		}
384

  
385
			// Add special fields:
386
		if ($GLOBALS['BE_USER']->isAdmin())	{
387
			$fieldListArray[] = 'uid';
388
			$fieldListArray[] = 'pid';
389
		}
390

  
391
		return $fieldListArray;
392
	}
393

  
394
	/**
395
	 * Safely retrieve the queryString.
396
	 *
397
	 * @return string
398
	 * @see t3lib_db::quoteStr()
399
	 */
400
	public function getQueryString() {
401
		return $GLOBALS['TYPO3_DB']->quoteStr($this->queryString, '');
402
	}
403

  
404
	/**
405
	 * Setter for limit value.
406
	 *
407
	 * @param integer $limitCount
408
	 * @return void
409
	 */
410
	public function setLimitCount($limitCount) {
411
		$limit = t3lib_div::intval_positive($limitCount);
412
		if ($limit > 0) {
413
			$this->limitCount = $limit;
414
		}
415
	}
416

  
417
	/**
418
	 * Setter for start count value.
419
	 *
420
	 * @param integer $startCount
421
	 * @return void
422
	 */
423
	public function setStartCount($startCount) {
424
		$this->startCount = t3lib_div::intval_positive($startCount);
425
	}
426

  
427
	/**
428
	 * Setter for the search query string.
429
	 *
430
	 * @param string $queryString
431
	 * @return void
432
	 * @see t3lib_div::removeXSS()
433
	 */
434
	public function setQueryString($queryString) {
435
		$this->queryString = t3lib_div::removeXSS($queryString);
436
	}
437

  
438
	/**
439
	 * Creates an instance of t3lib_pageTree which will select a page tree to
440
	 * $depth and return the object. In that object we will find the ids of the tree.
441
	 *
442
	 * @param	integer		Page id.
443
	 * @param	integer		Depth to go down.
444
	 *
445
	 * @return	string		coma separated list of uids
446
	 */
447
	protected function getAvailablePageIds($id, $depth) {
448
		$idList = '';
449
		$tree = t3lib_div::makeInstance('t3lib_pageTree');
450
		$tree->init('AND ' . $this->userPermissions);
451
		$tree->makeHTML = 0;
452
		$tree->fieldArray = Array('uid','php_tree_stop');
453
		if ($depth) {
454
			$tree->getTree($id, $depth, '');
455
		}
456
		$tree->ids[] = $id;
457
		$idList = implode(',', $tree->ids);
458
		return $idList;
459
	}
460
}
461

  
462
?>
t3lib/search/class.t3lib_search_livesearch_queryParser.php (revision 0)
1
<?php
2
/***************************************************************
3
 *  Copyright notice
4
 *
5
 *  (c) 2009-2010 Michael Klapper <michael.klapper@aoemedia.de>
6
 *  (c) 2010 Jeff Segars <jeff@webempoweredchurch.org>
7
 *  All rights reserved
8
 *
9
 *  This script is part of the TYPO3 project. The TYPO3 project is
10
 *  free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  The GNU General Public License can be found at
16
 *  http://www.gnu.org/copyleft/gpl.html.
17
 *  A copy is found in the textfile GPL.txt and important notices to the license
18
 *  from the author is found in LICENSE.txt distributed with these scripts.
19
 *
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28

  
29
/**
30
 * Class for parsing query parameters in backend live search.
31
 *
32
 * @author Michael Klapper <michael.klapper@aoemedia.de>
33
 * @author Jeff Segars <jeff@webempoweredchurch.org>
34
 * @package TYPO3
35
 * @subpackage t3lib
36
 */
37
class t3lib_search_livesearch_queryParser {
38

  
39
	/**
40
	 * @var string
41
	 */
42
	protected $commandKey = '';
43

  
44
	/**
45
	 * @var string
46
	 */
47
	protected $tableName  = '';
48

  
49
	/**
50
	 * @var string
51
	 */
52
	const COMMAND_KEY_INDICATOR = '#';
53

  
54
	/**
55
	 * @var string
56
	 */
57
	const COMMAND_SPLIT_INDICATOR = ':';
58

  
59
	/**
60
	 * Retrive the validated command key
61
	 *
62
	 * @return string Command name
63
	 */
64
	protected function extractKeyFromQuery($query) {
65
		$keyAndValue = substr($query, 1);
66
		$key = explode(':', $keyAndValue);
67
		$this->commandKey = $key[0];
68
	}
69

  
70
	/**
71
	 * Extract the search value from the full search query which contains also the command part.
72
	 *
73
	 * @param string $query For example #news:weather
74
	 * @return string The extracted search value
75
	 */
76
	public function getSearchQueryValue($query) {
77
		$this->extractKeyFromQuery($query);
78
		return str_replace(self::COMMAND_KEY_INDICATOR . $this->commandKey . self::COMMAND_SPLIT_INDICATOR, '', $query);
79
	}
80

  
81
	/**
82
	 * Find the registerd table command and retrieve the matching table name.
83
	 *
84
	 * @param string $query
85
	 * @return string Database Table name
86
	 */
87
	public function getTableNameFromCommand($query) {
88
		$tableName = '';
89
		$this->extractKeyFromQuery($query);
90
		if (is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch']) && array_key_exists($this->commandKey, $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'])) {
91
			$tableName = $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'][$this->commandKey];
92
		}
93
		return $tableName;
94
	}
95

  
96
	/**
97
	 * Verify if an given query contains a page jump command.
98
	 *
99
	 * @param string $query A valid value looks like '#14'
100
	 * @return integer
101
	 */
102
	public function getId($query) {
103
		return str_replace(self::COMMAND_KEY_INDICATOR, '', $query);
104
	}
105

  
106
	/**
107
	 * Verify if a given query contains a page jump command.
108
	 *
109
	 * @param string $query A valid value looks like '#14'
110
	 * @return boolean
111
	 */
112
	public function isValidPageJump($query) {
113
		$isValid = false;
114

  
115
		if (preg_match('~^#(\d)+$~', $query)) {
116
			$isValid = true;
117
		}
118

  
119
		return $isValid;
120
	}
121

  
122
	/**
123
	 * Verify if an given query contains an registered command key.
124
	 *
125
	 * @param string $query
126
	 * @return boolean
127
	 */
128
	public function isValidCommand($query) {
129
		$isValid = false;
130
		if (strpos($query, self::COMMAND_KEY_INDICATOR) === 0 &&
131
		    strpos($query, self::COMMAND_SPLIT_INDICATOR) > 1 &&
132
		    $this->getTableNameFromCommand($query)) {
133
			$isValid = true;
134
		}
135

  
136
		return $isValid;
137
	}
138

  
139
	/**
140
	 * Gets the command for the given table.
141
	 *
142
	 * @param string $tableName The table to find a command for.
143
	 * @return string
144
	 */
145
	public function getCommandForTable($tableName) {
146
		$commandArray = array_keys($GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'], $tableName);
147
		if (is_array($commandArray)) {
148
			$command = $commandArray[0];
149
		} else {
150
			$command = FALSE;
151
		}
152

  
153
		return $command;
154
	}
155

  
156
	/**
157
	 * Gets the page jump command for a given query.
158
	 *
159
	 * @param string $query
160
	 * @return string
161
	 */
162
	public function getCommandForPageJump($query) {
163
		if ($this->isValidPageJump($query)) {
164
			$command = $this->getCommandForTable('pages');
165
			$id = $this->getId($query);
166

  
167
			$resultQuery = self::COMMAND_KEY_INDICATOR . $command . self::COMMAND_SPLIT_INDICATOR . $id;
168
		} else {
169
			$resultQuery = FALSE;
170
		}
171

  
172
		return $resultQuery;
173
	}
174
}
175
?>
t3lib/core_autoload.php (working copy)
59 59
	't3lib_registry' => PATH_t3lib . 'class.t3lib_registry.php',
60 60
	't3lib_rteapi' => PATH_t3lib . 'class.t3lib_rteapi.php',
61 61
	't3lib_scbase' => PATH_t3lib . 'class.t3lib_scbase.php',
62
	't3lib_search_livesearch' => PATH_t3lib . 'search/class.t3lib_search_livesearch.php',
63
	't3lib_search_livesearch_queryParser' => PATH_t3lib . 'search/class.t3lib_search_livesearch_queryParser.php',
62 64
	't3lib_softrefproc' => PATH_t3lib . 'class.t3lib_softrefproc.php',
63 65
	't3lib_sqlengine' => PATH_t3lib . 'class.t3lib_sqlengine.php',
64 66
	't3lib_sqlengine_resultobj' => PATH_t3lib . 'class.t3lib_sqlengine.php',
t3lib/extjs/dataprovider/class.extdirect_dataprovider_backendlivesearch.php (revision 0)
1
<?php
2
/***************************************************************
3
 *  Copyright notice
4
 *
5
 *  (c) 2009-2010 Michael Klapper <michael.klapper@aoemedia.de>
6
 *  (c) 2010 Jeff Segars <jeff@webempoweredchurch.org>
7
 *  All rights reserved
8
 *
9
 *  This script is part of the TYPO3 project. The TYPO3 project is
10
 *  free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  The GNU General Public License can be found at
16
 *  http://www.gnu.org/copyleft/gpl.html.
17
 *  A copy is found in the textfile GPL.txt and important notices to the license
18
 *  from the author is found in LICENSE.txt distributed with these scripts.
19
 *
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28

  
29
/**
30
 * ExtDirect Class for handling backend live search.
31
 *
32
 * @author Michael Klapper <michael.klapper@aoemedia.de>
33
 * @author Jeff Segars <jeff@webempoweredchurch.org>
34
 * @package TYPO3
35
 * @subpackage t3lib
36
 */
37
class extDirect_dataProvider_BackendLiveSearch {
38

  
39
	/**
40
	 * @var array
41
	 */
42
	protected $searchResults = array (
43
		'pageJump'	  => '',
44
		'searchItems' => array()
45
	);
46

  
47
	/**
48
	 * @var array
49
	 */
50
	protected $helpContent = array (
51
		'title' => 'How to use advanced search tags',
52
		'text'  => 'Search in certain tables:<br />page:Home will search for all pages with the title "Home"',
53
		'keys'	=> array(),
54
	);
55

  
56
	/**
57
	 * @var t3lib_search_livesearch
58
	 */
59
	protected $liveSearch = null;
60

  
61
	/**
62
	 * @var t3lib_search_livesearch_queryParser
63
	 */
64
	protected $queryParser = null;
65

  
66
	/**
67
	 * Initialize the live search
68
	 */
69
	public function __construct() {
70
		// @todo Use the autoloader for this. Not sure why its not working.
71
		require_once(PATH_t3lib . 'search/class.t3lib_search_livesearch_queryParser.php');
72

  
73
		$this->liveSearch  = t3lib_div::makeInstance('t3lib_search_livesearch');
74
		$this->queryParser = t3lib_div::makeInstance('t3lib_search_livesearch_queryParser');
75
	}
76

  
77
	/**
78
	 *
79
	 *
80
	 * @param stdClass $command
81
	 *
82
	 * @return array
83
	 */
84
	public function find($command) {
85
		$this->liveSearch->setStartCount($command->start);
86
		$this->liveSearch->setLimitCount($command->limit);
87
		$this->liveSearch->setQueryString($command->query);
88

  
89
			// jump & edit - find page and retrieve an edit link (this is only for pages
90
		if ($this->queryParser->isValidPageJump($command->query)) {
91
			$this->searchResults['pageJump'] = $this->liveSearch->findPage($command->query);
92
			$commandQuery = $this->queryParser->getCommandForPageJump($command->query);
93
			if ($commandQuery) {
94
				$command->query = $commandQuery;
95
			}
96
		}
97

  
98
			// search through the database and find records who match to the given search string
99
		$resultArray = $this->liveSearch->find($command->query);
100

  
101
		foreach ($resultArray as $resultFromTable) {
102
			foreach ($resultFromTable as $item) {
103
				$this->searchResults['searchItems'][] = $item;
104
			}
105
		}
106

  
107
		return $this->searchResults;
108
	}
109

  
110
	/**
111
	 * Build up and retrieve the general and custom help text "How can you search"
112
	 *
113
	 * @return array
114
	 */
115
	public function getHelp() {
116
		$content = array();
117
		$this->helpContent['keys'] = $this->getRegisteredHelpContent();
118

  
119
		return $this->helpContent;
120
	}
121

  
122

  
123
	/**
124
	 * Find all registerd help information.
125
	 *
126
	 * @return array All registered help content will collected returned
127
	 * @todo Doesn't actually return any data
128
	 */
129
	public function getRegisteredHelpContent() {
130
		$helpArray = array();
131
		$liveSearchConfiguration = ((is_array($GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'])) ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['livesearch'] : array());
132

  
133
		foreach ($liveSearchConfiguration as $key => $table) {
134
			$helpArray[] = '#' . $key;
135
		}
136

  
137
		return $helpArray;
138
	}
139

  
140
}
141
?>
typo3/js/livesearch.js (revision 0)
1
/***************************************************************
2
 *  Copyright notice
3
 *
4
 *  (c) 2009-2010 Michael Klapper <michael.klapper@aoemedia.de>
5
 *  (c) 2010 Jeff Segars <jeff@webempoweredchurch.org>
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
Ext.namespace('TYPO3');
29

  
30
TYPO3.BackendLiveSearch = Ext.extend(Ext.form.ComboBox, {
31
	autoSelect: false,
32
	ctCls: 'live-search-results',
33
	dataProvider: null,
34
	dbListUrl : 'id=0&search_levels=4&search_field=',
35
	displayField: 'title',
36
	emptyText: null,
37
	enableKeyEvents: true,
38
	helpTitle: null,
39
	itemSelector: 'div.search-item-title',
40
	listAlign : 'tr-br',
41
	listClass: 'live-search-list',
42
	listEmptyText: null,
43
	listWidth: 315,
44
	loadingText: null,
45
	minChars: 2,
46
	resizable: false,
47
	title: null,
48
	width: 205,
49

  
50
	triggerClass : 'x-form-clear-trigger',
51
	triggerConfig: '<span tag="a" class="t3-icon t3-icon-actions t3-icon-actions-input t3-icon-input-clear t3-tceforms-input-clearer">&nbsp;</span>',
52
	onTriggerClick: function() {
53
		// Empty the form field, give it focus, and collapse the results
54
		this.reset(this);
55
		this.focus();
56
		this.collapse();
57
	},
58
	tpl: new Ext.XTemplate(
59
		'<table border="0" cellspacing="0">',
60
			'<tpl for=".">',
61
				'<tr class="search-item">',
62
					'<td class="search-item-type" width="105" align="right">{recordTitle}</td>',
63
					'<td class="search-item-content" width="195">',
64
						'<div class="search-item-title">{iconHTML} {title}</span>',
65
					'</td>',
66
				'</tr>',
67
			'</tpl>',
68
		'</table>'
69
	),
70

  
71
	dataReader : new Ext.data.JsonReader({
72
		idProperty : 'type',
73
		root : 'searchItems',
74
		fields : [
75
			{name: 'recordTitle'},
76
			{name: 'id'},
77
			{name: 'iconHTML'},		 
78
			{name: 'title'},
79
			{name: 'editLink'}
80
		]
81
	}),
82
	listeners: {
83
		select : {
84
			scope: this,
85
			fn: function (combo, record, index) {
86
				jump(record.data.editLink, 'web_list', 'web');
87
			}
88
		},
89
		focus : {
90
			fn: function() {
91
				if (this.getValue() == this.emptyText) {
92
					this.reset(this);
93
				}
94
			}
95
		},
96
		specialkey : function (field, e) {
97
			if (e.getKey() == e.RETURN || e.getKey() == e.ENTER) {
98
				if (this.dataReader.jsonData.pageJump != '') {
99
					jump(this.dataReader.jsonData.pageJump, 'web_list', 'web');
100
				} else {
101
					TYPO3.ModuleMenu.App.showModule('web_list', this.dbListUrl + this.getValue());
102
				}
103
			}
104
		}
105
	},
106

  
107
	/**
108
	 * Initializes the component.
109
	 */
110
	initComponent: function() {
111
		this.store = new Ext.data.DirectStore({
112
			directFn: this.dataProvider.find,
113
			reader: this.dataReader
114
		});
115
		TYPO3.BackendLiveSearch.superclass.initComponent.apply(this, arguments);
116
	},
117

  
118
	restrictHeight : function(){
119
		this.innerList.dom.style.height = '';
120
		var inner = this.innerList.dom;
121
		var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight + 30; // @todo Remove hardcoded 30
122
		var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
123
		var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
124
		var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
125
		var space = Math.max(ha, hb, this.minHeight || 0)-pad-2;
126
		/** BUG FIX **/
127
		if (this.shadow === true) { space-=this.list.shadow.offset; }
128

  
129
		h = Math.min(h, space, this.maxHeight);
130

  
131
		/**
132
		 * @internal The calcated height of "h" in the line before seems not working as expected.
133
		 *			 If i define a min height, the box shold at least use this height also if only one entry is in there 
134
		 */
135
		//h = this.maxHeight;
136

  
137
		this.innerList.setHeight(h);
138
		this.list.beginUpdate();
139
		this.list.setHeight(h+pad);
140
		this.list.alignTo(this.el, this.listAlign);
141
		this.list.endUpdate();
142
	},
143

  
144
	initList : function () {
145
		TYPO3.BackendLiveSearch.superclass.initList.apply(this, arguments);
146

  
147
		var cls = 'x-combo-list';
148

  
149
		/**
150
		 * Create bottom Toolbar to the result layer
151
		 */
152
		this.footer = this.list.createChild({cls:cls+'-ft'});
153

  
154
		this.pageTb = new Ext.Toolbar({
155
			renderTo:this.footer,
156
			height: 30,
157
			items: [{
158
				xtype: 'tbfill',
159
				autoWidth : true
160
			},{
161
				xtype: 'button',
162
				text: TYPO3.LLL.liveSearch.showAllResults,
163
				arrowAlign : 'right',
164
				shadow: false,
165
				icon : '../typo3/sysext/t3skin/icons/module_web_list.gif',
166
				listeners : {
167
					scope : this,
168
					click : function () {
169
							// go to db_list.php and search for given search value
170
							// @todo the current selected page ID from the page tree is required, also we need the
171
							// values of $BE_USER->returnWebmounts() to search only during the allowed pages
172
						TYPO3.ModuleMenu.App.showModule('web_list', this.dbListUrl + this.getValue());
173
						this.collapse();
174
					}
175
				}
176
			}]
177
		});
178
		this.assetHeight += this.footer.getHeight();
179
	},
180

  
181
	// private
182
	onLoad : function(){
183
		TYPO3.BackendLiveSearch.superclass.onLoad.apply(this, arguments);
184

  
185
		// If an pageJump request is done this will immediately load the record for editing.
186
		// if (this.dataReader.jsonData.pageJump != '') {
187
		//	this.collapse();
188
		//	jump(this.dataReader.jsonData.pageJump, 'web_list', 'web');
189
		// } else {
190
			// Add an event handler to each iframe, closing the search window when there's a click inside the iframe
191
			// @todo Is there a cleaner way to handle this?
192
			var iframes = Ext.query('iframe');
193
			Ext.each(iframes, function(item, index, allItems) {
194
				item.contentWindow.document.body.onclick = function() {
195
					if (parent.TYPO3LiveSearch && parent.TYPO3LiveSearch.isExpanded()) {
196
						parent.TYPO3LiveSearch.collapse();
197
					}
198
				};
199
			}, this);
200
		//}
201
	},
202

  
203
	initQuery : function(){
204
		TYPO3.BackendLiveSearch.superclass.initQuery.apply(this, arguments);
205
		this.removeHelp();
206
	},
207
	initHelp : function () {
208
		if(!this.helpList){
209
			var cls = 'search-list-help';
210

  
211
			this.helpList = new Ext.Layer({
212
				parentEl: this.getListParent(),
213
				shadow: this.shadow,
214
				cls: [cls, this.listClass].join(' '),
215
				constrain:false
216
			});
217

  
218
			var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
219
			this.helpList.setSize(lw);
220
			this.helpList.swallowEvent('mousewheel');
221
			if(this.syncFont !== false){
222
				this.helpList.setStyle('font-size', this.el.getStyle('font-size'));
223
			}
224

  
225
			this.innerHelpList = this.helpList.createChild({cls:cls+'-inner'});
226
			this.mon(this.innerHelpList, 'mouseover', this.onViewOver, this);
227
			this.mon(this.innerHelpList, 'mousemove', this.onViewMove, this);
228
			this.innerHelpList.setWidth(lw - this.helpList.getFrameWidth('lr'));
229

  
230
			if(!this.helpTpl){
231
				this.helpTpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
232
			 }
233

  
234
			/**
235
			* The {@link Ext.DataView DataView} used to display the ComboBox's options.
236
			* @type Ext.DataView
237
			*/
238
			this.helpView = new Ext.DataView({
239
				applyTo: this.innerHelpList,
240
				tpl: this.helpTpl,
241
				singleSelect: true,
242
				selectedClass: this.selectedClass,
243
				itemSelector: this.itemSelector || '.' + cls + '-item',
244
				emptyText: this.listEmptyText
245
			});
246

  
247
			this.helpList.createChild({
248
				cls: cls + '-content',
249
				// @todo Can we grab this content via ExtDirect?
250
				html: '<strong>' + this.helpTitle + '</strong><p>' + TYPO3.LLL.liveSearch.helpDescription + '<br /> ' + TYPO3.LLL.liveSearch.helpDescriptionPages + '</p>'
251
			});
252

  
253
			this.helpList.alignTo(this.wrap, this.listAlign);
254
			this.helpList.show();
255

  
256
			var iframes = Ext.query('iframe');
257
			Ext.each(iframes, function(item, index, allItems) {
258
				item.contentWindow.document.body.onclick = function() {
259
					if (parent.TYPO3LiveSearch && parent.TYPO3LiveSearch.helpList.isVisible()) {
260
						parent.TYPO3LiveSearch.helpList.remove();
261
					}
262
				};
263
			}, this);
264

  
265
		}
266
	},
267

  
268
	removeHelp : function() {
269
		if (this.helpList) {
270
			this.helpList.destroy();
271
		}
272
	},
273

  
274
	onFocus : function() {
275
		TYPO3.BackendLiveSearch.superclass.onFocus.apply(this, arguments);
276

  
277
		// If search is blank, show the help on focus. Otherwise, show last results
278
		if (this.getValue() == '') {
279
			this.initHelp();
280
		} else {
281
			this.expand();
282
		}
283
	},
284

  
285
	postBlur : function() {
286
		TYPO3.BackendLiveSearch.superclass.postBlur.apply(this, arguments);
287
		this.removeHelp();
288
	},
289

  
290
	getTriggerWidth : function() {
291
		// Trigger is inset, so width used in calculations is 0
292
		return 0;
293
	},
294

  
295
	reset : function() {
296
	    this.originalValue = this.emptyText;
297
		TYPO3.BackendLiveSearch.superclass.reset.apply(this, arguments);
298
	}
299
});
300

  
301
var TYPO3LiveSearch;
302

  
303
Ext.onReady(function() {
304
	TYPO3LiveSearch = new TYPO3.BackendLiveSearch({
305
		dataProvider: TYPO3.LiveSearchActions.ExtDirect,
306
		title: TYPO3.LLL.liveSearch.title,
307
		helpTitle: TYPO3.LLL.liveSearch.helpTitle,
308
		emptyText: TYPO3.LLL.liveSearch.emptyText,
309
		loadingText: TYPO3.LLL.liveSearch.loadingText,
310
		listEmptyText: TYPO3.LLL.liveSearch.listEmptyText
311
	});
312
	
313
	TYPO3LiveSearch.applyToMarkup(Ext.get('live-search-box'));
314
});
typo3/classes/class.livesearch.php (revision 0)
1
<?php
2
/***************************************************************
3
 *  Copyright notice
4
 *
5
 *  (c) 2009-2010 Michael Klapper <michael.klapper@aoemedia.de>
6
 *  (c) 2010 Jeff Segars <jeff@webempoweredchurch.org>
7
 *  All rights reserved
8
 *
9
 *  This script is part of the TYPO3 project. The TYPO3 project is
10
 *  free software; you can redistribute it and/or modify
11
 *  it under the terms of the GNU General Public License as published by
12
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  (at your option) any later version.
14
 *
15
 *  The GNU General Public License can be found at
16
 *  http://www.gnu.org/copyleft/gpl.html.
17
 *  A copy is found in the textfile GPL.txt and important notices to the license
18
 *  from the author is found in LICENSE.txt distributed with these scripts.
19
 *
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28

  
29
/**
30
 * Adds backend live search. to the toolbar
31
 *
32
 * @author Michael Klapper <michael.klapper@aoemedia.de>
33
 * @author Jeff Segars <jeff@webempoweredchurch.org>
34
 * @package TYPO3
35
 * @subpackage t3lib
36
 */
37
class LiveSearch implements backend_toolbarItem {
38

  
39
	/**
40
	 * reference back to the backend object
41
	 *
42
	 * @var	TYPO3backend
43
	 */
44
	protected $backendReference;
45

  
46
	/**
47
	 * constructor
48
	 *
49
	 * @param	TYPO3backend	TYPO3 backend object reference
50
	 */
51
	public function __construct(TYPO3backend &$backendReference = null) {
52
		$this->backendReference = $backendReference;
53
	}
54

  
55
	/**
56
	 * checks whether the user has access to this toolbar item
57
	 *
58
	 * @return  boolean  true if user has access, false if not
59
	 */
60
	public function checkAccess() {
61
			// LiveSearch module is enabled for everybody
62
		return true;
63
	}
64

  
65
	/**
66
	 * Creates the selector for workspaces
67
	 *
68
	 * @return	string		workspace selector as HTML select
69
	 */
70
	public function render() {
71
		$this->addJavascriptToBackend();
72
		return '<div class="live-search-wrapper">
73
					<span title="Search" class="t3-icon t3-icon-apps t3-icon-apps-toolbar t3-icon-toolbar-menu-search">&nbsp;</span>
74
					<input id="live-search-box" />
75
				</div>';
76
	}
77

  
78
	/**
79
	 * adds the necessary JavaScript to the backend
80
	 *
81
	 * @return	void
82
	 */
83
	protected function addJavascriptToBackend() {
84
		$pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
85
		$pageRenderer->addJsFile('ajax.php?ajaxID=ExtDirect::getAPI&namespace=TYPO3.LiveSearchActions', 'text/javascript', $compress = FALSE);
86

  
87
		$this->backendReference->addJavascriptFile('js/livesearch.js');
88
	}
89

  
90
	/**
91
	 * returns additional attributes for the list item in the toolbar
92
	 *
93
	 * @return	string		list item HTML attibutes
94
	 */
95
	public function getAdditionalAttributes() {
96
		return ' id="live-search-menu"';
97
	}
98

  
99
}
100

  
101
?>
typo3/classes/class.backendsearchmenu.php (working copy)
1
<?php
2
/***************************************************************
3
*  Copyright notice
4
*
5
*  (c) 2007-2010 Ingo Renner <ingo@typo3.org>
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

  
29
/**
30
 * class to render the backend search toolbar item menu
31
 *
32
 * $Id$
33
 *
34
 * @author	Ingo Renner <ingo@typo3.org>
35
 * @package TYPO3
36
 * @subpackage core
37
 */
38
class BackendSearchMenu implements backend_toolbarItem {
39

  
40
	/**
41
	 * reference back to the backend object
42
	 *
43
	 * @var	TYPO3backend
44
	 */
45
	protected $backendReference;
46

  
47
	/**
48
	 * constructor
49
	 *
50
	 * @param	TYPO3backend	TYPO3 backend object reference
51
	 */
52
	public function __construct(TYPO3backend &$backendReference = null) {
53
		$this->backendReference = $backendReference;
54
	}
55

  
56
	/**
57
	 * checks whether the user has access to this toolbar item
58
	 *
59
	 * @return  boolean  true if user has access, false if not
60
	 */
61
	public function checkAccess() {
62
			// Backendsearch module is enabled for everybody
63
		return true;
64
	}
65

  
66
	/**
67
	 * Creates the selector for workspaces
68
	 *
69
	 * @return	string		workspace selector as HTML select
70
	 */
71
	public function render() {
72
		$title = $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:toolbarItems.search', true);
73
		$this->addJavascriptToBackend();
74
		$searchMenu = array();
75

  
76
		$searchMenu[] = '<a href="#" class="toolbar-item">' .
77
			t3lib_iconWorks::getSpriteIcon('apps-toolbar-menu-search', array('title' => $title)) .
78
			'</a>';
79

  
80
		$searchMenu[] = '<div class="toolbar-item-menu" style="display: none;">';
81
		$searchMenu[] = '<input type="text" id="search-query" name="search-query" value="" />';
82
		$searchMenu[] = '</div>';
83

  
84
		return implode(LF, $searchMenu);
85
	}
86

  
87
	/**
88
	 * adds the necessary JavaScript to the backend
89
	 *
90
	 * @return	void
91
	 */
92
	protected function addJavascriptToBackend() {
93
		$this->backendReference->addJavascriptFile('js/backendsearch.js');
94
	}
95

  
96
	/**
97
	 * returns additional attributes for the list item in the toolbar
98
	 *
99
	 * @return	string		list item HTML attibutes
100
	 */
101
	public function getAdditionalAttributes() {
102
		return ' id="backend-search-menu"';
103
	}
104

  
105
}
106

  
107

  
108
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.backendsearchmenu.php'])	{
109
	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['typo3/classes/class.backendsearchmenu.php']);
110
}
111

  
112
?>
typo3/backend.php (working copy)
36 36
	// core toolbar items
37 37
require('classes/class.clearcachemenu.php');
38 38
require('classes/class.shortcutmenu.php');
39
require('classes/class.backendsearchmenu.php');
39
require('classes/class.livesearch.php');
40 40

  
41 41
require_once('class.alt_menu_functions.inc');
42 42
$GLOBALS['LANG']->includeLLFile('EXT:lang/locallang_misc.xml');
......
172 172
		$coreToolbarItems = array(
173 173
			'shortcuts'         => 'ShortcutMenu',
174 174
			'clearCacheActions' => 'ClearCacheMenu',
175
			'backendSearch'     => 'BackendSearchMenu'
175
			'liveSearch'        => 'LiveSearch'
176 176
		);
177 177

  
178 178
		foreach($coreToolbarItems as $toolbarItemName => $toolbarItemClassName) {
......
330 330
	protected function renderToolbar() {
331 331

  
332 332
			// move search to last position
333
		$search = $this->toolbarItems['backendSearch'];
334
		unset($this->toolbarItems['backendSearch']);
335
		$this->toolbarItems['backendSearch'] = $search;
333
		$search = $this->toolbarItems['liveSearch'];
334
		unset($this->toolbarItems['liveSearch']);
335
		$this->toolbarItems['liveSearch'] = $search;
336 336

  
337 337
		$toolbar = '<ul id="typo3-toolbar">';
338 338
		$toolbar.= '<li>'.$this->getLoggedInUserLabel().'</li>
......
496 496
			'allError401' => $GLOBALS['LANG']->getLL('fileUpload_allError401'),
497 497
			'allError2038' => $GLOBALS['LANG']->getLL('fileUpload_allError2038'),
498 498
		);
499

  
499
		$t3LLLliveSearch = array(
500
			'title' => $GLOBALS['LANG']->getLL('liveSearch_title'),
501
			'helpTitle' => $GLOBALS['LANG']->getLL('liveSearch_helpTitle'),
502
			'emptyText' => $GLOBALS['LANG']->getLL('liveSearch_emptyText'),
503
			'loadingText' => $GLOBALS['LANG']->getLL('liveSearch_loadingText'),
504
			'listEmptyText' => $GLOBALS['LANG']->getLL('liveSearch_listEmptyText'),
505
			'showAllResults' => $GLOBALS['LANG']->getLL('liveSearch_showAllResults'),
506
			'helpDescription' => $GLOBALS['LANG']->getLL('liveSearch_helpDescription'),
507
			'helpDescriptionPages' => $GLOBALS['LANG']->getLL('liveSearch_helpDescriptionPages'),
508
			'helpDescriptionContent' => $GLOBALS['LANG']->getLL('liveSearch_helpDescriptionContent')
509
		);
500 510
			// Convert labels/settings back to UTF-8 since json_encode() only works with UTF-8:
501 511
		if ($GLOBALS['LANG']->charSet !== 'utf-8') {
502 512
			$t3Configuration['username'] = $GLOBALS['LANG']->csConvObj->conv($t3Configuration['username'], $GLOBALS['LANG']->charSet, 'utf-8');
503 513
			$GLOBALS['LANG']->csConvObj->convArray($t3LLLcore, $GLOBALS['LANG']->charSet, 'utf-8');
504 514
			$GLOBALS['LANG']->csConvObj->convArray($t3LLLfileUpload, $GLOBALS['LANG']->charSet, 'utf-8');
515
			$GLOBALS['LANG']->csConvObj->convArray($t3LLLliveSearch, $GLOBALS['LANG']->charSet, 'utf-8');
505 516
		}
506 517

  
507 518
		$this->js .= '
508 519
	TYPO3.configuration = ' . json_encode($t3Configuration) . ';
509 520
	TYPO3.LLL = {
510 521
		core : ' . json_encode($t3LLLcore) . ',
511
		fileUpload: ' . json_encode($t3LLLfileUpload) . '
522
		fileUpload: ' . json_encode($t3LLLfileUpload) . ',
523
		liveSearch: ' . json_encode($t3LLLliveSearch) . '
512 524
	};
513 525

  
514 526
	/**
typo3/sysext/t3skin/stylesheets/visual/toolbar_livesearch.css (revision 0)
1
/* - - - - - - - - - - - - - - - - - - - - -
2
Backend  Live Search
3
- - - - - - - - - - - - - - - - - - - - - */
4

  
5
.live-search-results .t3-icon-toolbar-menu-search {
6
	position: absolute;
7
	z-index: 3000;
8
	top: 0;
9
	margin: 3px;
10
}
11

  
12
.t3-icon-input-clear {
13
	position: absolute;
14
	top: 0px;
15
	right: 20px;
16
}
17

  
18
#live-search-box {
19
	padding-left: 20px;
20
	width: 180px;
21
	border: none;
22
}
23

  
24
.live-search-list {
25
	background-color: white;
26
	border: none;
27
}
28

  
29
.live-search-list .x-combo-list {
30
	background-color: white;
31
}
32

  
33
.live-search-list .x-combo-list-inner {
34
	padding-bottom: 5px;
35
}
36

  
37
.live-search-list .x-combo-list-hd {
38
	background: none;
39
	border: none;
40
	margin-left: 110px;
41
	color: #ddd;
42
}
43

  
44
.search-list-help-content {
45
	margin: 5px;
46
	height: 100%;
47
	padding: 0.6em 0.6em 0.6em 2.6em;
48
	background-repeat: no-repeat;
49
	background-position: 0.5em 0.7em;
50
	border: 1px solid;
51
	color: #000000;
52

  
53
	background-color: #ddeef9;
54
	border-color: #8aafc4;
55
}
56

  
57
.live-search-list .search-item-type {
58
	border-right: 1px solid #ddd;
59
	padding: 2px 5px 2px 0;
... This diff was truncated because it exceeds the maximum size that can be displayed.