Hi Garvin,
Must be my lucky day seeing you respond to my question right away. Many thanks! The two servers run indeed two different PHP versions. My development machine runs 5.2.4 and the production server runs 4.3.10. I suspected exactly the same thing, a parse error with 4.x, however, the unit test runs okay on the production server. So, I guess it can't be. I've tested it with Serendipity V-1.3 and V-1.3.1. Here are the sources:
serendipty_plugin_popular.php
Code: Select all
<?php # $Id: serendipity_plugin_popular.php,v 1.0 2008/09/27 11:31:55 time4you Exp $
if (IN_serendipity !== true) {
die ("Don't hack!");
}
// Probe for a language include with constants. Still include defines later on, if some constants were missing
$probelang = dirname(__FILE__) . '/' . $serendipity['charset'] . 'lang_' . $serendipity['lang'] . '.inc.php';
if (file_exists($probelang)) {
include $probelang;
}
include dirname(__FILE__) . '/lang_en.inc.php';
@define('PLUGIN_POPULAR_DEFAULT_NUMBER_OF_ENTRIES', 5);
class serendipity_plugin_popular extends serendipity_plugin {
var $title = PLUGIN_POPULAR_TITLE;
function introspect(&$propbag) {
$this->title = $this->get_config('title', $this->title);
$propbag->add('name', PLUGIN_POPULAR_TITLE);
$propbag->add('description', PLUGIN_POPULAR_BLAHBLAH);
$propbag->add('stackable', true);
$propbag->add('author', 'time4you GmbH');
$propbag->add('requirements', array(
'serendipity' => '0.9',
'smarty' => '2.6.7',
'php' => '4.1.0'
));
$propbag->add('version', '1.0');
$propbag->add('configuration', array('title',
'mostrecent', 'mostrecent_number',
'mostread', 'mostread_number',
'lastread', 'lastread_number',
'mostcommented', 'mostcommented_number',
'lastcommented', 'lastcommented_number',
));
$propbag->add('groups', array('STATISTICS'));
}
function introspect_config_item($name, &$propbag) {
global $serendipity;
switch($name) {
case 'title':
$propbag->add('type', 'string');
$propbag->add('name', TITLE);
$propbag->add('description', TITLE_FOR_NUGGET);
$propbag->add('default', PLUGIN_POPULAR_TITLE);
break;
case 'mostrecent':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_POPULAR_MOSTRECENT);
$propbag->add('description', PLUGIN_POPULAR_MOSTRECENT_BLAHBLAH);
$propbag->add('default', true);
break;
case 'mostread':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_POPULAR_MOSTREAD);
$propbag->add('description', PLUGIN_POPULAR_MOSTREAD_BLAHBLAH);
$propbag->add('default', true);
break;
case 'lastread':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_POPULAR_LASTREAD);
$propbag->add('description', PLUGIN_POPULAR_LASTREAD_BLAHBLAH);
$propbag->add('default', false);
break;
case 'mostcommented':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_POPULAR_MOSTCOMMENTED);
$propbag->add('description', PLUGIN_POPULAR_MOSTCOMMENTED_BLAHBLAH);
$propbag->add('default', true);
break;
case 'lastcommented':
$propbag->add('type', 'boolean');
$propbag->add('name', PLUGIN_POPULAR_LASTCOMMENTED);
$propbag->add('description', PLUGIN_POPULAR_LASTCOMMENTED_BLAHBLAH);
$propbag->add('default', false);
break;
case 'mostrecent_number':
case 'mostread_number':
case 'lastread_number':
case 'mostcommented_number':
case 'lastcommented_number':
$propbag->add('type', 'string');
$propbag->add('name', PLUGIN_POPULAR_NUMBER);
$propbag->add('description', PLUGIN_POPULAR_NUMBER_BLAHBLAH);
$propbag->add('validate', 'number');
$propbag->add('validate_error', PLUGIN_POPULAR_NUMBER_ERRORTEXT);
$propbag->add('default', PLUGIN_POPULAR_DEFAULT_NUMBER_OF_ENTRIES);
break;
default:
return false;
}
return true;
}
function generate_content(&$title) {
global $serendipity;
$title = $this->get_config('title', $this->title);
if ($this->get_config('mostrecent')) {
$number = $this->get_number_of_links('mostrecent_number');
$query =
"SELECT e.*
FROM {$serendipity['dbPrefix']}entries AS e
WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "
ORDER BY e.timestamp DESC
LIMIT $number";
$articles = serendipity_db_query($query);
$this->output_links($articles, PLUGIN_POPULAR_MOSTRECENT);
}
if ($this->get_config('mostread')) {
$number = $this->get_number_of_links('mostread_number');
$query =
"SELECT DISTINCT e.*
FROM {$serendipity['dbPrefix']}entries AS e
LEFT OUTER JOIN {$serendipity['dbPrefix']}plugin_popular AS p
ON p.entry_id = e.id
WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "
ORDER BY p.count DESC
LIMIT $number";
$articles = serendipity_db_query($query);
$this->output_links($articles, PLUGIN_POPULAR_MOSTREAD);
}
if ($this->get_config('lastread')) {
$number = $this->get_number_of_links('lastread_number');
$query =
"SELECT DISTINCT e.*
FROM {$serendipity['dbPrefix']}entries AS e
LEFT OUTER JOIN {$serendipity['dbPrefix']}plugin_popular AS p
ON p.entry_id = e.id
WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "
ORDER BY p.timestamp DESC
LIMIT $number";
$articles = serendipity_db_query($query);
$this->output_links($articles, PLUGIN_POPULAR_LASTREAD);
}
if ($this->get_config('mostcommented')) {
$number = $this->get_number_of_links('mostcommented_number');
$query =
"SELECT e.*
FROM {$serendipity['dbPrefix']}entries AS e
WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "
AND e.comments > 0
ORDER BY e.comments DESC
LIMIT $number";
$articles = serendipity_db_query($query);
$this->output_links($articles, PLUGIN_POPULAR_MOSTCOMMENTED);
}
if ($this->get_config('lastcommented')) {
$number = $this->get_number_of_links('lastcommented_number');
$query =
"SELECT DISTINCT e.*
FROM {$serendipity['dbPrefix']}entries AS e
LEFT OUTER JOIN {$serendipity['dbPrefix']}comments AS c
ON c.entry_id = e.id
WHERE e.isdraft = 'false' AND e.timestamp <= " . time() . "
AND e.comments > 0
ORDER BY c.timestamp DESC
LIMIT $number";
$articles = serendipity_db_query($query);
$this->output_links($articles, PLUGIN_POPULAR_LASTCOMMENTED);
}
}
function output_links(&$articles, $title) {
if (isset($articles) && is_array($articles) && (count($articles) > 0) ) {
echo htmlentities($title), "\n";
echo '<div style="margin-left:10px;margin-bottom:5px">', "\n";
foreach ($articles as $k => $article) {
$articleLink = serendipity_archiveURL(
$article['id'],
$article['title'],
'serendipityHTTPPath',
true,
array('timestamp' => $article['timestamp'])
);
echo '<a href="', $articleLink,
'" title="', htmlspecialchars($article['title']), '">',
$article['title'], '</a><br />', "\n";
}
echo '</div>', "\n";
}
}
function get_number_of_links($identifier) {
$number = (int) $this->get_config($identifier, PLUGIN_POPULAR_DEFAULT_NUMBER_OF_ENTRIES);
return ($number > 0)? $number : PLUGIN_POPULAR_DEFAULT_NUMBER_OF_ENTRIES;
}
}
serendipity_event_popular.php:
Code: Select all
<?php # $Id: serendipity_event_popular.php,v 1.0 2008/09/27 11:31:55 time4you Exp $
if (IN_serendipity !== true) {
die ("Don't hack!");
}
// Probe for a language include with constants. Still include defines later on, if some constants were missing
$probelang = dirname(__FILE__) . '/' . $serendipity['charset'] . 'lang_' . $serendipity['lang'] . '.inc.php';
if (file_exists($probelang)) {
include $probelang;
}
include dirname(__FILE__) . '/lang_en.inc.php';
class serendipity_event_popular extends serendipity_event {
var $title = PLUGIN_POPULAR_TITLE;
function install() {
global $serendipity;
$sql = "CREATE TABLE {$serendipity['dbPrefix']}plugin_popular (
entry_id int(10) unsigned default NULL,
count int(10) unsigned default '0',
timestamp int(10) unsigned default NULL,
UNIQUE KEY entry_id (entry_id),
KEY count (count),
KEY timestamp (timestamp)
);";
serendipity_db_schema_import($sql);
}
function introspect(&$propbag) {
$this->title = $this->get_config('title', $this->title);
$propbag->add('name', PLUGIN_POPULAR_TITLE);
$propbag->add('description', PLUGIN_POPULAR_REQUIREDBY);
$propbag->add('stackable', false);
$propbag->add('author', 'time4you GmbH');
$propbag->add('requirements', array(
'serendipity' => '0.9',
'smarty' => '2.6.7',
'php' => '4.1.0'
));
$propbag->add('version', '1.0');
$propbag->add('groups', array('STATISTICS'));
$propbag->add('event_hooks', array(
'frontend_display:html:per_entry' => true,
'frontend_display:rss-1.0:per_entry' => true,
'frontend_display:rss-2.0:per_entry' => true,
'xmlrpc_fetchEntry' => true,
'entry_display' => true
));
}
function generate_content(&$title) {
$title = $this->title;
}
function event_hook($event, &$bag, &$eventData) {
global $serendipity;
$hooks = &$bag->get('event_hooks');
if (!isset($hooks[$event]))
return false;
switch($event) {
case 'entry_display':
if (isset($serendipity['GET']['id'])) {
$entryid = (int)serendipity_db_escape_string($serendipity['GET']['id']);
} elseif (preg_match(PAT_COMMENTSUB, $_SERVER['REQUEST_URI'], $matches)) {
$entryid = (int)$matches[1];
} else {
$entryid = false;
}
if ($entryid)
$this->increment_counter($entryid);
return true;
case 'frontend_display:html:per_entry':
case 'frontend_display:rss-1.0:per_entry':
case 'frontend_display:rss-2.0:per_entry':
case 'xmlrpc_fetchEntry':
if (isset($eventData['id'])) {
$entryid = (int) $eventData['id'];
$this->increment_counter($entryid, false);
}
return true;
default:
return false;
}
return false;
}
function increment_counter($entryid, $settime=true, $count=1) {
global $serendipity;
$sql = "UPDATE {$serendipity['dbPrefix']}plugin_popular
SET count = count + " . $count;
if ($settime)
$sql .= ', timestamp = ' . time();
$sql .= " WHERE entry_id = $entryid";
serendipity_db_query($sql, true);
if (serendipity_db_affected_rows() < 1) {
$sql = "INSERT INTO {$serendipity['dbPrefix']}plugin_popular
(entry_id, count, timestamp)
VALUES ('$entryid', '1', '" . time() . "')";
serendipity_db_query($sql);
}
}
}
lang_en.inc.php:
Code: Select all
<?php # $Id: lang_en.inc.php,v 1.0 2008/09/27 11:31:55 time4you Exp $
/**
* @version $Revision: 1.0 $
* @author Thomas Knierim, time4you GmbH, www.time4you.de
* EN-Revision: Revision of lang_en.inc.php
*/
@define('PLUGIN_POPULAR_TITLE', 'Popular Articles');
@define('PLUGIN_POPULAR_BLAHBLAH', 'Shows links to recent and/or popular articles in the sidebar. To display the most read or the last read articles, the associated event plugin "Popular Articles" must be installed.');
@define('PLUGIN_POPULAR_REQUIREDBY', 'This plugin is required by the "Popular Articles" sidebar plugin.');
@define('PLUGIN_POPULAR_NUMBER', 'Number Of Articles');
@define('PLUGIN_POPULAR_NUMBER_BLAHBLAH', 'How many items should be displayed?');
@define('PLUGIN_POPULAR_NUMBER_ERRORTEXT', 'Number of items must be an integer number.');
@define('PLUGIN_POPULAR_MOSTRECENT', 'Most Recent');
@define('PLUGIN_POPULAR_MOSTRECENT_BLAHBLAH', 'Display the most recent articles?');
@define('PLUGIN_POPULAR_MOSTREAD', 'Most Read');
@define('PLUGIN_POPULAR_MOSTREAD_BLAHBLAH', 'Display the most read articles?');
@define('PLUGIN_POPULAR_LASTREAD', 'Last Read');
@define('PLUGIN_POPULAR_LASTREAD_BLAHBLAH', 'Display the last read articles?');
@define('PLUGIN_POPULAR_MOSTCOMMENTED', 'Most Commented');
@define('PLUGIN_POPULAR_MOSTCOMMENTED_BLAHBLAH', 'Display the most commented articles?');
@define('PLUGIN_POPULAR_LASTCOMMENTED', 'Last Commented');
@define('PLUGIN_POPULAR_LASTCOMMENTED_BLAHBLAH', 'Display the last commented articles?');
?>
Unit Test Code (test_plugin_popular.php):
Code: Select all
<?php
header('Content-type: text/plain');
define('IN_serendipity', true);
$serendipity = array();
class serendipity_plugin {
function get_config($param1, $param2=0) {}
function install() {}
function introspect(&$propertybag) {}
function introspect_config_item($param1, $param2) {}
function generate_content(&$title) {}
}
class PropertyBag {
var $contents = array();
function add($param1, $param2) {
$this->contents[$param1] = $param2;
}
function getContents() {
return $this->contents;
}
}
class serendipity_event extends serendipity_plugin{}
echo "Start Test\n";
include 'serendipity_plugin_popular.php';
echo "serendipity_plugin_popular.php loaded!\n";
$plugin = new serendipity_plugin_popular();
echo "serendipity_plugin_popular object created!\n";
$propertybag = new PropertyBag();
$plugin->introspect(&$propertybag);
echo "Called introspect()!\n";
$plugin->introspect_config_item('title', &$propertybag);
echo "Called introspect_config_item()!\n";
echo "Result:\n";
var_dump($propertybag);
echo "Calling generate_content():\n";
$title = 'Title';
$plugin->generate_content(&$title);
echo "generate_content() finished!\n";
include 'serendipity_event_popular.php';
echo "serendipity_event_popular.php loaded!\n";
$plugin = new serendipity_event_popular();
echo "serendipity_event_popular object created!\n";
$propertybag = new PropertyBag();
$plugin->introspect(&$propertybag);
echo "Called introspect()!\n";
$plugin->introspect_config_item('title', &$propertybag);
echo "Called introspect_config_item()!\n";
echo "Result:\n";
var_dump($propertybag);
echo "Calling generate_content():\n";
$title = 'Title';
$plugin->generate_content(&$title);
echo "generate_content() finished!\n";
echo "End Test\n";
?>
Cheers, Serendipity-Fan