Suggest innerhalb von Flexforms

Seit dem 4.4er-Zweig gibt es den Suggest-Wizard. Damit kann man ein TCA-Feld um einen AJAX-Suggest erweitern.
Dies kann die Arbeit im Backend um Einiges erleichtern und beschleunigen.
Leider scheint der Wizard innerhalb von Flexforms noch nicht zu funktionieren.
Es gibt bereits eine Extension namens „ajaxgroupsearch“, welche diese Funktionalität bereitstellt.
Allerdings habe ich mir gedacht, dass es möglicherweise performanter und besser ist, eine XClass der Klasse t3lib_TCEforms_Suggest zu schreiben:
Die XClass sieht dabei so aus:

class ux_t3lib_TCEforms_Suggest extends t3lib_TCEforms_Suggest {

    /**
     * @var string
     */
    protected static $ffNeedle = 'sssssssssss';
    /**
     *
     * @var string
     */
    protected static $ffNeedleLong = 'fffffffff';

    /**
     * Renders an ajax-enabled text field. Also adds required JS
     *
     * @param string $fieldname The fieldname in the form
     * @param string $table The table we render this selector for
     * @param string $field The field we render this selector for
     * @param array $row The row which is currently edited
     * @param array $config The TSconfig of the field
     * @return string The HTML code for the selector
     */
	public function renderSuggestSelector($fieldname, $table, $field, array $row, array $config) {

                $this->suggestCount++;

		$containerCssClass = $this->cssClass . ' ' . $this->cssClass . '-position-right';
		$suggestId = 'suggest-' . $table . '-' . $field . '-' . $row['uid'];

                if('pi_flexform' == $field) {
                    if($config['fieldConf']['config']['wizards']['suggest']['type'] == 'suggest') {
                        $configTemp = $config['fieldConf']['config'];
                        $name = str_replace('data[' .$table. '][' .$row['uid']. '][pi_flexform]', '', $config['itemFormElName']);
                        $name = self::$ffNeedleLong.'pi_flexform]' .substr($name, 0, -1);
                        $paramsArray = array();
                        $paramsArray[] = $name;
                        $paramsArray[] = $configTemp['suggest_name'] ? $configTemp['suggest_name'] : '';
                        $paramsArray[] = $configTemp['allowed'] ? $configTemp['allowed'] : '';
                        $paramsArray[] = $configTemp['foreign_table'] ? $configTemp['foreign_table'] : '';
                        $paramsArray[] = $configTemp['foreign_table_where'] ? $configTemp['foreign_table_where'] : '';
                        $field = implode(self::$ffNeedle, $paramsArray);
                    }
                }

		$selector = '

<div id="' . $suggestId . '" class="' . $containerCssClass . '">
<input id="' . $fieldname . 'Suggest" class="' . $this-&gt;cssClass . '-search" type="text" value="' .
				$GLOBALS['LANG']-&gt;sL('LLL:EXT:lang/locallang_core.xml:labels.findRecord') . '" />

<div id="' . $fieldname . 'SuggestIndicator" class="' . $this-&gt;cssClass . '-indicator" style="display: none;">
				<img src="' . $GLOBALS['BACK_PATH'] . 'gfx/spinner.gif" alt="' . $GLOBALS['LANG']-&gt;sL('LLL:EXT:lang/locallang_core.xml:alttext.suggestSearching') . '" /></div>


</div>


';

			// get minimumCharacters from TCA
		if (isset($config['fieldConf']['config']['wizards']['suggest']['default']['minimumCharacters'])) {
			$minChars = intval($config['fieldConf']['config']['wizards']['suggest']['default']['minimumCharacters']);
		}
			// overwrite it with minimumCharacters from TSConfig (TCEFORM) if given
		if (isset($config['fieldTSConfig']['suggest.']['default.']['minimumCharacters'])) {
			$minChars = intval($config['fieldTSConfig']['suggest.']['default.']['minimumCharacters']);
		}
		$minChars = ($minChars &gt; 0 ? $minChars : 2);

			// replace "-" with ucwords for the JS object name
		$jsObj = str_replace(' ', '', ucwords(str_replace('-', ' ', t3lib_div::strtolower($suggestId))));
		$this-&gt;TCEformsObj-&gt;additionalJS_post[] = '
			var ' . $jsObj . ' = new TCEForms.Suggest("' . $fieldname . '", "' . $table . '", "' . $field .
			'", "' . $row['uid'] . '", ' . $row['pid'] . ', ' . $minChars . ');
			' . $jsObj . '.defaultValue = "' . t3lib_div::slashJS($GLOBALS['LANG']-&gt;sL('LLL:EXT:lang/locallang_core.xml:labels.findRecord')) . '";
		';

		return $selector;
	}

	/**
	 * Ajax handler for the "suggest" feature in TCEforms.
	 *
	 * @param array $params The parameters from the AJAX call
	 * @param TYPO3AJAX $ajaxObj The AJAX object representing the AJAX call
	 * @return void
	 */
	public function processAjaxRequest($params, &amp;$ajaxObj) {

			// get parameters from $_GET/$_POST
		$search = t3lib_div::_GP('value');
		$table = t3lib_div::_GP('table');
		$field = t3lib_div::_GP('field');
                $uid = t3lib_div::_GP('uid');
		$pageId = t3lib_div::_GP('pid');

                $fieldTemp = $field;
		if (strpos($field, self::$ffNeedleLong) !== false){
                    $suggestFFArray = t3lib_div::trimExplode(self::$ffNeedle, $field);
                    $field = $suggestFFArray[1];
                    $fieldTemp = str_replace(self::$ffNeedleLong, '', $suggestFFArray[0]);
                    $ffAllowed = $suggestFFArray[2];
                    $ffForeignTable = $suggestFFArray[3];
                    $ffForeignTableWhere = $suggestFFArray[4];
                    $GLOBALS['TCA'][$table]['columns'][$field]['config']['allowed'] = $ffAllowed;
                    $GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table'] = $ffForeignTable;
                    $GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table_where'] = $ffForeignTableWhere;
                }

		t3lib_div::loadTCA($table);

			// If the $uid is numeric, we have an already existing element, so get the
			// TSconfig of the page itself or the element container (for non-page elements)
			// otherwise it's a new element, so use given id of parent page (i.e., don't modify it here)
		if (is_numeric($uid)) {
			if ($table == 'pages') {
				$pageId = $uid;
			} else {
				$row = t3lib_BEfunc::getRecord($table, $uid);
				$pageId = $row['pid'];
			}
		}

		$TSconfig = t3lib_BEfunc::getPagesTSconfig($pageId);
		$queryTables = array();
		$foreign_table_where = '';
		$wizardConfig = $GLOBALS['TCA'][$table]['columns'][$field]['config']['wizards']['suggest'];
                if (isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['allowed'])) {
                    $queryTables = t3lib_div::trimExplode(',', $GLOBALS['TCA'][$table]['columns'][$field]['config']['allowed']);
		} elseif (isset($GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table'])) {
			$queryTables = array($GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table']);
			$foreign_table_where = $GLOBALS['TCA'][$table]['columns'][$field]['config']['foreign_table_where'];
				// strip ORDER BY clause
			$foreign_table_where = trim(preg_replace('/ORDER[[:space:]]+BY.*/i', '', $foreign_table_where));
		}
		$resultRows = array();

			// fetch the records for each query table. A query table is a table from which records are allowed to
			// be added to the TCEForm selector, originally fetched from the "allowed" config option in the TCA
		foreach ($queryTables as $queryTable) {
			t3lib_div::loadTCA($queryTable);

				// if the table does not exist, skip it
			if (!is_array($GLOBALS['TCA'][$queryTable]) || !count($GLOBALS['TCA'][$queryTable])) {
				continue;
			}
			$config = (array)$wizardConfig['default'];

			if (is_array($wizardConfig[$queryTable])) {
				$config = t3lib_div::array_merge_recursive_overrule($config, $wizardConfig[$queryTable]);
			}

				// merge the configurations of different "levels" to get the working configuration for this table and
				// field (i.e., go from the most general to the most special configuration)
			if (is_array($TSconfig['TCEFORM.']['suggest.']['default.'])) {
				$config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.']['default.']);
			}

			if (is_array($TSconfig['TCEFORM.']['suggest.'][$queryTable.'.'])) {
				$config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.']['suggest.'][$queryTable.'.']);
			}

				// use $table instead of $queryTable here because we overlay a config
				// for the input-field here, not for the queried table
			if (is_array($TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.']['default.'])) {
				$config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.']['default.']);
			}
			if (is_array($TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.'][$queryTable.'.'])) {
				$config = t3lib_div::array_merge_recursive_overrule($config, $TSconfig['TCEFORM.'][$table.'.'][$field.'.']['suggest.'][$queryTable.'.']);
			}

				//process addWhere
			if (!isset($config['addWhere']) &amp;&amp; $foreign_table_where) {
				$config['addWhere'] = $foreign_table_where;
			}
			if (isset($config['addWhere'])) {
				$config['addWhere'] = strtr(' ' . $config['addWhere'], array(
					'###THIS_UID###' =&gt; intval($uid),
					'###CURRENT_PID###' =&gt; intval($pageId),
				));
			}
				// instantiate the class that should fetch the records for this $queryTable
			$receiverClassName = $config['receiverClass'];
			if (!class_exists($receiverClassName)) {
				$receiverClassName = 't3lib_TCEforms_Suggest_DefaultReceiver';
			}
			$receiverObj = t3lib_div::makeInstance($receiverClassName, $queryTable, $config);

			$params = array('value' =&gt; $search);
			$rows = $receiverObj-&gt;queryTable($params);

			if (empty($rows)) {
				continue;
			}
			$resultRows = t3lib_div::array_merge($resultRows, $rows);
			unset($rows);
		}

		$listItems = array();
		if (count($resultRows) &gt; 0) {
				// traverse all found records and sort them
			$rowsSort = array();
			foreach ($resultRows as $key =&gt; $row) {
				$rowsSort[$key] = $row['text'];
			}
			asort($rowsSort);
			$rowsSort = array_keys($rowsSort);

				// Limit the number of items in the result list
			$maxItems = $config['maxItemsInResultList'] ? $config['maxItemsInResultList'] : 10;
			$maxItems = min(count($resultRows), $maxItems);

				// put together the selector entry
			for ($i = 0; $i &lt; $maxItems; $i++) {
				$row = $resultRows[$rowsSort[$i]];
				$rowId = $row['table'] . '-' . $row['uid'] . '-' . $table . '-' . $uid . '-' . $fieldTemp;
				$listItems[] = '
' . $row['text'] . '

';
			}
		}

		if (count($listItems) &gt; 0) {
			$list = implode('', $listItems);
		} else {
			$list = '

	<li class="suggest-noresults"><em>' . $GLOBALS['LANG']-&gt;sL('LLL:EXT:lang/locallang_core.xml:labels.noRecordFound') . '</em></li>


';
		}

		$list = '

<ul class="' . $this-&gt;cssClass . '-resultlist">' . $list . '</ul>


';
		$ajaxObj-&gt;addContent(0, $list);
	}
}

Download aktuelle Fassung der Erweiterung „ssch_ff_suggest.t3x“

Gibt es bessere Ideen / Herangehensweisen?

Veröffentlicht von

avatar

Sebastian Schreiber

Ich bin 1980 in Bergisch Gladbach geboren. Nach dem Abitur und Zivildienst habe ich 2000 an der Fachhochschule Lippe & Höxter das Studium der Medienproduktin begonnen und nach längeren Aufenthalten in Valencia und Berlin 2003 das Studium mit dem Abschluss Bachelor of Science in Medienproduktion abgeschlossen. Nach einer Festanstellung kurz nach dem Studium in einer kleinen Webagentur in Köln mit Schwerpunkt TYPO3 bin ich nun seit 2008 freiberuflicher Webentwickler.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.