cvs: pear /Services_Trackback/Services/Trackback/SpamCheck Akismet.php /Services_Trackback/test Services_Trackback_SpamCheck_Akismet_Test.php
Services_Trackback_TestAll.php akismet_key.php
| From: | Tobias Schlitt | Date: | Fri, 17 Feb 2006 15:08:51 +0000 |
| Subject: | cvs: pear /Services_Trackback/Services/Trackback/SpamCheck Akismet.php /Services_Trackback/test Services_Trackback_SpamCheck_Akismet_Test.php Services_Trackback_TestAll.php akismet_key.php |
||
| Groups: | php.pear.cvs | ||
| Request: | Send a blank email to pear-cvs+get-38327@lists.php.net to get a copy of this message | ||
toby Fri Feb 17 15:08:51 2006 UTC
Added files:
/pear/Services_Trackback/Services/Trackback/SpamCheck Akismet.php
/pear/Services_Trackback/test
Services_Trackback_SpamCheck_Akismet_Test.php
akismet_key.php
Modified files:
/pear/Services_Trackback/test Services_Trackback_TestAll.php
Log:
- Adding Akismet.com spamcheck.
# Attention, work in progress.
http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/test/Services_Trackback_TestAll.php?r1=1.3&r2=1.4&diff_format=u Index: pear/Services_Trackback/test/Services_Trackback_TestAll.php diff -u pear/Services_Trackback/test/Services_Trackback_TestAll.php:1.3 pear/Services_Trackback/test/Services_Trackback_TestAll.php:1.4 --- pear/Services_Trackback/test/Services_Trackback_TestAll.php:1.3 Thu Feb 9 19:09:37 2006 +++ pear/Services_Trackback/test/Services_Trackback_TestAll.php Fri Feb 17 15:08:51 2006 @@ -18,5 +18,7 @@ require_once 'Services_Trackback_SpamCheck_SURBL_Test.php'; echo "\n\nRunning test suite for Services_Trackback_SpamCheck_Wordlist\n\n"; require_once 'Services_Trackback_SpamCheck_Wordlist_Test.php'; +echo "\n\nRunning test suite for Services_Trackback_SpamCheck_Wordlist\n\n"; +require_once 'Services_Trackback_SpamCheck_Akismet_Test.php'; ?> http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/Services/Trackback/SpamCheck/Akismet.php?view=markup&rev=1.1 Index: pear/Services_Trackback/Services/Trackback/SpamCheck/Akismet.php +++ pear/Services_Trackback/Services/Trackback/SpamCheck/Akismet.php <?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** * Services_Trackback_SpamCheck_Akismet. * * This spam detection module for Services_Trackback checks the given trackback * against the spam checking webservice Akismet {@link http://akismet.com/} * provided by {@link http://wordpress.com}. ATTENTION: To use this spam check, * you need a valid WordPress.com API key. * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to license@php.net so we can mail you a copy immediately. * * @category Webservices * @package Trackback * @author Tobias Schlitt <toby@php.net> * @copyright 2005-2006 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: Akismet.php,v 1.1 2006/02/17 15:08:51 toby Exp $ * @link http://pear.php.net/package/Services_Trackback * @since File available since Release 0.6.0 */ // {{{ require_once /** * Load PEAR error handling */ require_once 'PEAR.php'; /** * Load SpamCheck base class */ require_once 'Services/Trackback/SpamCheck.php'; /** * HTTP_Request for sending POST requests to Akismet */ require_once 'HTTP/Request.php'; // }}} /** * Akismet * Module for spam detecion using {@link http://akismet.com}. * * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @category Webservices * @package Trackback * @author Tobias Schlitt <toby@php.net> * @copyright 2005-2006 The PHP Group * @version Release: @package_version@ * @link http://pear.php.net/package/Services_Trackback * @since 0.6.0 * @access public */ class Services_Trackback_SpamCheck_Akismet extends Services_Trackback_SpamCheck { // {{{ _options /** * Options for the Wordlist. * * @var array * @since 0.5.0 * @access protected */ var $_options = array( 'continuous' => false, 'sources' => array( 'rest.akismet.com/1.1/', ), // URL of the blog sending the Akismet request 'url' => '', // WordPress.com API key to use 'key' => '', 'elements' => array( 'title', 'excerpt', 'blog_name', 'url', 'host', ), ); // }}} // {{{ Services_Trackback_SpamCheck_Akismet() /** * Constructor. * Create a new instance of the Akismet spam protection module. * * @since 0.5.0 * @access public * @param array $options An array of options for this spam protection module. General options are * 'continuous': Whether to continue checking more sources, if a match has been found. * 'sources': List of Akismet servers URIs. * @return object(Services_Trackback_SpamCheck_Akismet) The newly created SpamCheck object. */ function Services_Trackback_SpamCheck_Akismet($options = null) { if (is_array($options)) { foreach ($options as $key => $val) { $this->_options[$key] = $val; } } } // }}} // {{{ check() function check($trackback) { if (empty($this->_options['url'])) { return PEAR::raiseError('Missing option "url". Cannot procede without it.', 0); } if (empty($this->_options['key'])) { return PEAR::raiseError('Missing option "key". Cannot procede without it.', 0); } if (!is_array($this->_options['sources']) || count($this->_options['sources']) < 1) { return PEAR::raiseError('Missing option "sources". Cannot procede without it.', 0); } if (!is_array(($extra = $trackback->get('extra'))) || count($extra) < 1){ return PEAR::raiseError('Missing data "extra". Cannot procede without it.', 0); } $foundSpam = false; foreach ($this->_options['sources'] as $id => $source) { if ($foundSpam && !$this->_options['continuous']) { // We already found spam and shall not continue $this->_results[$id] = false; } else { if (PEAR::isError($res = $this->_checkSource($this->_options['sources'][$id], $trackback))) { return $res; } $this->_results[$id] = $res; $foundSpam = $foundSpam || $res; } } return $foundSpam; } // }}} // {{{ verifyKey() function verifyKey() { $tmpTrack = Services_Trackback::create(array('id' => 1)); if (PEAR::isError($res = $this->_sendAkismetRequest($this->_options['sources'][0], $tmpTrack))) { var_dump($res); return $res; } return $res == 'valid'; } // }}} // {{{ _checkSource() function _checkSource(&$source, $trackback) { if (PEAR::isError($res = $this->_sendAkismetRequest($source, $trackback, 'comment-check'))) { return $res; } if ($res == 'invalid') { return PEAR::raiseError('Invalid Akismet request send. Maybe your key is invalid?'); } return ($res == 'true'); } // }}} // {{{ _sendAkismetRequest() function _sendAkismetRequest($baseUri, $trackback, $action = 'verify-key') { $action = strtolower($action); $req = null; $options = $trackback->getOptions(); $httpRequestOptions = $options['httprequest']; switch ($action) { case 'verify-key': $url = 'http://' . $baseUri . $action; echo $url; $req = new HTTP_Request($url, $httpRequestOptions); $req->setMethod(HTTP_REQUEST_METHOD_POST); $req->addPostData('key', $this->_options['key']); $req->addPostData('blog', $this->_options['url']); break; case 'comment-check': case 'submit-spam': case 'submit-ham': $url = 'http://' . $this->_options['key'] . '.' . $baseUri . $action; $req = new HTTP_Request($url, $httpRequestOptions); $req->setMethod(HTTP_REQUEST_METHOD_POST); $req->addHeader('User-Agent', $httpRequestOptions['useragent']); $req->addPostData('comment_type', 'trackback'); $req->addPostData('key', $this->_options['key']); $req->addPostData('blog', $this->_options['url']); $req->addPostData('comment_author_url', $trackback->get('url')); $req->addPostData('user_ip', $trackback->get('host')); $extra = $trackback->get('extra'); $req->addPostData('user_agent', $extra['USER_AGENT']); $req->addPostData('referrer', $extra['REFERER']); break; default: return PEAR::raiseError('Invalid Akismet action: "'.$action.'".'); break; } if (($res = $req->sendRequest()) !== true) { return $res; } if ($req->getResponseCode() !== 200) { return PEAR::raiseError('Could not open URL "'.$url.'". Code: "'.$req->getResponseCode().'".'); } return trim($req->getResponseBody()); } // }}} } http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/test/Services_Trackback_SpamCheck_Akismet_Test.php?view=markup&rev=1.1 Index: pear/Services_Trackback/test/Services_Trackback_SpamCheck_Akismet_Test.php +++ pear/Services_Trackback/test/Services_Trackback_SpamCheck_Akismet_Test.php <?php // {{{ require_once // Services_Trackback classes require_once 'Services/Trackback.php'; require_once 'Services/Trackback/SpamCheck.php'; require_once 'Services/Trackback/SpamCheck/Akismet.php'; // Unittest suite require_once 'PHPUnit.php'; // Testdata require_once dirname(__FILE__).'/trackback_data.php'; // Akismet.com API key require_once 'test/akismet_key.php'; // }}} class Webservices_Trackback_SpamCheck_Akismet_TestCase extends PHPUnit_TestCase { var $trackbacks = array(); var $spamCheck; var $options = array(); // {{{ Webservices_Trackback_SpamCheck_Akismet_TestCase() // constructor of the test suite function Webservices_Trackback_SpamCheck_Akismet_TestCase($name) { $this->PHPUnit_TestCase($name); } // }}} // {{{ setup() function setUp() { global $trackbackData; global $akismetApiKey; if (!isset($akismetApiKey) || $akismetApiKey === false) { return false; } foreach ($trackbackData as $id => $set) { $this->trackbacks[$id] = Services_Trackback::create($set); $this->trackbacks[$id]->set( 'extra', array( 'REFERER' => 'http://www.example.com', 'USER_AGENT' => 'Test', ) ); } $this->_options = array( 'url' => 'http://www.schlitt.info/applications/blog/', 'key' => $akismetApiKey, ); $this->spamCheck = Services_Trackback_SpamCheck::create('Akismet', $this->_options); } // }}} // {{{ tearDown() function tearDown() { } // }}} // {{{ Test create() function test_create() { $realCheck = new Services_Trackback_SpamCheck_Akismet($this->_options); $this->assertTrue($this->spamCheck == $realCheck); } // }}} // {{{ Test check() function test_check_failure_nospam() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['nospam'])); } function test_check_failure_undetected() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['undetected'])); } function test_check_success_all() { $this->assertTrue($this->spamCheck->check($this->trackbacks['all'])); } function test_check_success_host() { $this->assertTrue($this->spamCheck->check($this->trackbacks['host'])); } function test_check_failure_title() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['title'])); } function test_check_faulire_excerpt() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['excerpt'])); } function test_check_failure_url() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['url'])); } function test_check_failure_blog_name() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['blog_name'])); } // }}} // {{{ Test getResults() function test_getResults() { $results = $this->spamCheck->getResults(); $this->assertTrue($results[0]); } // }}} // {{{ Test reset() function test_reset() { $this->spamCheck->check($this->trackbacks['all']); $this->spamCheck->reset(); $fakeCheck = Services_Trackback_SpamCheck::create('Akismet'); $fakeCheck->_dnsbl->blacklists = array('bl.spamcop.net'); $this->assertTrue($this->spamCheck == $fakeCheck); } // }}} // {{{ Test verifyKey() function test_verifyKey_success() { $this->assertTrue($this->spamCheck->verifyKey()); } function test_verifyKey_failure() { $this->spamCheck->_options['key'] = 'foobar'; $this->assertFalse($this->spamCheck->verifyKey()); } // }}} } if (isset($akismetApiKey) && $akismetApiKey !== false) { $suite = new PHPUnit_TestSuite("Webservices_Trackback_SpamCheck_Akismet_TestCase"); $result = PHPUnit::run($suite); echo $result->toString(); } else { echo 'Skipped test case "Webservices_Trackback_SpamCheck_Akismet_TestCase" because Akismet API key is missing. Please configure it in test/akismet_key.php!'; } ?> http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/test/akismet_key.php?view=markup&rev=1.1 Index: pear/Services_Trackback/test/akismet_key.php +++ pear/Services_Trackback/test/akismet_key.php <?php $akismetApiKey = false; ?>
http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/test/Services_Trackback_TestAll.php?r1=1.3&r2=1.4&diff_format=u Index: pear/Services_Trackback/test/Services_Trackback_TestAll.php diff -u pear/Services_Trackback/test/Services_Trackback_TestAll.php:1.3 pear/Services_Trackback/test/Services_Trackback_TestAll.php:1.4 --- pear/Services_Trackback/test/Services_Trackback_TestAll.php:1.3 Thu Feb 9 19:09:37 2006 +++ pear/Services_Trackback/test/Services_Trackback_TestAll.php Fri Feb 17 15:08:51 2006 @@ -18,5 +18,7 @@ require_once 'Services_Trackback_SpamCheck_SURBL_Test.php'; echo "\n\nRunning test suite for Services_Trackback_SpamCheck_Wordlist\n\n"; require_once 'Services_Trackback_SpamCheck_Wordlist_Test.php'; +echo "\n\nRunning test suite for Services_Trackback_SpamCheck_Wordlist\n\n"; +require_once 'Services_Trackback_SpamCheck_Akismet_Test.php'; ?> http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/Services/Trackback/SpamCheck/Akismet.php?view=markup&rev=1.1 Index: pear/Services_Trackback/Services/Trackback/SpamCheck/Akismet.php +++ pear/Services_Trackback/Services/Trackback/SpamCheck/Akismet.php <?php /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /** * Services_Trackback_SpamCheck_Akismet. * * This spam detection module for Services_Trackback checks the given trackback * against the spam checking webservice Akismet {@link http://akismet.com/} * provided by {@link http://wordpress.com}. ATTENTION: To use this spam check, * you need a valid WordPress.com API key. * * PHP versions 4 and 5 * * LICENSE: This source file is subject to version 3.0 of the PHP license * that is available through the world-wide-web at the following URI: * http://www.php.net/license/3_0.txt. If you did not receive a copy of * the PHP License and are unable to obtain it through the web, please * send a note to license@php.net so we can mail you a copy immediately. * * @category Webservices * @package Trackback * @author Tobias Schlitt <toby@php.net> * @copyright 2005-2006 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: Akismet.php,v 1.1 2006/02/17 15:08:51 toby Exp $ * @link http://pear.php.net/package/Services_Trackback * @since File available since Release 0.6.0 */ // {{{ require_once /** * Load PEAR error handling */ require_once 'PEAR.php'; /** * Load SpamCheck base class */ require_once 'Services/Trackback/SpamCheck.php'; /** * HTTP_Request for sending POST requests to Akismet */ require_once 'HTTP/Request.php'; // }}} /** * Akismet * Module for spam detecion using {@link http://akismet.com}. * * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @category Webservices * @package Trackback * @author Tobias Schlitt <toby@php.net> * @copyright 2005-2006 The PHP Group * @version Release: @package_version@ * @link http://pear.php.net/package/Services_Trackback * @since 0.6.0 * @access public */ class Services_Trackback_SpamCheck_Akismet extends Services_Trackback_SpamCheck { // {{{ _options /** * Options for the Wordlist. * * @var array * @since 0.5.0 * @access protected */ var $_options = array( 'continuous' => false, 'sources' => array( 'rest.akismet.com/1.1/', ), // URL of the blog sending the Akismet request 'url' => '', // WordPress.com API key to use 'key' => '', 'elements' => array( 'title', 'excerpt', 'blog_name', 'url', 'host', ), ); // }}} // {{{ Services_Trackback_SpamCheck_Akismet() /** * Constructor. * Create a new instance of the Akismet spam protection module. * * @since 0.5.0 * @access public * @param array $options An array of options for this spam protection module. General options are * 'continuous': Whether to continue checking more sources, if a match has been found. * 'sources': List of Akismet servers URIs. * @return object(Services_Trackback_SpamCheck_Akismet) The newly created SpamCheck object. */ function Services_Trackback_SpamCheck_Akismet($options = null) { if (is_array($options)) { foreach ($options as $key => $val) { $this->_options[$key] = $val; } } } // }}} // {{{ check() function check($trackback) { if (empty($this->_options['url'])) { return PEAR::raiseError('Missing option "url". Cannot procede without it.', 0); } if (empty($this->_options['key'])) { return PEAR::raiseError('Missing option "key". Cannot procede without it.', 0); } if (!is_array($this->_options['sources']) || count($this->_options['sources']) < 1) { return PEAR::raiseError('Missing option "sources". Cannot procede without it.', 0); } if (!is_array(($extra = $trackback->get('extra'))) || count($extra) < 1){ return PEAR::raiseError('Missing data "extra". Cannot procede without it.', 0); } $foundSpam = false; foreach ($this->_options['sources'] as $id => $source) { if ($foundSpam && !$this->_options['continuous']) { // We already found spam and shall not continue $this->_results[$id] = false; } else { if (PEAR::isError($res = $this->_checkSource($this->_options['sources'][$id], $trackback))) { return $res; } $this->_results[$id] = $res; $foundSpam = $foundSpam || $res; } } return $foundSpam; } // }}} // {{{ verifyKey() function verifyKey() { $tmpTrack = Services_Trackback::create(array('id' => 1)); if (PEAR::isError($res = $this->_sendAkismetRequest($this->_options['sources'][0], $tmpTrack))) { var_dump($res); return $res; } return $res == 'valid'; } // }}} // {{{ _checkSource() function _checkSource(&$source, $trackback) { if (PEAR::isError($res = $this->_sendAkismetRequest($source, $trackback, 'comment-check'))) { return $res; } if ($res == 'invalid') { return PEAR::raiseError('Invalid Akismet request send. Maybe your key is invalid?'); } return ($res == 'true'); } // }}} // {{{ _sendAkismetRequest() function _sendAkismetRequest($baseUri, $trackback, $action = 'verify-key') { $action = strtolower($action); $req = null; $options = $trackback->getOptions(); $httpRequestOptions = $options['httprequest']; switch ($action) { case 'verify-key': $url = 'http://' . $baseUri . $action; echo $url; $req = new HTTP_Request($url, $httpRequestOptions); $req->setMethod(HTTP_REQUEST_METHOD_POST); $req->addPostData('key', $this->_options['key']); $req->addPostData('blog', $this->_options['url']); break; case 'comment-check': case 'submit-spam': case 'submit-ham': $url = 'http://' . $this->_options['key'] . '.' . $baseUri . $action; $req = new HTTP_Request($url, $httpRequestOptions); $req->setMethod(HTTP_REQUEST_METHOD_POST); $req->addHeader('User-Agent', $httpRequestOptions['useragent']); $req->addPostData('comment_type', 'trackback'); $req->addPostData('key', $this->_options['key']); $req->addPostData('blog', $this->_options['url']); $req->addPostData('comment_author_url', $trackback->get('url')); $req->addPostData('user_ip', $trackback->get('host')); $extra = $trackback->get('extra'); $req->addPostData('user_agent', $extra['USER_AGENT']); $req->addPostData('referrer', $extra['REFERER']); break; default: return PEAR::raiseError('Invalid Akismet action: "'.$action.'".'); break; } if (($res = $req->sendRequest()) !== true) { return $res; } if ($req->getResponseCode() !== 200) { return PEAR::raiseError('Could not open URL "'.$url.'". Code: "'.$req->getResponseCode().'".'); } return trim($req->getResponseBody()); } // }}} } http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/test/Services_Trackback_SpamCheck_Akismet_Test.php?view=markup&rev=1.1 Index: pear/Services_Trackback/test/Services_Trackback_SpamCheck_Akismet_Test.php +++ pear/Services_Trackback/test/Services_Trackback_SpamCheck_Akismet_Test.php <?php // {{{ require_once // Services_Trackback classes require_once 'Services/Trackback.php'; require_once 'Services/Trackback/SpamCheck.php'; require_once 'Services/Trackback/SpamCheck/Akismet.php'; // Unittest suite require_once 'PHPUnit.php'; // Testdata require_once dirname(__FILE__).'/trackback_data.php'; // Akismet.com API key require_once 'test/akismet_key.php'; // }}} class Webservices_Trackback_SpamCheck_Akismet_TestCase extends PHPUnit_TestCase { var $trackbacks = array(); var $spamCheck; var $options = array(); // {{{ Webservices_Trackback_SpamCheck_Akismet_TestCase() // constructor of the test suite function Webservices_Trackback_SpamCheck_Akismet_TestCase($name) { $this->PHPUnit_TestCase($name); } // }}} // {{{ setup() function setUp() { global $trackbackData; global $akismetApiKey; if (!isset($akismetApiKey) || $akismetApiKey === false) { return false; } foreach ($trackbackData as $id => $set) { $this->trackbacks[$id] = Services_Trackback::create($set); $this->trackbacks[$id]->set( 'extra', array( 'REFERER' => 'http://www.example.com', 'USER_AGENT' => 'Test', ) ); } $this->_options = array( 'url' => 'http://www.schlitt.info/applications/blog/', 'key' => $akismetApiKey, ); $this->spamCheck = Services_Trackback_SpamCheck::create('Akismet', $this->_options); } // }}} // {{{ tearDown() function tearDown() { } // }}} // {{{ Test create() function test_create() { $realCheck = new Services_Trackback_SpamCheck_Akismet($this->_options); $this->assertTrue($this->spamCheck == $realCheck); } // }}} // {{{ Test check() function test_check_failure_nospam() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['nospam'])); } function test_check_failure_undetected() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['undetected'])); } function test_check_success_all() { $this->assertTrue($this->spamCheck->check($this->trackbacks['all'])); } function test_check_success_host() { $this->assertTrue($this->spamCheck->check($this->trackbacks['host'])); } function test_check_failure_title() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['title'])); } function test_check_faulire_excerpt() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['excerpt'])); } function test_check_failure_url() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['url'])); } function test_check_failure_blog_name() { $this->assertTrue(!$this->spamCheck->check($this->trackbacks['blog_name'])); } // }}} // {{{ Test getResults() function test_getResults() { $results = $this->spamCheck->getResults(); $this->assertTrue($results[0]); } // }}} // {{{ Test reset() function test_reset() { $this->spamCheck->check($this->trackbacks['all']); $this->spamCheck->reset(); $fakeCheck = Services_Trackback_SpamCheck::create('Akismet'); $fakeCheck->_dnsbl->blacklists = array('bl.spamcop.net'); $this->assertTrue($this->spamCheck == $fakeCheck); } // }}} // {{{ Test verifyKey() function test_verifyKey_success() { $this->assertTrue($this->spamCheck->verifyKey()); } function test_verifyKey_failure() { $this->spamCheck->_options['key'] = 'foobar'; $this->assertFalse($this->spamCheck->verifyKey()); } // }}} } if (isset($akismetApiKey) && $akismetApiKey !== false) { $suite = new PHPUnit_TestSuite("Webservices_Trackback_SpamCheck_Akismet_TestCase"); $result = PHPUnit::run($suite); echo $result->toString(); } else { echo 'Skipped test case "Webservices_Trackback_SpamCheck_Akismet_TestCase" because Akismet API key is missing. Please configure it in test/akismet_key.php!'; } ?> http://cvs.php.net/viewcvs.cgi/pear/Services_Trackback/test/akismet_key.php?view=markup&rev=1.1 Index: pear/Services_Trackback/test/akismet_key.php +++ pear/Services_Trackback/test/akismet_key.php <?php $akismetApiKey = false; ?>