---
title: "ve_guestbook und captcha abfrage"
url: "https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage"
source: "typo3.net"
tags: ["Extensions","Frage","Sicherheit"]
created: "2005-07-31"
last_reply: "2007-04-14"
replies: 37
solved: false
page: 1
pages: 1
lang: "de"
---

# ve_guestbook und captcha abfrage

Extensions · 37 Antworten · gestartet 2005-07-31

## Eröffnungsbeitrag

**Dade Murphy** · 2005-07-31 · [Beitrag #1](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/1)

Hallo,

ich habe mir Captcha extension installiert, das soll automatische Spambots davon abhalten, die Formulare auszufüllen und das Gästebuch zuzumüllen.

leider verstehe ich die knappe Anleitung von Captcha nicht. Hat das schon jemand mit ve_guestbook kombiniert und kann mir kurz eine Anleitung geben, was ich tun muss, nachdem ich ve_guestbook installiert und zum laufen gebracht habe und Captcha verwenden möchte...

vielen Dank für jeden Hinweis :-)
Dade

## Antworten

### [#2](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/2) · Renko · 2005-08-25

hat noch keiner Captcha in Kombination mit ve_guestbook zum laufen gebracht ??

Wenn ja , bitte Lösung posten . Habs versucht aber bisher auch noch nicht hinbekommen !

### [#3](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/3) · zab1981 · 2005-10-18

Würde mich auch brennend interessieren. Wenn irgendjemand was in der Richtung hat ... her damit.

### [#4](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/4) · Dade Murphy · 2005-11-12

Das Gästebuch umsetzen dauert immer am längsten...

habe es mit der Captcha Extension von Kasper zum laufen gebracht. Hier das veränderte script:

Modern Guestbook (ve_guestbook)
pi1/class.tx_veguestbook_pi1.php

```php
<?php
/***************************************************************
*  Copyright notice
*
*  (c) 2004 Udo von Eynern (udo@voneynern.de)
*  All rights reserved
*
*  This script is part of the TYPO3 project. The TYPO3 project is
*  free software; you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation; either version 2 of the License, or
*  (at your option) any later version.
*
*  The GNU General Public License can be found at
*  http://www.gnu.org/copyleft/gpl.html.
*
*  This script is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.

*
*  This copyright notice MUST APPEAR in all copies of the script!
***************************************************************/

########################################################
### this version does work with captcha extension of Kasper
### this patch is done by stonie@cafegermany.de
###
### add to your template file the fields ###CAPTCHA_INSERT###
###                                                   ###FORM_CAPTCHA###
### <input type="text" name="tx_veguestbook_pi1[captcha_response]" value="" class="tx-guestbook-form-inputfield-big" />
########################################################


require_once(PATH_tslib."class.tslib_pibase.php");

/**
 * Plugin 'guestbook' for the 've_guestbook' extension.
 *
 * @author	Udo von Eynern <udo@voneynern.de>
 * @package TYPO3
 * @subpackage ve_guestbook
 */



class tx_veguestbook_pi1 extends tslib_pibase {
	var $prefixId = "tx_veguestbook_pi1";		// Same as class name
	var $scriptRelPath = "pi1/class.tx_veguestbook_pi1.php";	// Path to this script relative to the extension dir.
	var $extKey = "ve_guestbook";	// The extension key.
	var $strEntryTable = "tx_veguestbook_entries";
	var $code = '';
	var $tt_news=array();
	var $for_tt_news;
	var $tt_news_url_params_list='tx_ttnews[tt_news],tx_ttnews[backPid],tx_ttnews[year],tx_ttnews[month],tx_ttnews[day],cHash';

	/**
	 * Init Function: all needed configuration values are stored in the member variable $this->config and the template code goes in $this->templateCode .
	 *
	 * @param	array		$conf: configuration array from TS
	 * @return	void
	 */
	function init($conf) {



		$this->conf = $conf; // Storing configuration as a member var
		$this->pi_USER_INT_obj = 1;  // Disable caching
		$this->pi_loadLL(); // Loading language-labels
		$this->pi_setPiVarDefaults(); // Set default piVars from TS
		$this->pi_initPIflexForm(); // Init FlexForm configuration for plugin

		$this->sys_language_uid = $GLOBALS['TSFE']->config['config']['sys_language_uid'] ? $GLOBALS['TSFE']->config['config']['sys_language_uid'] : '0';


		$this->enableFields = $this->cObj->enableFields($this->strEntryTable);
		$this->code = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'what_to_display', 'sDEF');

		// Getting the pid list via the flexform
		$pid_list = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'pages', 'sDEF') ? implode(t3lib_div::intExplode(',', $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'pages', 'sDEF')), ',') : $GLOBALS['TSFE']->id;

		// Checking for recursive level
		$recursive = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'recursive', 'sDEF');
		if (is_numeric($recursive) && $recursive > 0) {
			$this->config['pid_list'] = $this->pi_getPidList($pid_list,$recursive);
		}
		else {
			$this->config['pid_list'] = $pid_list;
		}

		// Template code
		$templateflex_file = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'template_file', 'sDEF');

		$this->templateCode = $this->cObj->fileResource($templateflex_file  ? 'uploads/tx_veguestbook/'.$templateflex_file : $this->conf['templateFile']);

		// Redirect page after submitting the form
		$this->config['redirect_page'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'redirect_page', 's_form') ? implode(t3lib_div::intExplode(',', $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'redirect_page', 's_form')), ',') : $GLOBALS['TSFE']->id;

		// Obligation fields in the form
		$this->config['obligationfields'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'obligation_fields', 's_form');

		if (!empty($this->config['obligationfields'])) {
			$this->config['obligationfields'] = explode(',', $this->config['obligationfields']);
		}

		// E-Mail-Validation
		$this->config['email_validation'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'email_validation', 's_form');

		// E-Mail substitution for spam protection
		$this->config['email_subst'] = $GLOBALS['TSFE']->tmpl->setup['config.']['spamProtectEmailAddresses_atSubst'];

		// Website-Validation
		$this->config['website_validation'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'website_validation', 's_form');

		// Website-Validation
		$this->config['strip_tags'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'strip_tags', 's_form');

		// Link to the guestbook in teaser mode and notification mail
		$this->config['guestbook'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'guestbook', 'sDEF') ? implode(t3lib_div::intExplode(',', $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'guestbook', 'sDEF')), ',') : '';

		if ($this->config['guestbook'] < 1) {
			$this->config['guestbook'] = $GLOBALS["TSFE"]->id;
		}

		// Max items per page shown in list & teaser mode

		$flex_limit = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'limit', 's_list');

		$this->config['limit'] = $flex_limit ? $flex_limit : $this->conf['limit'];

		$this->config['notify_mail'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'notify_mail', 's_form');

		$this->config['feedback_mail'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'feedback_mail', 's_form');

		$this->config['email_from_name'] = $this->conf['email_from_name'];
		$this->config['email_from_mail'] = $this->conf['email_from_mail'];

		$this->config['manual_backend_release'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'manual_backend_release', 's_form');

		$this->config['nolangfilter'] = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'nolangfilter', 's_list');

		// Cutting the string in teaser mode
		$flex_teasercut = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'teasercut', 's_list');
		$this->config['teasercut'] = $flex_teasercut ? $flex_teasercut : $this->conf['teasercut'];


		//for tt_news
		$this->tt_news = $this->getAddParams($this->tt_news_url_params_list);



		if ($this->tt_news['tx_ttnews[tt_news]'] > 0){
			$this->for_tt_news = true;
		}

		// Cutting words
		$flex_wordcut = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'wordcut', 's_list');
		$this->config['wordcut'] = $flex_wordcut ? $flex_wordcut : $this->conf['wordcut'];

		// Sorting options for the list & teaser mode
		$flex_sortingField = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'listOrderBy', 's_list');
		$flex_sortingDirection = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'ascDesc', 's_list');

		$this->config['sortingField'] = $flex_sortingField ? $flex_sortingField : $this->conf['sortingField'];
		$this->config['sortingDirection'] = $flex_sortingDirection ? $flex_sortingDirection : $this->conf['sortingDirection'];
	}
	/**
	 * Main Function: Mcalls the init() function to setup the configuration and decides by the
	 * given CODEs which of the functions to display news should by called.
	 *
	 * @param	string		$content: function output is added to this
	 * @param	array		$conf: configuration array
	 * @return	string		$content: complete content generated by the plugin
	 */
	function main($content,$conf)	{
		$this->local_cObj = t3lib_div::makeInstance('tslib_cObj'); // Local cObj.
		$this->init($conf);

		switch($this->code) {
			case 'TEASER':
			case 'LIST':
				$content = $this->displayList();
			break;
			case 'FORM':
				$content = $this->displayForm();
			break;
			default:
				// To-Do: Help Template
			break;
		}

		return $this->pi_wrapInBaseClass($content);
	}

	/**
	 * Generating the list of guestbook entries for the modes LIST & TEASER
	 *
	 * @return	string		$content: generated content
	 */
	function displayList() {

		if (!$this->config['nolangfilter']) {
			$language_filter = ' AND (sys_language_uid = ' .$this->sys_language_uid.' OR sys_language_uid = -1) ';
		}

		$temp_where='pid IN ('. $this->config['pid_list'] . ')'. $language_filter . $this->cObj->enableFields($this->strEntryTable);
		if ($this->for_tt_news){
			$temp_where=' uid_tt_news='.$this->tt_news['tx_ttnews[tt_news]'].' AND '.$temp_where;
		}
		$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery('*', $this->strEntryTable, $temp_where);

		$count = $GLOBALS['TYPO3_DB']->sql_num_rows($res);

		$templateName = 'TEMPLATE_'.$this->code;

		// Teaser specific wrapping
		if ($this->code == 'TEASER') {
			$markerArray['###TEASER_HEADLINE###'] = $this->pi_getLL('teaser_headline');

			if ($this->config['guestbook'] > 0) {
				$markerArray['###TEASER_MORE###'] = $this->pi_getLL('teaser_more');


				$wrappedSubpartArray = array();
				$wrappedSubpartArray['###LINK_ITEM###'] = explode('|', $this->pi_linkTP_keepPIvars('|', array(), 0,'',$this->config['guestbook']));
			} else {
				$markerArray['###TEASER_MORE###'] = '';
				$wrappedSubpartArray = array();
			}


		} else {
			$markerArray['###TEASER_HEADLINE###'] = '';
			$markerArray['###TEASER_MORE###'] = '';
		}

		$list = $this->cObj->getSubpart($this->templateCode, '###'.$templateName.'###');

		if ($this->config['limit'] > 0 && $count > $this->config['limit'] && $this->code == 'LIST') {
			// configure pagebrowser
			$this->internal['res_count'] = $count;

			$this->internal['maxPages'] = $this->conf['pageBrowser.']['maxPages'] > 0 ? $this->conf['pageBrowser.']['maxPages'] : 10;

			$this->internal['results_at_a_time'] = $this->config['limit'];

			if (!$this->conf['pageBrowser.']['showPBrowserText']) {
				$this->LOCAL_LANG[$this->LLkey]['pi_list_browseresults_page'] = '';
			}

			$markerArray['###BROWSE_LINKS###'] = $this->pi_list_browseresults($this->conf['pageBrowser.']['showResultCount'],$this->conf['pageBrowser.']['tableParams']);

			$markerArray = $this->getPageBrowser($markerArray);

		} else {

			$this->internal['res_count'] = $count;

			$this->internal['maxPages'] = $this->conf['pageBrowser.']['maxPages'] > 0 ? $this->conf['pageBrowser.']['maxPages'] : 10;

			$markerArray = $this->getPageBrowser($markerArray);

			$markerArray['###BROWSE_LINKS###'] = '';
			$markerArray['###LINK_PREV###'] = '';
			$markerArray['###PAGES###'] = '';
			$markerArray['###LINK_NEXT###'] = '';
		}

		if ($count > 0) {

			if (!empty($this->config['sortingField']) && !empty($this->config['sortingDirection'])) {
				$orderBy = $this->config['sortingField'].' '.$this->config['sortingDirection'];
			}

			if ($this->piVars['pointer'] > 0) {
				$limit_start = $this->piVars['pointer']*$this->config['limit'];
			} else {
				$limit_start = 0;
			}

			$temp_where='pid IN ('. $this->config['pid_list'] . ')'.$language_filter . $this->cObj->enableFields($this->strEntryTable);
			if ($this->for_tt_news){
				$temp_where=' uid_tt_news='.$this->tt_news['tx_ttnews[tt_news]'].' AND '.$temp_where;
			}

			$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
				'*',
				$this->strEntryTable,
				$temp_where,
				'',
				$orderBy,
				$limit_start.','.$this->config['limit']
			);

			$entry = $GLOBALS['TSFE']->cObj->getSubpart($list, '###ENTRY###');
			$subpartArray['###CONTENT###'] = $this->getListContent($res, $entry);

			// Adds hook for processing of extra item markers
			if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['extraItemMarkerHook'])) {
				foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['extraItemMarkerHook'] as $_classRef) {
					$_procObj = & t3lib_div::getUserObj($_classRef);
					$markerArray = $_procObj->extraItemMarkerProcessor($markerArray, $row, $this->config, $this);
				}
			}

			return $this->cObj->substituteMarkerArrayCached($list, $markerArray, $subpartArray, $wrappedSubpartArray);
		}
		else {
			$no_entries = $this->cObj->getSubpart($this->templateCode, '###TEMPLATE_NO_ENTRIES###');

			$markerArray['###NO_ENTRIES_HEADLINE###'] = $this->pi_getLL('no_entries_headline');
			$markerArray['###NO_ENTRIES_TEXT###'] = $this->pi_getLL('no_entries_text');

			$no_entries = $this->cObj->substituteMarkerArrayCached($no_entries, $markerArray, array(), array());

			return $no_entries;
		}
	}

	/**
	 * Getting the page browser for paging
	 *
	 * @param	array		$markerArray: Array containing the template marker
	 * @return	array		$markerArray: Array containing the template marker
	 */
	function getPageBrowser($markerArray) {

		$newsCount = $this->internal['res_count'] ;
		$begin_at = $this->piVars['pointer'] * $this->config['limit'];
		// Make Next link
		if ($newsCount > $begin_at + $this->config['limit']) {
			$next = ($begin_at + $this->config['limit'] > $newsCount) ? $newsCount - $this->config['limit']:$begin_at + $this->config['limit'];
			$next = intval($next / $this->config['limit']);
			$next_link = $this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_next', 'Next >'), array('pointer' => $next), $this->allowCaching);

			$markerArray['###LINK_NEXT###'] = $this->local_cObj->stdWrap($next_link, $this->conf['pageBrowser.']['next_stdWrap.']);

		} else {
			$markerArray['###LINK_NEXT###'] = '';
		}
		// Make Previous link
		if ($begin_at) {
			$prev = ($begin_at - $this->config['limit'] < 0)?0:$begin_at - $this->config['limit'];
			$prev = intval($prev / $this->config['limit']);
			$prev_link = $this->pi_linkTP_keepPIvars($this->pi_getLL('pi_list_browseresults_prev', '< Previous'), array('pointer' => $prev), $this->allowCaching);
			$markerArray['###LINK_PREV###'] = $this->local_cObj->stdWrap($prev_link, $this->conf['pageBrowser.']['previous_stdWrap.']);
		} else {
			$markerArray['###LINK_PREV###'] = '';
		}

		$firstPage = 0;
		$lastPage = $pages = ceil($newsCount / $this->config['limit']);
		$actualPage = floor($begin_at / $this->config['limit']);

		if(ceil($actualPage - $this->internal['maxPages']/2) > 0){
			$firstPage=ceil($actualPage - $this->internal['maxPages']/2);
			$addLast=0;
		}else{
			$firstPage=0;
			$addLast=floor(($this->internal['maxPages']/2)-$actualPage);
		}

		if(ceil($actualPage + $this->internal['maxPages']/2) <= $pages){
			$lastPage=ceil($actualPage + $this->internal['maxPages']/2) > 0 ? ceil($actualPage + $this->internal['maxPages']/2) : 0;
			$subFirst=0;
		} else{
			$lastPage=$pages;
			$subFirst=ceil($this->internal['maxPages']/2-($pages-$actualPage));
		}

		$firstPage=($firstPage-$subFirst)>0?($firstPage-$subFirst):$firstPage;
		$lastPage=($lastPage+$addLast)<=$pages?($lastPage+$addLast):$pages;


		for ($i = $firstPage ; $i < $lastPage; $i++) {
			if (($begin_at >= $i * $this->config['limit']) && ($begin_at < $i * $this->config['limit'] + $this->config['limit'])) {
				$item = ($this->conf['pageBrowser.']['showPBrowserText']?$this->pi_getLL('pi_list_browseresults_page', 'Page'):'') . (string)($i + 1);
				$markerArray['###PAGES###'] .= $this->local_cObj->stdWrap($item, $this->conf['pageBrowser.']['activepage_stdWrap.']) . ' ';
			} else {
				$item = ($this->conf['pageBrowser.']['showPBrowserText']?$this->pi_getLL('pi_list_browseresults_page', 'Page'):'') . (string)($i + 1);

				$link = $this->pi_linkTP_keepPIvars($this->local_cObj->stdWrap($item, $this->conf['pageBrowser.']['pagelink_stdWrap.']) , array('pointer' => $i), $this->allowCaching) . ' ';

				$markerArray['###PAGES###'] .= $this->local_cObj->stdWrap($link, $this->conf['pageBrowser.']['page_stdWrap.']);
			}
		}

		$end_at = ($begin_at + $this->config['limit']);

		if ($this->conf['pageBrowser.']['showResultCount']) {

			$markerArray['###RESULT_COUNT###'] = ($this->internal['res_count'] ?
    			sprintf(
					str_replace('###SPAN_BEGIN###','<span'.$this->pi_classParam('browsebox-strong').'>',$this->pi_getLL('pi_list_browseresults_displays','Displaying results ###SPAN_BEGIN###%s to %s</span> out of ###SPAN_BEGIN###%s</span>')),
					$this->internal['res_count'] > 0 ? ($begin_at+1) : 0,
					min(array($this->internal['res_count'],$end_at )),
					$this->internal['res_count']
				) :
				$this->pi_getLL('pi_list_browseresults_noResults','Sorry, no items were found.'));
		}
		else {
			$markerArray['###RESULT_COUNT###'] = '';
		}


		return $markerArray;
	}

	/**
	 * Generating the rows of guestbook entries
	 *
	 * @param	mixed		$res: database result of the current selection
	 * @param	string		$templatecode: HTML code including the template markers
	 * @return	string		$entries: Generated entries (HTML)
	 */
	function getListContent($res, $templatecode) {

		while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {

			$current_templatecode = $templatecode;

			$markerArray = $this->getItemMarkerArray($row);

			if (empty($row['email'])) {

				$current_templatecode = $this->cObj->substituteSubpart($current_templatecode,'###ENTRY_EMAIL###','');
			}

			if (empty($row['homepage']) OR $row['homepage'] == 'http://') {

				$current_templatecode = $this->cObj->substituteSubpart($current_templatecode,'###ENTRY_HOMEPAGE###','');
			}

			if (empty($row['entrycomment'])) {

				$current_templatecode = $this->cObj->substituteSubpart($current_templatecode,'###ENTRY_ENTRYCOMMENT###','');
			}

			$entries .= $this->cObj->substituteMarkerArrayCached($current_templatecode, $markerArray, array(), array());
			$cc++;
			if ($cc == $this->config['limit']) {
			   break;
			}
		}

		return $entries;
	}

	/**
	 * Fills in the markerArray with data for a guestbook entry
	 *
	 * @param	array		$row: result row for a news item
	 * @return	array		$markerArray: filled marker array
	 */
	function getItemMarkerArray($row) {
		$markerArray['###GUESTBOOK_UID###'] = $row['uid'];
		$markerArray['###GUESTBOOK_FIRSTNAME###'] = $this->cutDown($row['firstname']);
		$markerArray['###GUESTBOOK_SURNAME###'] = $this->cutDown($row['surname']);


		if (!empty($row['place'])) {
			$markerArray['###GUESTBOOK_FROM###'] = $this->pi_getLL('list_from_place');
			$markerArray['###GUESTBOOK_PLACE###'] = $this->cutDown($row['place']);
		}
		else {
			$markerArray['###GUESTBOOK_FROM###'] = '';
			$markerArray['###GUESTBOOK_PLACE###'] = '';
		}
### Modification for CAPTCHA Plugin ###
		$substituteArray = array('firstname', 'surname', 'email', 'homepage', 'place', 'entry', 'entrycomment', 'submit', 'captcharesponse', 'captcha');

		foreach ($substituteArray AS $marker) {
			$markerArray['###FORM_'.strtoupper($marker).'###'] = $this->pi_getLL('form_'.$marker);
		}

		if (!empty($row['email'])) {
			$markerArray["###GUESTBOOK_EMAIL_URL###"] = htmlspecialchars($this->get_url('', $row['email']));

			if (!empty($this->config['email_subst'])) {
				$markerArray["###GUESTBOOK_EMAIL###"] = str_replace('@', $this->config['email_subst'], trim($row['email']));
			}
			else {
				$markerArray["###GUESTBOOK_EMAIL###"] = trim($row['email']);
			}
		}

		if (!empty($row['homepage']) && $row['homepage'] != 'http://') {
			$markerArray["###GUESTBOOK_HOMEPAGE###"] = htmlspecialchars($this->get_url('', $row['homepage']));
		}



		$markerArray['###GUESTBOOK_DATE###'] = $this->pi_getLL('list_datetime_prefix'). date($this->pi_getLL('list_datetime_format'), $row['crdate']). $this->pi_getLL('list_datetime_postfix');

		$row['entry'] = $this->cutDown(stripslashes($row['entry']));
		$row['entrycomment'] = stripslashes($row['entrycomment']);

		if ($this->code == 'TEASER') {
			$words = split(' ', $row['entry']);
			if (is_array($words) && count($words)>0 && strlen($row['entry'])>$this->config['teasercut']) {
				foreach ($words AS $word) {
					if (strlen($teaser) <= $this->config['teasercut']) {
						$teaser .=  $word.' ';
					}
				}
				$markerArray['###GUESTBOOK_ENTRY###'] = $teaser.'[...]';
			}
			else {
				$markerArray['###GUESTBOOK_ENTRY###'] = $row['entry'];
			}

		} else {
			$markerArray['###GUESTBOOK_ENTRY###'] = nl2br($row['entry']);
		}


		$markerArray['###GUESTBOOK_ENTRY###'] = $this->substituteEmoticons($markerArray['###GUESTBOOK_ENTRY###']);
		$markerArray['###GUESTBOOK_ENTRYCOMMENT###'] = $this->substituteEmoticons(nl2br($row['entrycomment']));

		// Adds hook for processing of extra item markers
		if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['extraItemMarkerHook'])) {
			foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['extraItemMarkerHook'] as $_classRef) {
				$_procObj = & t3lib_div::getUserObj($_classRef);
				$markerArray = $_procObj->extraItemMarkerProcessor($markerArray, $row, $this->config, $this);
			}
		}

		return $markerArray;
	}

	/**
	 * Cutting down a string
	 *
	 * @param	string	$text: String that has to be cut down
	 * @return	string	Shorten string
	 */
	function cutDown($text) {

		if ($this->config['wordcut'] < 1)
			return $text;

		if (strlen($text) <= $this->config['wordcut'])
			return $text;

		$splitted_words = explode(' ', $text);

		if (is_array($splitted_words) && count($splitted_words)>0 ) {

			$cutwords = array();

			foreach ($splitted_words AS $word) {
				if (strlen($word)>$this->config['wordcut'])
					$cutwords[] = substr($word, 0, $this->config['wordcut']) . '[..]';
				else
					$cutwords[] = $word;
			}

			return implode(' ', $cutwords);
					if ($this->for_tt_news){
						$saveData['uid_tt_news']=$this->tt_news['tx_ttnews[tt_news]'];
					}

		}
		else
			return $text;
	}

	/**
	 * Generates a pibase-compliant typolink
	 *
	 * @param	string		$tag: string to include within <a>-tags; if empty, only the url is returned
	 * @param	string		$id: page id (could of the form id,type )
	 * @param	array		$vars: extension variables to add to the url ($key, $value)
	 * @param	array		$unsetVars: extension variables (piVars to unset)
	 * @param	boolean		$usePiVars: if set, input vars and incoming piVars arrays are merge
	 * @return	string		generated link or url
	 */
	function get_url($tag = '', $id, $vars = array(), $unsetVars = array(), $usePiVars = true) {

		$vars = (array) $vars;
		$unsetVars = (array)$unsetVars;
		if ($usePiVars) {
			$vars = array_merge($this->piVars, $vars); //vars override pivars
			while (list(, $key) = each($unsetVars)) {
				// unsetvars override anything
				unset($vars[$key]);
			}
		}
		while (list($key, $val) = each($vars)) {
			$piVars[$this->prefixId . '['. $key . ']'] = $val;
		}
		if ($tag) {
			return $this->cObj->getTypoLink($tag, $id, $piVars);

		} else {
			return $this->cObj->getTypoLink_URL($id, $piVars);
		}
	}


	/**
	 * Generating the form for new guestbook entries
	 *
	 * @return	string		$content : the form (HTML)
	 */
	function displayForm() {
		if (is_array($this->LOCAL_LANG) && count($this->LOCAL_LANG) > 0)
		{
			$form = $this->cObj->getSubpart($this->templateCode, '###TEMPLATE_FORM###');

			$substituteArray = array('firstname', 'surname', 'email', 'homepage', 'place', 'entry', 'submit', 'captcha_response', 'captcha');

			foreach ($substituteArray AS $marker) {
				$markerArray['###FORM_'.strtoupper($marker).'###'] = $this->pi_getLL('form_'.$marker);
			}

			$markerArray['###PID###'] = $GLOBALS["TSFE"]->id;
			$url = $this->getUrl($GLOBALS["TSFE"]->id);
			$markerArray['###ACTION_URL###'] = $url;
## CAPTCHA PLUGIN #########################################################################################################################################################
if (t3lib_extMgm::isLoaded('captcha'))	{
#creating any random string to workarround browser caching of old captcha image
	$anything = date("d.m.Y-H:i:s",time());
	$captchaHTMLoutput = '<img src="'.t3lib_extMgm::siteRelPath('captcha').'captcha/captcha.php?'.$anything.'" alt="No Spam!" />';
} else {
	$captchaHTMLoutput = '';
}
$markerArray['###CAPTCHA_INSERT###'] = $captchaHTMLoutput;
## CAPTCHA PLUGIN #########################################################################################################################################################
                        $this->postvars = t3lib_div::GPvar('tx_veguestbook_pi1');
			if ($this->postvars['submitted'] == 1) {


				if (isset($this->postvars['homepage'])) {
					if (!strstr($this->postvars['homepage'], 'http://') && !empty($this->postvars['homepage'])) {
						$this->postvars['homepage'] = 'http://'.$this->postvars['homepage'];
					}
				}

				foreach($this->postvars as $k => $v) {
					$markerArray['###VALUE_'.strtoupper($k).'###'] = stripslashes($v);
				}

				$error = $this->checkForm();

				if (!empty($error)) {
					$markerArray['###FORM_ERROR###'] = $this->pi_getLL('form_error');
					$markerArray['###FORM_ERROR_FIELDS###'] = $error;
				} else {

					$db_fields = array('firstname', 'surname', 'email', 'homepage', 'place', 'entry');

					$saveData['uid'] = '';
					$saveData['pid'] = $this->config['pid_list'];
					$saveData['tstamp'] = time();
					$saveData['crdate'] = time();
					$saveData['deleted'] = '0';
					$saveData['sys_language_uid'] = $this->sys_language_uid;
					$saveData['remote_addr'] = $_SERVER['REMOTE_ADDR'];

					if ($this->for_tt_news){
						$saveData['uid_tt_news']=$this->tt_news['tx_ttnews[tt_news]'];
					}

					if ($this->config['manual_backend_release'] == 1) {
						$saveData['hidden'] = '1';
					} else {
						$saveData['hidden'] = '0';
					}

					foreach ($this->postvars AS $k => $v)
					{
						if (in_array($k, $db_fields)) {

							if ($this->config['strip_tags']) {
								$v = strip_tags($v);
							}

							$saveData[$k] = $v;
						}
					}

					$insert = $GLOBALS['TYPO3_DB']->exec_INSERTquery($this->strEntryTable, $saveData);

					if ($insert) {

						if (!empty($this->config['notify_mail'])) {
							$this->sendNotificationMail($this->config['notify_mail']);
						}

						if (!empty($this->postvars['email']) && $this->config['feedback_mail']) {
							$this->sendFeedbackMail($this->postvars['email']);
						}

						if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['postEntryInsertedHook'])) {
							foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['postEntryInsertedHook'] as $_classRef) {
								$_procObj = & t3lib_div::getUserObj($_classRef);
								$_procObj->postEntryInsertedProcessor($this);
							}
						}

						header('Location: '.t3lib_div::getIndpEnv('TYPO3_REQUEST_DIR').$this->getUrl($this->config['redirect_page']));
					}
				}
			}

            // Pre-fill form data if FE user in logged in
            if (!$this->postvars && $GLOBALS['TSFE']->loginUser) {
					$surname_pos = strpos($GLOBALS['TSFE']->fe_user->user['name'], ' ');
                    $markerArray['###VALUE_FIRSTNAME###'] = substr($GLOBALS['TSFE']->fe_user->user['name'], 0, $surname_pos);
                    $markerArray['###VALUE_SURNAME###'] = substr($GLOBALS['TSFE']->fe_user->user['name'], ($surname_pos+1));
                    $markerArray['###VALUE_EMAIL###'] = $GLOBALS['TSFE']->fe_user->user['email'];
                    $markerArray['###VALUE_HOMEPAGE###'] = $GLOBALS['TSFE']->fe_user->user['www'];
                    $markerArray['###VALUE_PLACE###'] = $GLOBALS['TSFE']->fe_user->user['city'];
            }

			$markerArray = $this->markObligationFields($markerArray);

			// Adds hook for processing of extra item markers
			if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['extraItemMarkerHook'])) {
				foreach($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['ve_guestbook']['extraItemMarkerHook'] as $_classRef) {
					$_procObj = & t3lib_div::getUserObj($_classRef);
					$markerArray = $_procObj->extraItemMarkerProcessor($markerArray, $row, $this->config, $this);
				}
			}

			$form = $this->cObj->substituteMarkerArrayCached($form, $markerArray, array(), array());

			$form = ereg_replace('###[A-Za-z_1234567890]+###', '', $form);

			return $form;
		}
	}

	/**
	 * Returns an array with additional Link parameters
	 * from chc-forum @author Zach Davis <zach@crito.org>
	 *
	 * @param	string		$addParamsList: comma-seperated list of parameters that will be added to all links.

	 * @return	array		additional link parameters in an array
	 */
	function getAddParams($addParamsList){
	 	$queryString = explode('&', t3lib_div::implodeArrayForUrl('', $GLOBALS['_GET'])) ;

		if ($queryString) {
			while (list(, $val) = each($queryString)) {
				$tmp = explode('=', $val);
				$paramArray[$tmp[0]] = $tmp[1];
			}

			while (list($pk, $pv) = each($paramArray)) {

				if (t3lib_div::inList($addParamsList, $pk)) {
					$addParamArray[$pk]=$pv ;
				}
			}
		}

		return $addParamArray;
	 }

	/**
	 * Gets the e-mail name out of the configuration
	 *
	 * @return	string		Name
	 */
	function getEmailFromName() {
		if (!empty($this->config['email_from_name']))
			return $this->config['email_from_name'];
		else
			return "ve_guestbook";
	}

	/**
	 * Gets the e-mail address out of the configuration
	 *
	 * @return	string		E-Mail
	 */
	function getEmailFromMail() {
		if (!empty($this->config['email_from_mail']))
			return $this->config['email_from_mail'];
		else
			return "ve_guestbook@".$_SERVER['SERVER_NAME'];;
	}

	/**
	 * After submitting a new entry you can activate a notification mail to remind the admin
	 *
	 * @param	string		$emailto: E-Mail recipient
	 * @return	boolean		Mail delivery: true / false
	 */
	function sendNotificationMail($emailto) {
		$notification_mail_subject = $this->pi_getLL('notification_mail_subject');
		$notification_mail_text = $this->pi_getLL('notification_mail_text');

		$markerArray['###SERVER_NAME###'] = $_SERVER['SERVER_NAME'];
		$markerArray['###URL###'] = t3lib_div::getIndpEnv('TYPO3_SITE_URL').$this->getUrl($this->config['guestbook']);

		if (is_array($this->postvars)) {
			foreach ($this->postvars AS $k => $v) {
				$markerArray['###'.strtoupper($k).'###'] = stripslashes($v);
			}

			$notification_mail_subject = $this->cObj->substituteMarkerArrayCached($notification_mail_subject, $markerArray, array(), array());
			$notification_mail_text = $this->cObj->substituteMarkerArrayCached($notification_mail_text, $markerArray, array(), array());

			$emailfrom_name = $this->getEmailFromName();
			$emailfrom = $this->getEmailFromMail();

			return t3lib_div::plainMailEncoded($emailto, $notification_mail_subject, $notification_mail_text, "From: ".$emailfrom_name." <".$emailfrom.">\r\nReply-To: ".$emailfrom);
		}
	}

	/**
	 * After submitting a new entry you can activate a feedback mail for the submitting user
	 *
	 * @param	string		$emailto: E-Mail recipient
	 * @return	boolean		Mail delivery: true / false
	 */
	function sendFeedbackMail($emailto) {

		$notification_mail_subject = $this->pi_getLL('feedback_mail_subject');
		$notification_mail_text = $this->pi_getLL('feedback_mail_text');

		$markerArray['###SERVER_NAME###'] = $_SERVER['SERVER_NAME'];
		$markerArray['###URL###'] =
			t3lib_div::getIndpEnv('TYPO3_SITE_URL').$this->getUrl($this->config['guestbook']);

		if (is_array($this->postvars)) {
			foreach ($this->postvars AS $k => $v) {
				$markerArray['###'.strtoupper($k).'###'] = stripslashes($v);
			}

			$notification_mail_subject = $this->cObj->substituteMarkerArrayCached($notification_mail_subject, $markerArray, array(), array());
			$notification_mail_text = $this->cObj->substituteMarkerArrayCached($notification_mail_text, $markerArray, array(), array());

			$emailfrom_name = $this->getEmailFromName();
			$emailfrom = $this->getEmailFromMail();

			return t3lib_div::plainMailEncoded($emailto, $notification_mail_subject, $notification_mail_text, "From: ".$emailfrom_name." <".$emailfrom.">\r\nReply-To: ".$emailfrom);
		}
	}
	/**
	 * Getting the URL to the given ID with all needed params
	 *
	 * @param	integer		$id: Page ID
	 * @return	string		$url: URL
	 */
	function getUrl($id)
	{
		if (t3lib_div::_GP('L')) {
			$urlParameters['L'] = t3lib_div::_GP('L');
		}

		#$urlParameters = array_merge($urlParameters, $this->tt_news);
		$urlParameters = array($urlParameters, $this->tt_news);
		return $this->pi_getPageLink($id, '',$urlParameters);
	}

	/**
	 * All obligation fields will be marked in the form
	 *
	 * @param	array		$markerArray: template marker array
	 * @return	array		$markerArray: filled template marker array
	 */
	function markObligationFields($markerArray) {
		if (is_array($this->config['obligationfields']) && count($this->config['obligationfields'])>0) {
			foreach ($this->config['obligationfields'] AS $obl_field) {
				$markerArray['###FORM_'.strtoupper($obl_field).'_OBLIGATION###'] = '*';
			}
		}

		return $markerArray;
	}

	/**
	 * Emoticons substitution
	 * wrap the string with this function to replace emoticontags with emoticonicons
	 *
	 * @param	string		the message
	 * @return	string		The message with replaced emoticon string as image
	 */
	function substituteEmoticons($str)	{
		if ($this->conf['emoticons.']['active']==1)	{
			reset($this->conf['emoticons.']['subst.']);
			$emoConf = $this->conf['emoticons.'];
			while(list($source,$dest)=each($emoConf['subst.']))	{
				$imgFile = str_replace('###EMOTICON###', $dest['val'], $emoConf['10.']['file']);

				if (strstr($dest['str'], '||')) {
					$aohIcons = explode('||', $dest['str']);

					foreach ($aohIcons as $icon) {

						$str = str_replace(trim($icon),  $this->cObj->cImage($imgFile, $emoConf['10.']), $str);
					}
				}
				else {
					$str = str_replace(trim($dest['str']),  $this->cObj->cImage($imgFile, $emoConf['10.']), $str);
				}
			}
		}
		return $str;
	}

	/**
	 * Method for checking the user input in the form mode
	 *
	 * @return	string		$error Error-Code (HTML)
	 */
	function checkForm() {
## CAPTCHA PLUGIN #########################################################################################################################################################
# Getting the Captcha String #################
if (t3lib_extMgm::isLoaded('captcha'))	{
	session_start();
	$captchaStr = $_SESSION['tx_captcha_string'];
	$_SESSION['tx_captcha_string'] = '';
} else {
	$captchaStr = -1;
}
# Evaluating the captcha string
#if ($this->postvars['captcha_response'] != $captchaStr) {
if (strcasecmp($this->postvars['captcha_response'], $captchaStr) != 0) {
$error .= '<li>Eingabe des Antispamcode war leider falsch, bitte nochmal probieren!</li>';
}
## CAPTCHA PLUGIN #########################################################################################################################################################

		if (is_array($this->config['obligationfields']) && count($this->config['obligationfields'])>0) {
			foreach ($this->config['obligationfields'] AS $obl_field) {
				if (empty($this->postvars[$obl_field])) {
					$error .= '<li>'.ucfirst($this->pi_getLL('form_'.$obl_field))."</li>\n";
				}
			}
		}

		if ($this->config['email_validation'] && !empty($this->postvars['email'])) {

			if (t3lib_div::validEmail($this->postvars['email']) == false) {
				$error .= '<li>'.$this->pi_getLL('form_email')." (".$this->pi_getLL('form_invalid_field').")</li>\n";
			}
		}

		if ($this->config['website_validation'] && !empty($this->postvars['homepage']) && $this->postvars['homepage'] != 'http://') {
			if ($this->isURL($this->postvars['homepage']) == false) {
				$error .= '<li>'.ucfirst($this->pi_getLL('form_homepage'))." (".$this->pi_getLL('form_invalid_field').")</li>\n";
			}
		}

		if (!empty($error)) {
			return "<ul>\n".$error."</ul>\n";
		}
	}

	/**
	 * URL validation method
	 *
	 * @param	string		$url: URL to validate
	 * @return	boolean		Success: valid / not valid
	 */
	function isURL($url) {
		if (!preg_match('#^http\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url)) {
			return false;
		} else {
			return true;
		}
	}
}



if (defined("TYPO3_MODE") && $TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/ve_guestbook/pi1/class.tx_veguestbook_pi1.php"])	{
	include_once($TYPO3_CONF_VARS[TYPO3_MODE]["XCLASS"]["ext/ve_guestbook/pi1/class.tx_veguestbook_pi1.php"]);
}

?>
```

und hier noch das veränderte Captcha script, damit die Grafik schöner ist. Den Code habe ich im Internet gefunden...

Captcha Library (captcha)
captcha/captcha.php

```php
<?php
/***************************************************************************
 *
 *   Filename   		  : image.php
 *   Began			  : 2005/04/04
 *   Modified   		  :
 *   Copyright  		  : (c) 2005 xkare.com
 *   Version    		  : 1.0
 *   Written by 		  : Mert ÖÐÜT in istanbul / TURKEY
 *
 *   You are encouraged to redistribute and / or modify this program under the terms of
 *   the GNU General Public License as published by the Free Software Foundation
 *    (www.fsf.org); any version as from version 2 of the License.
 *
 ***************************************************************************/
session_start();
function strrand($length)
{
	$str = "";

	while(strlen($str)<$length){
	$random=rand(48,122);
	#if( ($random>47 && $random<58-)  ){
	if (ereg('[A-Za-z]',chr($random)))
		$str.=chr($random);
	#}

	}

	return $str;
}



$word = $_SESSION['tx_captcha_string'] = strrand(5);
$im = imagecreate(150, 40); // Create new 150 x 40 image
// Set colors for image
$background_color = imagecolorallocate($im, 255, 255, 255);
$text_color = imagecolorallocate($im, 0, 0, 0);
$line = imagecolorallocate($im, 201, 201, 201);
$circle = imagecolorallocate($im, 193, 224, 231);
if($word){
   while($obj['ell']<5){
      // Draw ellipse in background
      imagefilledellipse($im,rand(10,140),rand(5,38-),rand(20,60),rand(5,35),$circle);
      ++$obj['ell']; // Increment ellipse count
   }
   while($obj['lines']<10){
      // Draw line in background
      imageline($im,rand(1,150),rand(1,20),rand(1,150),rand(30,40),$line);
      ++$obj['lines']; // Increment line count
   }
   $letters = preg_split("//",$word); // Split secret word into letters
   $cur_x = 5; // Start x location of letters
   foreach($letters as $value){ // Loop for all letters
      $cur_x = rand(10,20) + $cur_x;
      imagestring($im,4,$cur_x,rand(10,18-),$value,$text_color); // Put letter on image
   }
}else{
   // Put error on image
   imagestring($im, 4, 55, 5, "Error!", $text_color);
   imagestring($im, 4, 10, 20, "Reload the page!", $text_color);
}
// Draw border around image
imageline($im, 0, 0, 149, 0, $text_color); // Top horizontal
imageline($im, 0, 0, 0, 39, $text_color); // Left vertical
imageline($im, 149, 0, 149, 39, $text_color); // Right vertical
imageline($im, 0, 39, 149, 39, $text_color); // Bottom horizontal

header("Content-type: image/gif"); // Set display mode as PNG
imagegif($im); // Display image
imagedestroy($im); // Delete image from memory cache


#$text = $_SESSION['tx_captcha_string'] = strrand(5);
#$imgHeight = 17;
#$imgWidth = 47;
#$img_number = imagecreate($imgWidth,$imgHeight);
#$backcolor = imagecolorallocate($img_number,244,244,244);
#$textcolor = imagecolorallocate($img_number,0,0,0);
#$white = imagecolorallocate($img_number, 0xFF, 0xFF, 0xFF);
#imagefill($img_number,0,0,$backcolor);
#Imagestring($img_number,5,1,1,$text,$textcolor);
#
#       //some obfuscation
#        for ($i=0; $i<3; i="" x1="" imgwidth="" -="" 1="" y1="" roundimgheight="" 10="" x2="" roundimgwidth="" y2="" imgheight="" imagelineimg_number="" white="" rand1="" cx="" 50="" 25="" cy="" w="" 24="" imagearcimg_number="" 360="" headercontent-type:="" imagegif="" imagegifimg_number="">
```

zusätzlich muss im Gästebuchtemplate noch folgendes hinzugefügt werden:

```html
###CAPTCHA_INSERT###                                                  ###FORM_CAPTCHA###
<input type="text" name="tx_veguestbook_pi1[captcha_response]" value="" class="tx-guestbook-form-inputfield-big" />
```

viel Erfolg damit - bei mir funktioniert es jetzt  #giggle#

sagt hier bescheid, obs funzt. Achja, Freecap Extension habe ich auch ausprobiert, aber das Captchabild hat mir nicht gefallen und die Abfrage hat nicht gleich funktioniert. Im Gästebuch ist die Abfrage im Moment Caseinsesitive, kann man an der Markierten Stelle selber ändern indem man einfach die auskommentierte Zeile nimmt statt der vorhandenen...

Greets, Stonie

### [#5](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/5) · Unbekannter Benutzer · 2005-11-13

Sehr schön...

Ich würde auch gerne Cptcha mit dem Gästebuch verbinden...

Ich scheue mich aber etwas davo einfach die PHP Datei zu überschreiben und dann funktioniert vielleicht das restliche Gästebuch nicht mehr. Es kann ja schließlich sein, dass die Version Gästebuch Extension nicht übereinstimmt...

Vielleicht wäre es daher besser, wenn du nur den Teil posten könntest, der sich in der PHP Datei des Gästebuch geändert hat.
1. Damit das auch nachvollziehen kann
2 damit man weiß wo genau das hin gehört.

### [#6](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/6) · Unbekannter Benutzer · 2005-11-13

Nehme alles zurück und behaupte das Gegenteil!

Hab bei mir die beiden Code-Schnipsel eingebaut und auch den fürs Template. Klappt sehr gut!
Habe dabei noch die Farben der Grafik etwas abgestimmt und in das Formular des GB eingepflget mit einer kleinen Erklärung dazu.

Klappt auf jeden Fall sehr gut! Vielen vielen Dank dafür!

### [#7](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/7) · Dade Murphy · 2005-11-14

Hallo SLang, freut mich, dass Du es gebrauchen konntest. Schoene Seite hast Du. Für die anderen: der Hack ist für das "aktuelle Modern Guestbook 1.7.4" und "Captcha Library 1.0.0". Die Änderungen habe ich kommentiert, ihr koennt aber auch per cut&paste alles komplett rüberziehen wenns schnell gehen soll... viel Spass, greets, Stonie

### [#8](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/8) · Unbekannter Benutzer · 2005-11-15

Jo dank dir...

Falls es nochmal je,amd wissen möchte:
Der Hack läuft auch anstandslos und sofort in älteren ve-guestbook versionen, wie zum Beispiel 1.6.9
Ein Zwangsupdate ist also nicht nötig...

Bestens

### [#9](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/9) · Renko · 2005-12-02

Falls noch niemand gesehen hat in der aktuellen ve_guestbookversion 1.10 ist die Integration als beta vorhanden

Captcha function to avoid spamming +++ using sr_freecap +++ beta version +++ feel free to send me feedback

Ich habe die Integration aus dem Forum an Udo von Eynern geschickt und ihn gebeten , diese funktionalität als option ins Gästebuch zu integrieren ! 1 Tag später nun schon als Beta enthalten  .

Also runterladen und fleissig testen und eventuelle bugs reporten !

Habs schon ausprobiert , er hat es mit sr_freecap umgesetzt , einfach extension hochladen und sr_freecap aktivieren und eventuell bei eigen verwendeten GuestebookTemplate ergänzungen aus ve_guestbook Orginal template hinzufügen

### [#10](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/10) · swishi · 2006-02-17

**Renko schrieb:**

> ... einfach extension hochladen und sr_freecap aktivieren und eventuell bei eigen verwendeten GuestebookTemplate ergänzungen aus ve_guestbook Orginal template hinzufügen...

Hallo,
Da mein Gästebuch seit ein paar Wochen extrem gespamt wird (über 30 Spameinträge/Tag)wollte ich die captcha funktion einbauen komme aber nicht weiter... habe die neuste version von ve_guestbook (1.9.6) und sr_freecap (0.2.3). Das ve_guestbook Handbuch gibt keinerlei Hinweis wie man captcha aktiviert noch kann ich es im Template finden... bin für jeden Hinweis dankbar!

Gruss

SWISHI

### [#11](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/11) · Renko · 2006-02-19

Hallo Swishi:

ist eigentlich ganz einfach
du solltest´dir die aktuelle ve_guestbook 1.11.0 herunter laden

sobald sr_freecap installiert ist merkt das ve_guestbook und aktiviert das captcha im Template !

Du musst halt auch das neue Template aus der Version 1.11.0 nehmen!

### [#12](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/12) · swishi · 2006-02-19

**Renko schrieb:**

> du solltest´dir die aktuelle ve_guestbook 1.11.0 herunter laden

Danke Renko für die Antwort... typo3.net da werden Sie geholfen...
Sorry, aber vielleicht steh ich auf dem Schlauch... wenn ich mich über die typo installation ins repository einlogge kommt als aktuelle version von ve_guesbook 1.9.6??? Wo gibt es die 1.11.0?

Gruss und danke

SWISHI

### [#13](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/13) · swishi · 2006-02-19

wer sucht der findet... ich habs gefunden! 8-)
Danke für die Hilfe an alle!

Gruss & keep on rocking

SWISHI

### [#14](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/14) · lordrob · 2006-03-20

Hallo zusammen
Vielleicht kann mir ja jemand auf die sprünge helfen...
ich habe die code-schnippsel, wie gepostet abgeändert und die extension installiert.
kriege aber immernoch ca 6 spam-einträge pro stunde und da wo das bild mit dem captcha-code erscheinen sollte, kommt bei mir nur immer ein bild mit "No Spam!". #angry#
Weiss jemand vielleicht gerade abhilfe`?? ich wäre sehr dankbar!
gruss
rob

### [#15](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/15) · lordrob · 2006-03-24

ich antworte mir mal gleich selber...:
dank dem support von hostpoint.ch habe ichs dann doch noch rausgekriegt.
das problem lag bei der berechtigung auf file-ebene. im install-tool wars so eingestellt, dass ich neue extensions mit permission 775 anstatt 755 angelegt habe.
grüsse

### [#16](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/16) · wyps · 2006-03-28

...und wo musstest Du das einstellen?
Habe nämlich grade das gleiche Problem.

Danke Dir für Deine Hilfe
Matthias

### [#17](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/17) · kinnaj · 2006-04-03

Ich versuche gerade ve_guestbook und sr_freecap zu installieren, allerdings finde ich nur sr_freecap 0.3.0, was aber bei meinem Typo3 3.7.0 nicht funktioniert.

Kann mir jemand eine ältere Version von sr_freecap geben?

Vielen Dank!

### [#18](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/18) · Wu-mc · 2006-04-04

@ swishi

wo hast du die Version 1.11.0 gefunden? Ich hab bei mir auch nur die 1.9.6 in der Repository. Muss ich die über typo3.org runterladen?

Kann ich die irgendwie über eine vorhandenes Guestbook drüber installieren?

### [#19](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/19) · just2b · 2006-04-04

> **Wu-mc schrieb:**
>
> wo hast du die Version 1.11.0 gefunden? Ich hab bei mir auch nur die 1.9.6 in der Repository.

Extension Manager > suchst dir ve_guestbook > klickst auf den titel > links oben im dropdown kannst du die version bestimmen

lg georg

### [#20](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/20) · Wu-mc · 2006-04-04

Hallo just2b,

vielen Dank, hat wunderbar geklappt. Jedoch noch eine Frage, ist das jetzt automatisch aktiv, also das zum Blocken von Spambots? Weil ich keine Einstellung finden konnte. Oder muss ich dazu die 1.11 nehmen? Hab jetzt die 1.12er genommen.

### [#21](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/21) · Renko · 2006-04-04

Einfach sr_freecap installieren und das neue Template verwenden , dann solltest du die VEränderung auf der Eintragsseite sehen

### [#22](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/22) · Pluto · 2006-05-09

Moin liebe Forumgemeinde!

Bei mir funzt captcha im ve_guestbook so weit.
Nur das captcha-Bild ist ein wenig klein! :o

**Hat jemand eine Idee wie man das captcha-Bild insgesamt vergrößern kann?**

### [#23](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/23) · McCavity · 2006-05-10

> **Pluto schrieb:**
>
> **Hat jemand eine Idee wie man das captcha-Bild insgesamt vergrößern kann?**

Schau in Deinem Template im Constant Editor die "PLUGIN.TX_SRFREECAP" Konstanten an. Dort findest Du zum Beispiel "CAPTCHA image height"

### [#24](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/24) · GreaseGun · 2006-05-10

bei mir (ve_guestbook  	1.12.0 und sr_freecap  	0.3.3) wird nur der alt-text für die grafik eingeblendet.
wasmussichtun?

### [#25](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/25) · Pluto · 2006-05-10

Danke @McCavity!

Das klingt gut - aber ich habe nicht SRFREECAP, sondern die Capture-Libriary (capture).
Ich hab' mir 'nen Wolf gesucht: Diese Extension (Plugin/Lib?) hinterläßt im BE keine Spuren. Weder im Constant/Setup-Editor noch in der Constant-Oberfläche. Auch eine Suche im Objekt-Analyser verlief erfolglos.
Die Doku der Extension ist sehr spärlich, Eigenschaften werden erst gar nicht angesprochen.

Ich hab' es mit PHP in der captcha.php versucht:

```php
<?php
/***************************************************************************
 *
 *   Filename   		  : image.php
 *   Began			  : 2005/04/04
 *   Modified   		  :
 *   Copyright  		  : (c) 2005 xkare.com
 *   Version    		  : 1.0
 *   Written by 		  : Mert ÖÐÜT in istanbul / TURKEY
 *
 *   You are encouraged to redistribute and / or modify this program under the terms of
 *   the GNU General Public License as published by the Free Software Foundation
 *    (www.fsf.org); any version as from version 2 of the License.
 *
 ***************************************************************************/
session_start();
function strrand($length)
{
	$str = "";

	while(strlen($str)<$length){
	$random=rand(48,122);
	#if( ($random>47 && $random<58-)  ){
	if (ereg('[A-Za-z]',chr($random)))
		$str.=chr($random);
	#}

	}

	return $str;
}

# $imgHeight = 17;
# $imgWidth = 47;

$imgHeight = 34;
$imgWidth = 94;

$text = $_SESSION['tx_captcha_string'] = strrand(5);
$img_number = imagecreate($imgWidth,$imgHeight);
$backcolor = imagecolorallocate($img_number,244,244,244);
$textcolor = imagecolorallocate($img_number,0,0,0);
$white = imagecolorallocate($img_number, 0xFF, 0xFF, 0xFF);

imagefill($img_number,0,0,$backcolor);

Imagestring($img_number,5,1,1,$text,$textcolor);

        //some obfuscation
        for ($i=0; $i<3; $i++) {
            $x1 = rand(0, $imgWidth - 1);
            $y1 = rand(0, round($imgHeight / 10, 0));
            $x2 = rand(0, round($imgWidth / 10, 0));
            $y2 = rand(0, $imgHeight - 1);
            imageline($img_number, $x1, $y1, $x2, $y2, $white);

			$x1 = rand(0, $imgWidth - 1);
            $y1 = $imgHeight - rand(1, round($imgHeight / 10, 0));
            $x2 = $imgWidth - rand(1, round($imgWidth / 10, 0));
            $y2 = rand(0, $imgHeight - 1);
            imageline($img_number, $x1, $y1, $x2, $y2, $white);

/*			$cx = rand(0, $imgWidth - 50) + 25;
			$cy = rand(0, $imgHeight - 50) + 25;
			$w = rand(1, 24);
			imagearc($img_number, $cx, $cy, $w, $w, 0, 360, $white);
   */     }


header("Content-type: image/png");
imagepng($img_number);
```

Die Änderungen der Zeilen 36 u.37 haben jedoch lediglich eine Vergrößerung des Bildhintergrundes geführt.
Nun bin ich kein PHP-Guru, aber ich meine förmlich zu riechen, dass man hier die Größe der Ziffern ändern kann??

[Bild: feuerwehr-bremen.org/…/captcha.php](http://www.feuerwehr-bremen.org/typo3conf/ext/captcha/captcha/captcha.php?10.05.2006-08:56:57)

In freudiger Erwartung eines kleinen hilfreichen Hinweises ;)

### [#26](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/26) · Ted · 2006-05-10

```php
Imagestring($img_number,5,1,1,$text,$textcolor);
```

der zweite Wert ist die Textgröße, nämlich 5. Es ist nur 1 - 5 möglich. Du kannst auch imageloadfont() ausprobieren, das aber nur Bitmapfonts lädt.

Ich empfehle Dir, die Zeile komplett auszutauschen mit:

```php
$font = dirname($_SERVER["SCRIPT_FILENAME"]) . "verdana.ttf"; 
imagettftext($img_number, 20, 0, 10, 20, $textcolor, $font, "info@test.ch");
```

GD und Freetype muss installiert sein, der Font muss im Scriptverzeichnis abgelegt sein. Hab ich aber nicht getestet, ich nehme an Du musst den Pfad noch anpassen, da Du sonst den Pfad der index.php von Typo3 bekommst anstatt den der captcha.php

<http://www.selfphp.info/funktionsreferenz/image_funktionen/imagettftext.php>

Gruß,
Ted

### [#27](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/27) · Pluto · 2006-05-11

Jau - das läuft so weit

**Danke @Ted! ;)**

Das Prob mit dem Scriptpfad ist real gar nicht aufgetreten, eine einfache Angabe der *.ttf genügt.

### [#28](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/28) · tropical · 2006-05-23

Hallo ich habe auch ein Problem damit. Das Bild wird nicht angezeigt. <http://www.iprzw.de/index.php?id=12> hier könnt ihr euch das mal ansehen.

Wäre super, wenn mir jemand helfen könnte.

Danke und LG

Tobi

### [#29](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/29) · Ted · 2006-05-24

diese url bringt bei meiner domain bei jedem reload ein anderes captchabild:

<http://www.iprzw.de/typo3conf/ext/sr_freecap/pi1/captcha.php?id=12>

bringt bei Dir

Warning: fopen(/home/httpd/vhosts/iprzw.de/httpdocs/**typo3temp**/llxml/xml_f9cc07bc6d.de.iso-8859-1.cache) [function.fopen]: failed to open stream: **Permission denied** in /home/httpd/vhosts/iprzw.de/httpdocs/t3lib/class.t3lib_div.php on line 2117
**ERROR: File not written to disk! Write permission error** in filesystem?

Write permission error in filesystem? <---- darf es in /typo3temp/ schreiben? Sind die Schreibrechte für Typo3 alle bei der Installation passend gesetzt worden?   #angry#

viel Glück,
Gruß, Ted

### [#30](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/30) · tropical · 2006-05-25

Danke, daran hat es gelegen. Die Datei war nicht vorhanden habe sie angelegt und in den Ordner hochgeladen. Jetzt läuft alles bestens. :)

### [#31](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/31) · Evchen · 2006-06-22

Hab ein Problem mit sr_freecap... Er zeigt das Bild einfach nicht an...

Typo3: 3.7.0
ve_guestbook: 1.12.0
sr_freecap: 0.4.3

Wenn ich die Datei <http://www.mrs-twisting-smith.de/cms/typo3conf/ext/sr_freecap/pi1/captcha.php?id=6>
aufrufe kommt die Fehlermeldung:

**Fatal error:** Call to undefined function: connecttodb() in /home/httpd/vhosts/mrs-twisting-smith.de/httpdocs/cms/typo3conf/ext/sr_freecap/pi1/captcha.php on line 73

Woran kann das liegen? Habe noch keine Extension bearbeitet, alles noch Original!

Hatte vorher noch nie Probleme mit der DB oder Installation/Anpassung irgendwelcher Extensions oä...

Bin dankbar für jeden Tipp!

LG Evchen

### [#32](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/32) · Evchen · 2006-06-26

Musste sr_freecap deaktivieren, da das Gästebuch auf einer Seite läuft, die Online ist und sich dann ja keiner mehr eintragen kann!

Wäre trotzdem dankbar, wenn mir jemand helfen könnte!!

### [#33](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/33) · thefox · 2007-02-04

Hallo Evchen

hatte soeben das selbe Probelm "**Call to undefined function: connecttodb()...**" .... "**captcha.php on line 73**".

Ursache des Problems ist, das die Extension auf eine Funktion zugreift, welche erst ab der Typo3 Version 3.8.1 vorhanden ist. Weil bei dir (und bei mir) TYPO3 3.7 im Einsatz ist, wird dies der Grund sein. Welche Extension hast du jetzt genommen, da bei dir der Eintrag-Button erst ab 10 sec. klickbar ist ?

Gruss TheFox

### [#34](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/34) · Evchen · 2007-02-06

Hi Fox,

danke für die Info... werde dann doch irgendwann Typo3 mal updaten müssen...

Mein Eintrag-Button ist mit keiner Extension enstanden... ist mit JavaScript realisiert...

Hier findest du alles was du brauchst:

<http://www.neumueller.net/weblog/posts/artikel/gaestebuch-spam-die-zweite.html>

Damit ist mein Gästebuch bis jetzt (schon seit 4-5 Monaten) Spamfrei geblieben. Hoffe es hilft dir weiter.

LG
Evchen

### [#35](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/35) · Fassi · 2007-04-06

Hallo Zusammen

Der Code/Anleitung von Dade Murphy
funktioniert bei mir tadellos...
...vielen Dank, hat mir viel Arbeit erspart

Gruß
FASSI

### [#36](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/36) · Fassi · 2007-04-08

Anmerkungen:

Hier gibt es ne gute verbesserte Captcha Version, welche sich dan im BE wunderbar konfigurieren läßt
<http://www.sk-typo3.de/News-Details.43+M5f5fa9f9a55.0.html>

...die Code/Anleitung von Dade Murphy funktioniert wirklich gut, allerdings verschwinden die Datumsanzeigen im Gästebuch.

Gruß
FASSI

### [#37](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/37) · Elfe · 2007-04-13

Hallo Fassi,
Im Code von Dade Murphy die Zeilen 492-494 ersetzen mit den Zeilen aus der Originaldatei.

> $markerArray['###GUESTBOOK_DATE###'] = $this->local_cObj->stdWrap($row['crdate'], $this->conf['datetime_stdWrap.']);
> 		$markerArray['###GUESTBOOK_ONLYTIME###'] = $this->local_cObj->stdWrap($row['crdate'], $this->conf['date_stdWrap.']);
> 		$markerArray['###GUESTBOOK_ONLYDATE###'] = $this->local_cObj->stdWrap($row['crdate'], $this->conf['time_stdWrap.']);

Dann klappts auch mit dem Datum und der Uhrzeit.

Gruß
Rainer

### [#38](https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage/38) · Fassi · 2007-04-14

Vielen Dank...

Gruß Fassi

---

Quelle: „ve_guestbook und captcha abfrage“, typo3.net, https://www.typo3.net/d/28025-ve-guestbook-und-captcha-abfrage
Beiträge von Mitgliedern des Forums. Bitte mit Link auf die Diskussion zitieren.
