parser = xml_parser_create();
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, "_open", "_close");
xml_set_character_data_handler($this->parser, "_cdata");
$this->isError = false;
$this->inTarget = false;
}
function parse($data){
$this->words = array();
xml_parse($this->parser, $data);
$errcode = xml_get_error_code($this->parser);
if ( $errcode != XML_ERROR_NONE ) {
$this->isError = true;
$this->message = 'XML Parse Error: ' . xml_error_string($errcode) . ' in '. xml_get_current_line_number($this->parser);
}
return $this->message;
}
function free(){
xml_parser_free($this->parser);
}
function _open($parser, $name, $attribute){
switch( $name ){
case 'MESSAGE':
$this->inTarget = 'MESSAGE';
break;
case 'ERROR':
$this->inTarget = 'ERROR';
break;
}
}
function _close($parser, $name){
if( $name == $this->inTarget ) $this->inTarget = null;
}
function _cdata($parser, $data){
switch( $this->inTarget ){
case 'MESSAGE':
$this->message = trim($data);
break;
case 'ERROR':
$this->isError = ($data ? true : false);
break;
}
}
}
class NP_TrackBack extends NucleusPlugin {
var $useCurl = 1; // use curl? 2:precheck+read by curl, 1: read by curl 0: fread
//modify start+++++++++
function _createItemLink($itemid, $b){
global $CONF, $manager;
$itemLink = createItemLink($itemid,'');
if( strpos($itemLink, 'http') === 0 ){
return $itemLink;
}
$blogurl = $b->getURL();
if (!$blogurl) {
$b =& $manager->getBlog($CONF['DefaultBlog']);
$blogurl = $b->getURL();
if (!$blogurl) {
$blogurl = $CONF['IndexURL'];
}
}
if(substr($blogurl, -1) == '/') $blogurl = substr($blogurl,0,-1);
$usePathInfo = ($CONF['URLMode'] == 'pathinfo');
$itemUrlOrg = $CONF['ItemURL'];
$CONF['ItemURL'] = $blogurl . ($usePathInfo ? '' : '/index.php');
$itemLink = createItemLink($itemid,'');
$CONF['ItemURL'] = $itemUrlOrg;
return $itemLink;
}
//modify end+++++++++
/**************************************************************************************
* SKIN VARS, TEMPLATE VARS AND ACTIONS
*/
/*
* TrackBack data can be inserted using skinvars (or templatevars)
*/
function doSkinVar($skinType, $what = '', $tb_id = '', $amount = 'limit-1') {
global $itemid, $manager, $CONF;
//modify start+++++++++
if(eregi('limit', $tb_id)){
$amount = $tb_id;
$tb_id = '';
}
$amount = eregi_replace("limit", "", $amount);
$amount = intval($amount);
//modify end+++++++++
if ($tb_id == '') $tb_id = intval($itemid);
//mod by cles
$isAcceptPing = $this->isAcceptTrackBack($tb_id);
//if( $skinType == 'template' && (! $isAcceptPing ) ){
// return;
//}
//mod by cles end
switch ($what) {
// Insert Auto-discovery RDF code
case 'tbcode':
case 'code':
//mod by cles
// if($skinType == 'item')
$spamcheck = array (
'type' => 'tbcode',
'id' => -1,
'title' => '',
'excerpt' => '',
'blogname' => '',
'url' => '',
'return' => true,
'live' => true,
/* Backwards compatibility with SpamCheck API 1*/
'data' => '',
'ipblock' => true,
);
global $manager;
//$manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
$spam = false;
if (isset($spamcheck['result']) && $spamcheck['result'] == true){
$spam = true;
}
if( ($skinType == 'item') && (!$spam) && $isAcceptPing )
//mod by cles end
$this->insertCode($tb_id);
break;
// Insert TrackBack URL
case 'tburl':
case 'url':
//mod by cles
// echo $this->getTrackBackUrl($tb_id);
if($isAcceptPing)
echo $this->getTrackBackUrl($tb_id);
else
echo 'Sorry, no trackback pings are accepted.';
//mod by cles end
break;
// Insert manual ping URL
case 'form':
case 'manualpingformlink':
echo $this->getManualPingUrl($tb_id);
break;
case 'sendpinglink':
echo $manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id));
break;
// Insert TrackBack count
case 'count':
$count = $this->getTrackBackCount($tb_id);
switch ($count) {
case 0: echo TEMPLATE::fill($this->getOption('tplTbNone'), array('number' => $count)); break;
case 1: echo TEMPLATE::fill($this->getOption('tplTbOne'), array('number' => $count)); break;
default: echo TEMPLATE::fill($this->getOption('tplTbMore'), array('number' => $count)); break;
}
break;
// Shows the TrackBack list
case 'list':
case '':
//modify start+++++++++
// $this->showList($tb_id);
$this->showList($tb_id, $amount);
//modify end+++++++++
break;
//mod by cles
// show requred URL
case 'required':
echo $this->getRequiredURL($tb_id);
break;
// shows the Local list
case 'locallist':
$this->showLocalList($tb_id);
break;
//mod by cles end
default:
return;
}
}
/*
* When used in templates, the tb_id will be determined by the itemid there
*/
function doTemplateVar(&$item, $what = '') {
$this->doSkinVar('template', $what, $item->itemid);
}
function doTemplateCommentsVar(&$item, &$comment, $what = ''){
$this->doSkinVar('templatecomments', $what, $item->itemid);
}
/*
* A trackback ping is to be received on the URL
* http://yourdomain.com/item/1234.trackback
* Extra variables to be passed along are url, title, excerpt, blog_name
*/
function event_InitSkinParse(&$data) {
global $CONF, $itemid;
$format = requestVar('format');
if ($CONF['URLMode'] == 'pathinfo') {
if (preg_match('/(\/|\.)(trackback)(\/|$)/', serverVar('PATH_INFO'), $matches)) {
$format = $matches[2];
}
}
if ($format == 'trackback' && $data['type'] == 'item')
{
$errorMsg = $this->handlePing(intval($itemid));
if ($errorMsg != '')
$this->xmlResponse($errorMsg);
else
$this->xmlResponse();
exit;
}
}
/*
* A trackback ping is to be received on the URL
* http://yourdomain.com/action.php?action=plugin&name=TrackBack&tb_id=1234
* Extra variables to be passed along are url, title, excerpt, blog_name
*/
function doAction($type)
{
global $CONF,$manager;
$aActionsNotToCheck = array(
'',
'ping',
'form',
'redirect',
'left',
);
if (!in_array($type, $aActionsNotToCheck)) {
if (!$manager->checkTicket()) return _ERROR_BADTICKET;
}
switch ($type) {
// When no action type is given, assume it's a ping
case '':
$errorMsg = $this->handlePing();
if ($errorMsg != '')
$this->xmlResponse($errorMsg);
else
$this->xmlResponse();
break;
// Manual ping
case 'ping':
$errorMsg = $this->handlePing();
if ($errorMsg != '')
$this->showManualPingError(intRequestVar('tb_id'), $errorMsg);
else
$this->showManualPingSuccess(intRequestVar('tb_id'));
break;
// Show manual ping form
case 'form':
//mod by cles
// $this->showManualPingForm(intRequestVar('tb_id'));
$tb_id = intRequestVar('tb_id');
$isAcceptPing = $this->isAcceptTrackBack($tb_id);
if( $isAcceptPing )
$this->showManualPingForm($tb_id);
else
echo 'Sorry, no trackback pings are accepted.';
//mod by cles end
break;
// Detect trackback
case 'detect':
list($url, $title) =
$this->getURIfromLink(html_entity_decode(requestVar('tb_link')));
$url = addslashes($url);
$url = $this->_utf8_to_javascript($url);
$title = addslashes($title);
$title = $this->_utf8_to_javascript($title);
echo "tbDone('" . requestVar('tb_link') . "', '" . $url . "', '" . $title . "');";
break;
//mod by cles
// redirect
case 'redirect':
return $this->redirect(intRequestVar('tb_id'), requestVar('urlHash'));
break;
//mod by cles end
case 'left':
echo $this->showLeftList(intRequestVar('tb_id'), intRequestVar('amount'));
break;
// delete a trackback(local)
case 'deletelc':
$err = $this->deleteLocal(intRequestVar('tb_id'), intRequestVar('from_id'));
if( $err )
return $err;
header('Location: ' . serverVar('HTTP_REFERER'));
break;
}
exit;
}
function doIf($key = '', $value = '')
{
global $itemid;
//echo "key: $key, value: $value";
switch( strtolower($key) ){
case '':
case 'accept':
if( $value == '' ) $value = 'yes';
$value = ( $value == 'no' || (! $value) ) ? false : true;
$ret = false;
if( $itemid )
$ret = $this->isAcceptTrackBack($itemid);
else
$ret = $this->isAcceptTrackBack();
return ( $value == false ) ? (! $ret) : $ret;
case 'required':
if( $value == '' ) $value = 'yes';
$value = ( $value == 'no' || (! $value) ) ? false : true;
$ret = false;
if( $itemid )
$ret = $this->isEnableLinkCheck($itemid);
return ( $value == false ) ? (! $ret) : $ret;
default:
return false;
}
}
/**************************************************************************************
* OUTPUT
*/
/*
* Show a list of left trackbacks for this ID
*/
function showLeftList($tb_id, $offset = 0, $amount = 99999999) {
global $manager, $blog, $CONF;
$out = array();
$query = '
SELECT
url,
md5(url) as urlHash,
blog_name,
excerpt,
title,
UNIX_TIMESTAMP(timestamp) AS timestamp
FROM
'.sql_table('plugin_tb').'
WHERE
tb_id = '.intval($tb_id).' AND
block = 0
ORDER BY
timestamp DESC
';
if($offset)
$query .= ' LIMIT '.intval($offset).', ' .intval($amount);
$res = sql_query($query);
while ($row = mysql_fetch_array($res))
{
$row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES);
$row['title'] = htmlspecialchars($row['title'], ENT_QUOTES);
$row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES);
if (_CHARSET != 'UTF-8') {
//modify start+++++++++
$row['blog_name'] = $this->_restore_to_utf8($row['blog_name']);
$row['title'] = $this->_restore_to_utf8($row['title']);
$row['excerpt'] = $this->_restore_to_utf8($row['excerpt']);
//modify end+++++++++
$row['blog_name'] = $this->_utf8_to_entities($row['blog_name']);
$row['title'] = $this->_utf8_to_entities($row['title']);
$row['excerpt'] = $this->_utf8_to_entities($row['excerpt']);
}
$iVars = array(
'action' => $this->getTrackBackUrl($tb_id),
'form' => $this->getManualPingUrl($tb_id),
'name' => $row['blog_name'],
'title' => $row['title'],
'excerpt' => $this->_cut_string($row['excerpt'], 400),
'url' => htmlspecialchars($row['url'], ENT_QUOTES),
'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES)
);
//mod by cles
if( $this->getOption('HideUrl') == 'yes' )
$iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . $tb_id . '&urlHash=' . $row['urlHash'];
else
$iVars['url'] = $row['url'];
//mod by cles end
$out[] = TEMPLATE::fill($this->getOption('tplItem'), $iVars);
}
mysql_free_result($res);
return @join("\n",$out);
}
/*
* Show a list of all trackbacks for this ID
*/
function showList($tb_id, $amount = 0) {
$tb_id = intval($tb_id);
global $manager, $blog, $CONF, $member;
//mod by cles
$enableHideurl = true;
// for TB LinkLookup
if(
strstr(serverVar('HTTP_USER_AGENT'),'Hatena Diary Track Forward Agent')
|| strstr(serverVar('HTTP_USER_AGENT'),'NP_TrackBack')
|| strstr(serverVar('HTTP_USER_AGENT'),'TBPingLinkLookup')
|| strstr(serverVar('HTTP_USER_AGENT'),'MT::Plugin::BanNoReferTb')
|| strstr(serverVar('HTTP_USER_AGENT'),'livedoorBlog')
){
$enableHideurl = false;
$amount = '-1';
}
//mod by cles end
/*
$res = sql_query('
SELECT
url,
md5(url) as urlHash,
blog_name,
excerpt,
title,
UNIX_TIMESTAMP(timestamp) AS timestamp
FROM
'.sql_table('plugin_tb').'
WHERE
tb_id = '.$tb_id .' AND
block = 0
ORDER BY
timestamp ASC
');
*/
$query = '
SELECT
url,
md5(url) as urlHash,
blog_name,
excerpt,
title,
UNIX_TIMESTAMP(timestamp) AS timestamp
FROM
'.sql_table('plugin_tb').'
WHERE
tb_id = '.intval($tb_id) .' AND
block = 0
ORDER BY
timestamp DESC
';
if( $amount == '-1' )
$query .= ' LIMIT 9999999';
elseif( $amount )
$query .= ' LIMIT '.intval($amount);
if( $amount != 0)
$res = sql_query($query);
$gVars = array(
'action' => $this->getTrackBackUrl(intval($tb_id)),
'form' => $this->getManualPingUrl(intval($tb_id)),
'required' => $this->getRequiredURL(intval($tb_id)),
);
if ($member->isLoggedIn() && $member->isAdmin()){
$adminurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=list&id=' . intval($tb_id)), ENT_QUOTES);
$pingformurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id)), ENT_QUOTES);
$gVars['admin'] = '[admin]';
$gVars['pingform'] = '[pingform]';
}
echo TEMPLATE::fill($this->getOption('tplHeader'), $gVars);
while ($amount != 0 && $row = mysql_fetch_array($res))
{
$row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES);
$row['title'] = htmlspecialchars($row['title'], ENT_QUOTES);
$row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES);
/*
*/
if (_CHARSET != 'UTF-8') {
//modify start+++++++++
/*
$row['blog_name'] = $this->_utf8_to_entities($row['blog_name']);
$row['title'] = $this->_utf8_to_entities($row['title']);
$row['excerpt'] = $this->_utf8_to_entities($row['excerpt']);
*/
$row['blog_name'] = $this->_restore_to_utf8($row['blog_name']);
$row['title'] = $this->_restore_to_utf8($row['title']);
$row['excerpt'] = $this->_restore_to_utf8($row['excerpt']);
$row['blog_name'] = mb_convert_encoding($row['blog_name'], _CHARSET, 'UTF-8');
$row['title'] = mb_convert_encoding($row['title'], _CHARSET, 'UTF-8');
$row['excerpt'] = mb_convert_encoding($row['excerpt'], _CHARSET, 'UTF-8');
//modify end+++++++++
}
//modify start+++++++++
/*
$iVars = array(
'action' => $this->getTrackBackUrl($tb_id),
'form' => $this->getManualPingUrl($tb_id),
'name' => $row['blog_name'],
'title' => $row['title'],
'excerpt' => $row['excerpt'],
'url' => htmlspecialchars($row['url'], ENT_QUOTES),
'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp'] + ($blog->getTimeOffset() * 3600)), ENT_QUOTES)
);
*/
$iVars = array(
'action' => $this->getTrackBackUrl($tb_id),
'form' => $this->getManualPingUrl($tb_id),
'name' => htmlspecialchars($row['blog_name'], ENT_QUOTES),
'title' => htmlspecialchars($row['title'], ENT_QUOTES),
'excerpt' => htmlspecialchars($this->_cut_string($row['excerpt'], 400), ENT_QUOTES),
'url' => htmlspecialchars($row['url'], ENT_QUOTES),
'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES)
);
//mod by cles
if( $enableHideurl && $this->getOption('HideUrl') == 'yes' )
$iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . intval($tb_id) . '&urlHash=' . $row['urlHash'];
else
$iVars['url'] = $row['url'];
//mod by cles end
//modify end+++++++++
echo TEMPLATE::fill($this->getOption('tplItem'), $iVars);
}
//modify start+++++++++
$q = '
SELECT
count(*)
FROM
'.sql_table('plugin_tb').'
WHERE
tb_id = '.intval($tb_id) .' AND
block = 0
ORDER BY
timestamp DESC
';
$result = sql_query($q);
$total = mysql_result($result,0,0);
if($amount != -1 && $total > $amount){
$leftcount = $total - $amount;
echo '';
?>
getOption('tplEmpty'), $gVars);
}
mysql_free_result($res);
echo TEMPLATE::fill($this->getOption('tplFooter'), $gVars);
}
/*
* Returns the TrackBack count for a TrackBack item
*/
function getTrackBackCount($tb_id) {
return quickQuery('SELECT COUNT(*) as result FROM ' . sql_table('plugin_tb') . ' WHERE tb_id='.intval($tb_id).' AND block = 0');
}
/**
* Returns the manual ping URL
*/
function getManualPingUrl($itemid) {
global $CONF;
return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=form&tb_id='.$itemid;
}
/**
* Show the manual ping form
*/
function showManualPingError($itemid, $status = '') {
global $CONF;
$form = true; $error = true; $success = false;
sendContentType('text/html', 'admin-trackback', _CHARSET);
//modify start+++++++++
// include ($this->getDirectory() . '/templates/form.html');
require_once($this->getDirectory() . '/template.php');
$mTemplate = new Trackback_Template(null, $this->getDirectory());
$mTemplate->set ('CONF', $CONF);
$mTemplate->set ('itemid', $itemid);
$mTemplate->set ('form', $form);
$mTemplate->set ('error', $error);
$mTemplate->set ('success', $success);
$mTemplate->set ('status', $status);
$mTemplate->template('templates/form.html');
echo $mTemplate->fetch();
//modify end+++++++++
}
function showManualPingSuccess($itemid, $status = '') {
global $CONF;
$form = false; $error = false; $success = true;
sendContentType('text/html', 'admin-trackback', _CHARSET);
//modify start+++++++++
//include ($this->getDirectory() . '/templates/form.html');
require_once($this->getDirectory() . '/template.php');
$mTemplate = new Trackback_Template(null, $this->getDirectory());
$mTemplate->set ('CONF', $CONF);
$mTemplate->set ('itemid', $itemid);
$mTemplate->set ('form', $form);
$mTemplate->set ('error', $error);
$mTemplate->set ('success', $success);
$mTemplate->set ('status', $status);
$mTemplate->template('templates/form.html');
echo $mTemplate->fetch();
//modify end+++++++++
}
function showManualPingForm($itemid, $text = '') {
global $CONF;
$form = true; $error = false; $success = false;
// Check if we are allowed to accept pings
if ( !$this->isAcceptTrackBack($itemid) ) {
$text = 'Sorry, no trackback pings are accepted';
$form = false; $error = true;
}
sendContentType('text/html', 'admin-trackback', _CHARSET);
//modify start+++++++++
//include ($this->getDirectory() . '/templates/form.html');
require_once($this->getDirectory() . '/template.php');
$mTemplate = new Trackback_Template(null, $this->getDirectory());
$mTemplate->set ('CONF', $CONF);
$mTemplate->set ('itemid', $itemid);
$mTemplate->set ('form', $form);
$mTemplate->set ('error', $error);
$mTemplate->set ('success', $success);
$mTemplate->set ('status', $status);
$mTemplate->template('templates/form.html');
echo $mTemplate->fetch();
//modify end+++++++++
}
/**
* Returns the trackback URL
*/
function getTrackBackUrl($itemid) {
global $CONF, $manager;
return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&tb_id='.$itemid;
}
/*
* Insert RDF code for item
*/
function insertCode($itemid) {
$itemid = intval($itemid);
global $manager, $CONF;
$item = & $manager->getItem($itemid, 0, 0);
$blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
/*
$CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
$uri = createItemLink($item['itemid'],'');
*/
$uri = $this->_createItemLink($item['itemid'],$blog);
$title = strip_tags($item['title']);
$desc = strip_tags($item['body']);
$desc = $this->_cut_string($desc, 200);
$desc = htmlspecialchars($desc, ENT_QUOTES);
?>
getItem($tb_id, 0, 0);
if($item)
{
$blog =& $manager->getBlog(getBlogIDFromItemID($item['itemid']));
$blog_name = $blog->getName();
$title = $item['title'];
$excerpt = $item['body'];
//modify start+++++++++
/*
if (_CHARSET != 'UTF-8')
{
$title = $this->_convert_to_utf8($title, $encoding);
$excerpt = $this->_convert_to_utf8($excerpt, $encoding);
$blog_name = $this->_convert_to_utf8($blog_name, $encoding);
}
$title = $this->_decode_entities(strip_tags($title));
$excerpt = $this->_decode_entities(strip_tags($excerpt));
$blog_name = $this->_decode_entities(strip_tags($blog_name));
*/
$title = $this->_restore_to_utf8($title);
$excerpt = $this->_restore_to_utf8($excerpt);
$blog_name = $this->_restore_to_utf8($blog_name);
//modify end+++++++++
$excerpt = $this->_cut_string($excerpt, 200);
//modify start+++++++++
/*
$CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
$url = createItemLink($item['itemid'],'');
*/
$url = $this->_createItemLink($item['itemid'],$blog);
//modify end+++++++++
// Use UTF-8 charset for output
header('Content-Type: text/xml');
echo "<","?xml version='1.0' encoding='UTF-8'?",">\n";
echo "\n";
echo "\t0\n";
echo "\t\n";
echo "\t\t\n";
echo "\t\t\t".htmlspecialchars($title, ENT_QUOTES)."\n";
echo "\t\t\t".htmlspecialchars($url, ENT_QUOTES)."\n";
echo "\t\t\t".htmlspecialchars($excerpt, ENT_QUOTES)."\n";
$query = 'SELECT url, blog_name, excerpt, title, UNIX_TIMESTAMP(timestamp) as timestamp FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' AND block = 0 ORDER BY timestamp DESC';
$res = sql_query($query);
while ($o = mysql_fetch_object($res))
{
// No need to do conversion, because it is already UTF-8
$data = array (
'url' => htmlspecialchars($o->url, ENT_QUOTES),
'blogname' => htmlspecialchars($this->_restore_to_utf8($o->blog_name), ENT_QUOTES),
'timestamp' => strftime('%Y-%m-%d',$o->timestamp),
'title' => htmlspecialchars($this->_restore_to_utf8($o->title), ENT_QUOTES),
'excerpt' => htmlspecialchars($this->_restore_to_utf8($o->excerpt), ENT_QUOTES),
'tburl' => $this->getTrackBackUrl($tb_id)
);
echo "\n";
echo "\t\t\t- \n";
echo "\t\t\t\t".$data['title']."\n";
echo "\t\t\t\t".$data['url']."\n";
echo "\t\t\t\t".$data['excerpt']."\n";
echo "\t\t\t
\n";
}
echo "\t\t\n";
echo "\t\n";
echo "";
exit;
}
else
{
$this->xmlResponse(_ERROR_NOSUCHITEM);
}
}
/**************************************************************************************
* SENDING AND RECEIVING TRACKBACK PINGS
*/
/*
* Send a Trackback ping to another website
*/
function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url, $utf8flag=0)
{
$tempEncording = ($utf8flag)? 'UTF-8': _CHARSET;
// 1. Check some basic things
if (!$this->canSendPing()) {
return 'You\'re not allowed to send pings';
}
if ($this->getOption('SendPings') == 'no') {
return 'Sending trackback pings is disabled';
}
if ($ping_url == '') {
return 'No ping URL';
}
// 2. Check if protocol is correct http URL
$parsed_url = parse_url($ping_url);
if ($parsed_url['scheme'] != 'http' || $parsed_url['host'] == '')
return 'Bad ping URL';
$port = ($parsed_url['port']) ? $parsed_url['port'] : 80;
// 3. Create contents
if($tempEncording != _CHARSET){
$title = mb_convert_encoding($title, $tempEncording, _CHARSET);
$excerpt = mb_convert_encoding($excerpt, $tempEncording, _CHARSET);
$blog_name = mb_convert_encoding($blog_name, $tempEncording, _CHARSET);
}
$content = 'title=' . urlencode( $title );
$content .= '&url=' . urlencode( $url );
$content .= '&excerpt=' . urlencode( $excerpt );
$content .= '&blog_name=' . urlencode( $blog_name );
// 4. Prepare HTTP request
$request = 'POST ' . $parsed_url['path'];
if ($parsed_url['query'] != '')
$request .= '?' . $parsed_url['query'];
$request .= " HTTP/1.1\r\n";
$request .= "Accept: */*\r\n";
$request .= "User-Agent: " . $this->userAgent . "\r\n";
$request .= ( $port == 80 )?
"Host: " . $parsed_url['host'] . "\r\n":
"Host: " . $parsed_url['host'] . ":" . $port . "\r\n";
$request .= "Cache-Control: no-cache\r\n";
$request .= "Connection: Close\r\n";
$request .= "Content-Length: " . strlen( $content ) . "\r\n";
$request .= ($utf8flag)?
"Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n":
"Content-Type: application/x-www-form-urlencoded; charset="._CHARSET."\r\n";
$request .= "\r\n";
$request .= $content;
$socket = fsockopen( $parsed_url['host'], $port, $errno, $errstr );
if ( ! $socket )
return 'Could not send ping: '.$errstr.' ('.$errno.')';
// 5. Execute HTTP request
fputs($socket, $request);
// 6. Receive response
$result = '';
while (!feof($socket)) {
$result .= fgets($socket, 4096);
}
fclose($socket);
//modify start+++++++++
list($header, $body) = split("\r\n\r\n", $result, 2);
preg_match("/HTTP\/1\.[0-1] ([0-9]+) ([^\r\n]*)\r?\n/", $header, $httpresp);
$respCd = $httpresp[1];
$respMsg = $httpresp[2];
if( $respCd != 200 ){
return 'An error occurred: HTTP Error: [' . $respCd . '] ' . $respMsg;
}
if( function_exists('xml_parser_create') ){
$p = new NP_TrackBack_XMLParser();
$p->parse($body);
$p->free();
if( $p->isError ){
return 'An error occurred: ' . htmlspecialchars($p->message, ENT_QUOTES);
}
} else {
if ( strstr($DATA[1],'0') === false ){
preg_match("/(.*?)<\/message>/",$DATA[1],$error_message);
if( $error_message[1] )
return 'An error occurred: '.htmlspecialchars($error_message[1], ENT_QUOTES);
else
return 'An error occurred: fatal error.';
}
}
return '';
}
//modify end+++++++++
/*
* Handle a Trackback ping sent to this website
*/
function handlePing($tb_id = 0) {
global $manager;
// Defaults
$spam = false;
$link = false;
//modify start+++++++++
// $block = true;
$block = false;
//modify end+++++++++
if ($tb_id == 0)
$tb_id = intRequestVar('tb_id');
$rss = requestVar('__mode') == 'rss';
//mod by cles
$enableLinkCheck = $this->isEnableLinkCheck($tb_id);
$block = ( $enableLinkCheck ) ? true : false ;
//mod by cles end
if (!$tb_id) {
return 'TrackBack ID is missing (tb_id)';
}
if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes')) {
return _ERROR_NOSUCHITEM;
}
// 0. Check if we need to output the list as rss
if ($rss) {
$this->rssResponse($tb_id);
return;
}
//mod by cles
// check: accept pings.
$blogId = getBlogIDFromItemID($tb_id);
$isAcceptPing = $this->isAcceptTrackBack($tb_id);
if (! $isAcceptPing)
return 'Sorry, no trackback pings are accepted.';
//mod by cles end
// 1. Get attributes
//modify start+++++++++
$b =& $manager->getBlog($blogId);
//modify end+++++++++
$url = requestVar('url');
$title = requestVar('title');
$excerpt = requestVar('excerpt');
$blog_name = requestVar('blog_name');
if( $url && preg_match('/https?:\/\/([^\/]+)/', $url, $matches) ){
if( gethostbynamel($matches[1]) === FALSE )
return 'URL is invalid (url)';
} else {
return 'URL is missing or invalid (url)';
}
// 2. Conversion of encoding...
//modify start+++++++++
/* if (preg_match ("/;\s*charset=([^\n]+)/is", $_SERVER["CONTENT_TYPE"], $regs))
$encoding = strtoupper(trim($regs[1]));
else
$encoding = $this->_detect_encoding($excerpt);
*/
$encoding = $this->_detect_encoding($excerpt);
//modify end+++++++++
//modify start+++++++++
if (_CHARSET != 'UTF-8'){
$title = $this->_strip_controlchar(strip_tags(mb_convert_encoding($title, _CHARSET, $encoding)));
$excerpt = $this->_strip_controlchar(strip_tags(mb_convert_encoding($excerpt, _CHARSET, $encoding)));
$blog_name = $this->_strip_controlchar(strip_tags(mb_convert_encoding($blog_name, _CHARSET, $encoding)));
}else{
$title = $this->_strip_controlchar($this->_convert_to_utf8($title, $encoding));
$excerpt = $this->_strip_controlchar($this->_convert_to_utf8($excerpt, $encoding));
$blog_name = $this->_strip_controlchar($this->_convert_to_utf8($blog_name, $encoding));
$title = $this->_decode_entities(strip_tags($title));
$excerpt = $this->_decode_entities(strip_tags($excerpt));
$blog_name = $this->_decode_entities(strip_tags($blog_name));
}
//modify end+++++++++
// 4. Save data in the DB
$res = @sql_query('
SELECT
tb_id, block, spam
FROM
'.sql_table('plugin_tb').'
WHERE
url = \''.mysql_real_escape_string($url).'\' AND
tb_id = \''.intval($tb_id).'\'
');
if (mysql_num_rows($res) != 0)
{
// Existing TB, update it
/*
$res = @sql_query('
UPDATE
'.sql_table('plugin_tb').'
SET
title = "'.mysql_real_escape_string($title).'",
excerpt = "'.mysql_real_escape_string($excerpt).'",
blog_name = "'.mysql_real_escape_string($blog_name).'",
timestamp = '.mysqldate(time()).'
WHERE
url = "'.mysql_real_escape_string($url).'" AND
tb_id = "'.$tb_id.'"
');
*/
//modify start+++++++++
$rows = mysql_fetch_assoc($res);
$spam = ( $rows['block'] || $rows['spam'] ) ? true : false;
$res = @sql_query('
UPDATE
'.sql_table('plugin_tb').'
SET
title = \''.mysql_real_escape_string($title).'\',
excerpt = \''.mysql_real_escape_string($excerpt).'\',
blog_name = \''.mysql_real_escape_string($blog_name).'\',
timestamp = '.mysqldate($b->getCorrectTime()).'
WHERE
url = \''.mysql_real_escape_string($url).'\' AND
tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\'
');
//modify end+++++++++
if (!$res) {
return 'Could not update trackback data: '.mysql_error();
}
}
else
{
//mod by cles
// spam block
$res = @sql_query('SELECT id FROM '.sql_table('plugin_tb').' WHERE block = 1 and url = \''.mysql_real_escape_string($url).'\'' );
if (mysql_num_rows($res) != 0) {
// NP_Trackback has blocked tb !
ACTIONLOG :: add(INFO, "Trackback: Duplicated Blocked Trackback [ignore] (itemid:$tb_id from: $url)");
return 'Sorry, trackback ping is not accepted.';
}
//mod by cles end
// 4. SPAM check (for SpamCheck API 2 /w compat. API 1)
$spamcheck = array (
'type' => 'trackback',
'id' => $tb_id,
'title' => $title,
'excerpt' => $excerpt,
'blogname' => $blog_name,
'url' => $url,
'return' => true,
'live' => true,
/* Backwards compatibility with SpamCheck API 1*/
'data' => $url . "\n" . $title . "\n" . $excerpt . "\n" . $blog_name . "\n" . serverVar('HTTP_USER_AGENT'),
'ipblock' => true,
);
$manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
if (isset($spamcheck['result']) && $spamcheck['result'] == true)
{
$spam = true;
}
// 5. Content check (TO DO)
if($spam == false || $enableLinkCheck == 'ignore' ) //modify
{
//mod by cles
// $contents = $this->retrieveUrl ($url);
//
// if (preg_match("/(".preg_quote($_SERVER["REQUEST_URI"], '/').")|(".preg_quote($_SERVER["SERVER_NAME"], '/').")/i", $contents)) {
// $link = true;
// }
if( $enableLinkCheck ){
$contents = $this->retrieveUrl($url);
$linkArray = $this->getPermaLinksFromText($contents);
$itemLink = $this->_createItemLink($tb_id, $b);
$itemLinkPat = '{^' . preg_quote($itemLink) .'}i';
$itemLinkPat = str_replace('&','&(amp;)?', $itemLinkPat);
foreach($linkArray as $l) {
if(preg_match($itemLinkPat, $l)){
ACTIONLOG :: add(INFO, "Trackback: LinkCheck OK. (link: $l pat: $itemLinkPat )");
$link = true;
break;
}
}
if( ! $link ){
$cnt = @count($linkArray);
if( $enableLinkCheck == 'ignore' ){
ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [ignore] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat)");
return 'Sorry, trackback ping is not accepted.';
} else {
ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [block] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat");
}
}
}
//mod by cles end
}
// 6. Determine if Trackback is safe...
//modify start+++++++++
// $block = $spam == true || $link == false;
// $block = $spam == true ;
//modify end+++++++++
//mod by cles
if ( $enableLinkCheck )
$block = ($spam == true || $link == false);
else
$block = $spam == true ;
//mod by cles end
// New TB, insert it
/*
$query = '
INSERT INTO
'.sql_table('plugin_tb').'
SET
tb_id = "'.$tb_id.'",
block = "'.($block ? '1' : '0').'",
spam = "'.($spam ? '1' : '0').'",
link = "'.($link ? '1' : '0').'",
url = "'.mysql_real_escape_string($url).'",
title = "'.mysql_real_escape_string($title).'",
excerpt = "'.mysql_real_escape_string($excerpt).'",
blog_name = "'.mysql_real_escape_string($blog_name).'",
timestamp = '.mysqldate(time()).'
';
*/
//modify start+++++++++
$query = '
INSERT INTO
'.sql_table('plugin_tb').'
SET
tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\',
block = \''.($block ? '1' : '0').'\',
spam = \''.($spam ? '1' : '0').'\',
link = \''.($link ? '1' : '0').'\',
url = \''.mysql_real_escape_string($url).'\',
title = \''.mysql_real_escape_string($title).'\',
excerpt = \''.mysql_real_escape_string($excerpt).'\',
blog_name = \''.mysql_real_escape_string($blog_name).'\',
timestamp = '.mysqldate($b->getCorrectTime()).'
';
//modify end+++++++++
$res = @sql_query($query);
if (!$res) {
return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error() . $query;
}
}
// 7. Send notification e-mail if needed
$notifyAddrs = $this->getOption('NotifyEmail');
$notifyAddrs = ( $notifyAddrs ? $notifyAddrs . ';' : '')
. $this->getBlogOption($blogId ,'NotifyEmailBlog');
if ($notifyAddrs && $spam == false)
{
$vars = array (
'tb_id' => $tb_id,
'url' => $url,
'title' => $title,
'excerpt' => $excerpt,
'blogname' => $blog_name
);
//modify start+++++++++
/*
$vars = array (
'tb_id' => $tb_id,
'url' => $url,
'title' => mb_convert_encoding($title, 'ISO-2022-JP', _CHARSET),
'excerpt' => mb_convert_encoding($excerpt, 'ISO-2022-JP', _CHARSET),
'blogname' => mb_convert_encoding($blog_name, 'ISO-2022-JP', _CHARSET)
);
*/
//maybe not needed because japanese version has "mb_send_mail" in function notify
//modify end+++++++++
$mailto_title = TEMPLATE::fill($this->notificationMailTitle, $vars);
$mailto_msg = TEMPLATE::fill($this->notificationMail, $vars);
global $CONF, $DIR_LIBS;
// make sure notification class is loaded
if (!class_exists('notification'))
include($DIR_LIBS . 'NOTIFICATION.php');
$notify = new NOTIFICATION($notifyAddrs);
$notify->notify($mailto_title, $mailto_msg , $CONF['AdminEmail']);
//mod by cles+++++++++++
if ($manager->pluginInstalled('NP_Cache')){
$p =& $manager->getPlugin('NP_Cache');
$p->setCurrentBlog($tb_id);
$p->cleanItem($tb_id);
$p->cleanArray(array('index'));
}
//mod by cles end +++++++++++
}
if( $block )
return 'Sorry, trackback ping is not accepted.';
return '';
}
function xmlResponse($errorMessage = '')
{
header('Content-Type: text/xml');
echo "<","?xml version='1.0' encoding='UTF-8'?",">\n";
echo "\n";
if ($errorMessage)
echo "\t1\n\t",htmlspecialchars($errorMessage, ENT_QUOTES),"\n";
else
echo "\t0\n";
echo "";
exit;
}
/*
* Check if member may send ping (check if logged in)
*/
function canSendPing() {
global $member;
return $member->isLoggedIn() || $this->xmlrpc;
}
//mod by cles
function redirect($tb_id, $urlHash){
global $CONF;
$query = 'SELECT url FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' and md5(url)="'.$urlHash.'"';
$res = sql_query($query);
$url = $CONF['SiteURL'];
if ($o = mysql_fetch_object($res)) {
$url = htmlspecialchars($o->url, ENT_QUOTES);
}
$url = stripslashes($url);
$url = str_replace('&','&',$url);
$url = str_replace('<','<',$url);
$url = str_replace('>','>',$url);
$url = str_replace('"','"',$url);
header('Location: '.$url);
}
function getRequiredURL($itemid){
global $manager;
$blog = & $manager->getBlog(getBlogIDFromItemID($itemid));
if( $this->isEnableLinkCheck($itemid) )
return $this->_createItemLink($itemid, $blog);
return null;
}
function isEnableLinkCheck($itemid){
$blogid = getBlogIDFromItemID($itemid);
switch( $this->getItemOption($itemid, 'isAcceptW/OLink') ){
case 'default':
$def = $this->getBlogOption($blogid, 'isAcceptW/OLinkDef');
if($def == 'yes')
return false;
else
return $def; // block or ignore
case 'yes':
return false;
case 'no':
return true;
default :
ACTIONLOG :: add(INFO, "Trackback: Unknown Option (itemid:$itemid, value:$val)");
return false;
}
}
var $acceptTrackbacks = array();
function isAcceptTrackBack($itemid = null){
if( $itemid && isset($acceptTrackbacks[$itemid]) )
return $acceptTrackbacks[$itemid] === true;
$ret = false;
if( $this->getOption('AcceptPing') == 'yes' ){
$bid = null;
if($itemid){
$bid = getBlogIDFromItemID(intval($itemid));
} else {
global $blog;
$bid = $blog->getID();
}
if( $this->getBlogOption($bid, "AllowTrackBack") == 'yes' ){
if( ! $itemid ){
$ret = ( $this->getItemOption(intval($itemid), 'ItemAcceptPing') == 'yes' ) ? true : false ;
} else {
$ret = true;
}
} else {
$ret = false;
}
}
if($itemid)
$acceptTrackbacks[$itemid] = $ret;
return $ret === true;
}
//mod by cles end
/**************************************************************************************
* EVENTS
*/
function event_SendTrackback($data) {
global $manager;
// Enable sending trackbacks for the XML-RPC API, otherwise we would
// get an error because the current user is not exactly logged in.
$this->xmlrpc = true;
$itemid = $data['tb_id'];
$item = &$manager->getItem($itemid, 0, 0);
if (!$item) return; // don't ping for draft & future
if ($item['draft']) return; // don't ping on draft items
// gather some more information, needed to send the ping (blog name, etc)
$blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
$blog_name = $blog->getName();
$title = $data['title'] != '' ? $data['title'] : $item['title'];
$title = strip_tags($title);
$excerpt = $data['body'] != '' ? $data['body'] : $item['body'];
$excerpt = strip_tags($excerpt);
$excerpt = $this->_cut_string($excerpt, 200);
$CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
//$url = createItemLink($itemid);
$url = $this->_createItemLink($itemid, $blog);
while (list(,$url) = each($data['urls'])) {
$res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $url);
if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $url . ')');
}
}
function event_RetrieveTrackback($data) {
$res = sql_query('
SELECT
url,
title,
UNIX_TIMESTAMP(timestamp) AS timestamp
FROM
'.sql_table('plugin_tb').'
WHERE
tb_id = '.intval($data['tb_id']).' AND
block = 0
ORDER BY
timestamp ASC
');
while ($row = mysql_fetch_array($res)) {
$trackback = array(
'title' => $row['title'],
'url' => $row['url'],
'ip' => ''
);
$data['trackbacks'][] = $trackback;
}
}
/*
function event_BookmarkletExtraHead($data) {
global $NP_TB_URL;
list ($NP_TB_URL,) = $this->getURIfromLink(requestVar('loglink'));
}
*/
function event_PrepareItemForEdit($data) {
// if (!$this->getOption('AutoXMLHttp'))
if ($this->getOption('AutoXMLHttp') == 'no')
{
// The space between body and more is to make sure we didn't join 2 words accidently....
$this->larray = $this->autoDiscovery($data['item']['body'].' '.$data['item']['more']);
}
}
/*
* After an item has been added to the database, send out a ping if requested
* (trackback_ping_url variable in request)
*/
function event_PostAddItem($data) {
$this->pingTrackback($data);
}
function event_PreUpdateItem($data) {
$this->pingTrackback($data);
}
/**
* Add trackback options to add item form/bookmarklet
*/
function event_AddItemFormExtras($data) {
// global $NP_TB_URL;
?>
TrackBack
getOption('AutoXMLHttp'))
if ($this->getOption('AutoXMLHttp') == 'yes')
{
?>
jsautodiscovery();
}
?>
TrackBack
getOption('AutoXMLHttp'))
if ($this->getOption('AutoXMLHttp') == 'yes')
{
?>
jsautodiscovery();
}
else
{
if (count($this->larray) > 0)
{
?>
Auto Discovered Ping URL's:
larray).'" />';
$i = 0;
while (list($url, $title) = each ($this->larray))
{
//modify start+++++++++
if (_CHARSET != 'UTF-8') {
$title = $this->_utf8_to_entities($title);
$title = mb_convert_encoding($title, _CHARSET, 'UTF-8');
}
//modify end+++++++++
echo '
';
$i++;
}
}
}
?>
getItem($itemid, 0, 0);
if (!$item) return; // don't ping for draft & future
if ($item['draft']) return; // don't ping on draft items
// gather some more information, needed to send the ping (blog name, etc)
$blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
$blog_name = $blog->getName();
$title = $data['title'] != '' ? $data['title'] : $item['title'];
$title = strip_tags($title);
$excerpt = $data['body'] != '' ? $data['body'] : $item['body'];
$excerpt = strip_tags($excerpt);
$excerpt = $this->_cut_string($excerpt, 200);
/*
$CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
$url = createItemLink($itemid);
*/
$url = $this->_createItemLink($item['itemid'],$blog);
// send the ping(s) (add errors to actionlog)
for ($i=0; $isendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_urls[$i], $utf8flag[$i]);
else
$res = $this->handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_urls[$i]);
if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $ping_urls[$i] . ')');
}
}
/**************************************************************************************
* AUTO-DISCOVERY
*/
/*
* Auto-Discovery of TrackBack Ping URLs based on HTML story
*/
function autoDiscovery($text)
{
$links = $this->getPermaLinksFromText($text);
$result = array();
for ($i = 0; $i < count($links); $i++)
{
list ($url, $title) = $this->getURIfromLink($links[$i]);
if ($url != '')
$result[$url] = $title;
}
return $result;
}
/*
* Auto-Discovery of TrackBack Ping URLs based on single link
*/
function getURIfromLink($link)
{
// Check to see if the cache contains this link
$res = sql_query('SELECT url, title FROM '.sql_table('plugin_tb_lookup').' WHERE link=\''.mysql_real_escape_string($link).'\'');
if ($row = mysql_fetch_array($res))
{
if ($row['title'] != '')
{
//modify start+++++++++
if (_CHARSET != 'UTF-8'){
$row['title'] = mb_convert_encoding($row['title'], 'UTF-8', _CHARSET);
$row['title'] = $this->_decode_entities($row['title']);
}
//modify end+++++++++
return array (
$row['url'], $row['title']
);
}
else
{
return array (
$row['url'], $row['url']
);
}
}
// Retrieve RDF
if (($rdf = $this->getRDFFromLink($link)) !== false)
{
// Get PING attribute
if (($uri = $this->getAttributeFromRDF($rdf, 'trackback:ping')) !== false)
{
// Get TITLE attribute
if (($title = $this->getAttributeFromRDF($rdf, 'dc:title')) !== false)
{
// Get CREATOR attribute
if (($author = $this->getAttributeFromRDF($rdf, 'dc:creator')) !== false)
{
$title = $author. ": " . $title;
}
$uri = $this->_decode_entities($uri);
//modify start+++++++++
if (_CHARSET != 'UTF-8')
$convertedTitle = mb_convert_encoding($title, _CHARSET, 'UTF-8');
else
$convertedTitle = $title;
/*
// Store in cache
$res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($title)."')");
*/
// Store in cache
$res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','".mysql_real_escape_string($convertedTitle)."')");
//modify end+++++++++
$title = $this->_decode_entities($title);
return array (
$uri, $title
);
}
else
{
$uri = html_entity_decode($uri, ENT_COMPAT);
// Store in cache
$res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','')");
return array (
$uri, $uri
);
}
}
}
// Store in cache
$res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','','')");
return array ('', '');
}
/*
* Detect links used in HTML code
*/
function getPermaLinksFromText($text)
{
$links = array();
if (preg_match_all('/<[aA] +([^>]+)>/', $text, $array, PREG_SET_ORDER))
{
for ($i = 0; $i < count($array); $i++)
{
if( preg_match('/s?https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+/', $array[$i][1], $matches) )
$links[$matches[0]] = 1;
}
}
return array_keys($links);
}
/*
* Retrieve RDF code from external link
*/
function getRDFFromLink($link)
{
if ($content = $this->getContents($link))
{
preg_match_all('/()/sm', $content, $rdfs, PREG_SET_ORDER);
if (count($rdfs) > 1)
{
for ($i = 0; $i < count($rdfs); $i++)
{
if (preg_match('|dc:identifier="'.preg_quote($link).'"|ms',$rdfs[$i][1]))
{
return $rdfs[$i][1];
}
}
}
else
{
// No need to check the identifier
return $rdfs[0][1];
}
}
return false;
}
/**
* Retrieve the contents of an external (X)HTML document
*/
function getContents($link) {
// Use cURL extention if available
if (function_exists("curl_init") && $this->useCurl == 2)
{
// Make HEAD request
$ch = curl_init();
@curl_setopt($ch, CURLOPT_URL, $link);
@curl_setopt($ch, CURLOPT_HEADER, true);
@curl_setopt($ch, CURLOPT_NOBODY, true);
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
@curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@curl_setopt($ch, CURLOPT_TIMEOUT, 20);
@curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
$headers = curl_exec($ch);
curl_close($ch);
// Check if the link points to a (X)HTML document
if (preg_match('/Content-Type: (text\/html|application\/xhtml+xml)/i', $headers))
{
return $this->retrieveUrl ($link);
}
return false;
}
else
{
return $this->retrieveUrl ($link);
}
}
/*
* Get a single attribute from RDF
*/
function getAttributeFromRDF($rdf, $attribute)
{
if (preg_match('/'.$attribute.'="([^"]+)"/', $rdf, $matches))
{
return $matches[1];
}
return false;
}
/**************************************************************************************/
/* Internal helper functions for dealing with external file retrieval */
function retrieveUrl ($url) {
//mod by cles
$ua = ini_set('user_agent', $this->userAgent);
//mod by cles end
if (function_exists('curl_init') && $this->useCurl > 0)
{
// Set options
$ch = curl_init();
@curl_setopt($ch, CURLOPT_URL, $url);
@curl_setopt($ch, CURLOPT_HEADER, 1);
@curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
@curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
@curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
@curl_setopt($ch, CURLOPT_TIMEOUT, 20);
@curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
// Retrieve response
$raw = curl_exec($ch);
$info = curl_getinfo($ch);
// Split into headers and contents
$headers = substr($raw, 0, $info['header_size']);
$contents = substr($raw, $info['header_size']);
curl_close($ch);
}
elseif ($fp = @fopen ($url, "r"))
{
//mod by cles
// $contents = fread($fp, 8192);
$contents = '';
while (!feof($fp)) {
$contents .= fread($fp, 8192);
}
//mod by cles end
$headers = '';
fclose($fp);
}
//mod by cles
ini_set('user_agent', $ua);
//mod by cles end
// Next normalize the encoding to UTF8...
$contents = $this->_convert_to_utf8_auto($contents, $headers);
return $contents;
}
/**************************************************************************************/
/* Internal helper functions for dealing with encodings and entities */
var $entities_default = array (
'"' => '"',
'&' => '&',
''' => ''',
'<' => '<',
'>' => '>',
);
//modify start+++++++++
function _restore_to_utf8($contents)
{
if (_CHARSET != 'UTF-8')
{
$contents = mb_convert_encoding($contents, 'UTF-8', _CHARSET);
}
$contents = $this->_decode_entities(strip_tags($contents));
return $contents;
}
//modify end+++++++++
function _detect_encoding($string)
{
//modify start+++++++++
if (function_exists('mb_convert_encoding')) {
$encoding = (preg_match ("/;\s*charset=([^\n]+)/is", serverVar("CONTENT_TYPE"), $regs))?
strtoupper(trim($regs[1])):
'';
if ( ($encoding !="") && ((mb_http_input("P") == "") || ( strtolower( ini_get("mbstring.http_input") ) == "pass")) ) {
return $encoding;
} else {
$encoding = mb_detect_encoding($string, 'UTF-8,EUC-JP,SJIS,ISO-8859-1,ASCII,JIS');
}
return ( $encoding ) ? $encoding : 'ISO-8859-1';
}
//modify end+++++++++
if (!ereg("[\x80-\xFF]", $string) && !ereg("\x1B", $string))
return 'US-ASCII';
if (!ereg("[\x80-\xFF]", $string) && ereg("\x1B", $string))
return 'ISO-2022-JP';
if (preg_match("/^([\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF])+$/", $string) == 1)
return 'UTF-8';
if (preg_match("/^([\x01-\x7F]|\x8E[\xA0-\xDF]|\x8F[xA1-\xFE][\xA1-\xFE]|[\xA1-\xFE][\xA1-\xFE])+$/", $string) == 1)
return 'EUC-JP';
if (preg_match("/^([\x01-\x7F]|[\xA0-\xDF]|[\x81-\xFC][\x40-\xFC])+$/", $string) == 1)
return 'Shift_JIS';
return 'ISO-8859-1';
}
function _convert_to_utf8($contents, $encoding)
{
$done = false;
//modify start+++++++++
// if (!$done && function_exists('iconv'))
// {
//
// $result = @iconv($encoding, 'UTF-8//IGNORE', $contents);
//
// if ($result)
// {
// $contents = $result;
// $done = true;
// }
// }
if(!$done && function_exists('mb_convert_encoding'))
{
if( function_exists('mb_substitute_character') ){
@mb_substitute_character('none');
}
$result = @mb_convert_encoding($contents, 'UTF-8', $encoding );
if ($result)
{
$contents = $result;
$done = true;
}
}
if (!$done && function_exists('iconv'))
{
$result = @iconv($encoding, 'UTF-8//IGNORE', $contents);
if ($result)
{
$contents = $result;
$done = true;
}
}
//modify end+++++++++
return $contents;
}
function _convert_to_utf8_auto($contents, $headers = '')
{
/* IN: string in unknown encoding, headers received during transfer
* OUT: string in UTF-8 encoding
*/
$str = substr($contents, 0, 4096);
$len = strlen($str);
$pos = 0;
$out = '';
while ($pos < $len)
{
$ord = ord($str[$pos]);
if ($ord > 32 && $ord < 128)
$out .= $str[$pos];
$pos++;
}
// Detection of encoding, check headers
if (preg_match ("/;\s*charset=([^\n]+)/is", $headers, $regs))
$encoding = strtoupper(trim($regs[1]));
// Then check meta inside document
if (preg_match ("/;\s*charset=([^\"']+)/is", $out, $regs))
$encoding = strtoupper(trim($regs[1]));
// Then check xml declaration
if (preg_match("/<\?xml.+encoding\s*=\s*[\"|']([^\"']+)[\"|']\s*\?>/i", $out, $regs))
$encoding = strtoupper(trim($regs[1]));
// Converts
return $this->_convert_to_utf8($contents, $encoding);
}
function _decode_entities($string)
{
/* IN: string in UTF-8 containing entities
* OUT: string in UTF-8 without entities
*/
/// Convert all hexadecimal entities to decimal entities
$string = preg_replace('/[Xx]([0-9A-Fa-f]+);/e', "''.hexdec('\\1').';'", $string);
global $_entities;
// Deal with invalid cp1251 numeric entities
$string = strtr($string, $_entities['cp1251']);
// Convert all named entities to numeric entities
$string = strtr($string, $this->entities_default);
$string = strtr($string, $_entities['named']);
// Convert all numeric entities to UTF-8
$string = preg_replace('/([0-9]+);/e', "''.dechex('\\1').';'", $string);
$string = preg_replace('/[Xx]([0-9A-Fa-f]+);/e', "NP_TrackBack::_hex_to_utf8('\\1')", $string);
return $string;
}
function _hex_to_utf8($s){
return entity::_hex_to_utf8($s);
}
function _utf8_to_entities($string)
{
/* IN: string in UTF-8 encoding
* OUT: string consisting of only characters ranging from 0x00 to 0x7f,
* using numeric entities to represent the other characters
*/
$len = strlen ($string);
$pos = 0;
$out = '';
while ($pos < $len)
{
$ascii = ord (substr ($string, $pos, 1));
if ($ascii >= 0xF0)
{
$byte[1] = ord(substr ($string, $pos, 1)) - 0xF0;
$byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
$byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
$byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80;
$char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4];
$pos += 4;
}
elseif (($ascii >= 0xE0) && ($ascii < 0xF0))
{
$byte[1] = ord(substr ($string, $pos, 1)) - 0xE0;
$byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
$byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
$char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3];
$pos += 3;
}
elseif (($ascii >= 0xC0) && ($ascii < 0xE0))
{
$byte[1] = ord(substr ($string, $pos, 1)) - 0xC0;
$byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
$char_code = ($byte[1] << 6) + $byte[2];
$pos += 2;
}
else
{
$char_code = ord(substr ($string, $pos, 1));
$pos += 1;
}
if ($char_code < 0x80)
$out .= chr($char_code);
else
$out .= ''. str_pad($char_code, 5, '0', STR_PAD_LEFT) . ';';
}
return $out;
}
function _utf8_to_javascript($string)
{
/* IN: string in UTF-8 encoding
* OUT: string consisting of only characters ranging from 0x00 to 0x7f,
* using javascript escapes to represent the other characters
*/
$len = strlen ($string);
$pos = 0;
$out = '';
while ($pos < $len)
{
$ascii = ord (substr ($string, $pos, 1));
if ($ascii >= 0xF0)
{
$byte[1] = ord(substr ($string, $pos, 1)) - 0xF0;
$byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
$byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
$byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80;
$char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4];
$pos += 4;
}
elseif (($ascii >= 0xE0) && ($ascii < 0xF0))
{
$byte[1] = ord(substr ($string, $pos, 1)) - 0xE0;
$byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
$byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
$char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3];
$pos += 3;
}
elseif (($ascii >= 0xC0) && ($ascii < 0xE0))
{
$byte[1] = ord(substr ($string, $pos, 1)) - 0xC0;
$byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
$char_code = ($byte[1] << 6) + $byte[2];
$pos += 2;
}
else
{
$char_code = ord(substr ($string, $pos, 1));
$pos += 1;
}
if ($char_code < 0x80)
$out .= chr($char_code);
else
$out .= '\\u'. str_pad(dechex($char_code), 4, '0', STR_PAD_LEFT);
}
return $out;
}
/*
function _cut_string($string, $dl = 0) {
$defaultLength = $dl > 0 ? $dl : $this->getOption('defaultLength');
if ($defaultLength < 1)
return $string;
$border = 6;
$count = 0;
$lastvalue = 0;
for ($i = 0; $i < strlen($string); $i++)
{
$value = ord($string[$i]);
if ($value > 127)
{
if ($value >= 192 && $value <= 223)
$i++;
elseif ($value >= 224 && $value <= 239)
$i = $i + 2;
elseif ($value >= 240 && $value <= 247)
$i = $i + 3;
if ($lastvalue <= 223 && $value >= 223 &&
$count >= $defaultLength - $border)
{
return substr($string, 0, $i) . '...';
}
// Chinese and Japanese characters are
// wider than Latin characters
if ($value >= 224)
$count++;
}
elseif ($string[$i] == '/' || $string[$i] == '?' ||
$string[$i] == '-' || $string[$i] == ':' ||
$string[$i] == ',' || $string[$i] == ';')
{
if ($count >= $defaultLength - $border)
return substr($string, 0, $i) . '...';
}
elseif ($string[$i] == ' ')
{
if ($count >= $defaultLength - $border)
return substr($string, 0, $i) . '...';
}
if ($count == $defaultLength)
return substr($string, 0, $i + 1) . '...';
$lastvalue = $value;
$count++;
}
return $string;
}
*/
function _cut_string($string, $dl = 0) {
$maxLength = $dl > 0 ? $dl : $this->getOption('defaultLength');
if ($maxLength < 1)
return $string;
if (strlen($string) > $maxLength)
$string = mb_strimwidth($string, 0, $maxLength, '...', _CHARSET);
return $string;
}
function _strip_controlchar($string){
$string = preg_replace("/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]+/","",$string);
$string = str_replace("\0","",$string);
return $string;
}
//modify start+++++++++
function checkTableVersion(){
$res = sql_query("SHOW FIELDS from ".sql_table('plugin_tb') );
$fieldnames = array();
while ($co = mysql_fetch_assoc($res)) {
if($co['Field'] == 'block') return true;
}
return false;
}
//modify end+++++++++
/*---------------------------------------------------------------------------------- */
/* LOCAL */
/*---------------------------------------------------------------------------------- */
/**
* Handle an incoming TrackBack ping and save the data in the database
*/
function handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_url){
global $manager;
$ping_url = trim($ping_url);
if( preg_match("/^.+tb_id=([0-9]+)$/",$ping_url,$idnum) ){
$tb_id = intval($idnum[1]);
} elseif ( preg_match("/([0-9]+)\.trackback/",$ping_url,$idnum) ){
$tb_id = intval($idnum[1]);
} elseif ( preg_match("/itemid=([0-9]+)/",$ping_url,$idnum) ){
$tb_id = intval($idnum[1]);
}
if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes'))
return _ERROR_NOSUCHITEM . "[ $tb_id ]";
// save data in the DB
$query = 'INSERT INTO ' . sql_table('plugin_tb_lc') . " (tb_id, from_id) VALUES ('".intval($tb_id)."','".intval($itemid)."')";
$res = @sql_query($query);
if (!$res)
return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error();
}
/**
* Show the list of TrackBack pings for a certain Trackback ID
*/
function showLocalList($tb_id) {
global $CONF, $manager;
// create SQL query
$query = 'SELECT t.from_id as from_id , i.ititle as ititle, i.ibody as ibody, i.itime as itime, i.iblog as iblog FROM '.sql_table('plugin_tb_lc').' as t, '.sql_table('item').' as i WHERE t.tb_id='.intval($tb_id) .' and i.inumber=t.from_id ORDER BY i.itime DESC';
$res = sql_query($query);
$vars = array(
'tburl' => $this->getTrackBackUrl($tb_id)
);
// when no TrackBack pings are found
if (!$res || mysql_num_rows($res) == 0) {
echo TEMPLATE::fill($this->getOption('tplLocalEmpty'), $vars);
return;
}
// when TrackBack pings are found
echo TEMPLATE::fill($this->getOption('tplLocalHeader'), $vars);
while ($o = mysql_fetch_object($res)) {
$canDelete = $this->canDelete($tb_id);
$data = array(
'url' => createItemLink($o->from_id),
'blogname' => htmlspecialchars(getBlogNameFromID($o->iblog)),
'timestamp' => strftime('%Y-%m-%d',strtotime($o->itime)),
'title' => htmlspecialchars($o->ititle),
'excerpt' => htmlspecialchars(shorten(strip_tags($o->ibody),200,'...')),
'delete' => $canDelete?'[delete]':'',
'tburl' => $this->getTrackBackUrl($tb_id),
'commentcount'=> quickQuery('SELECT COUNT(*) as result FROM '.sql_table('comment').' WHERE citem=' . intval($o->from_id))
);
echo TEMPLATE::fill($this->getOption('tplLocalItem'), $data);
}
echo TEMPLATE::fill($this->getOption('tplLocalFooter'), $vars);
}
/**
* Delete a TrackBack item, redirect to referer
*/
function deleteLocal($tb_id, $from_id) {
if (!$this->canDelete($tb_id))
return 'You\'re not allowed to delete this trackback item';
$query = 'DELETE FROM ' . sql_table('plugin_tb_lc') . " WHERE tb_id='" . intval($tb_id) . "' and from_id='" . intval($from_id) ."'";
sql_query($query);
return '';
}
function canDelete($tb_id) {
global $member, $manager;
if ( ! $member->isLoggedIn() ) return 0;
$checkIDs = $this->getOption('CheckIDs');
$itemExists =& $manager->existsItem($tb_id,0,0);
// if CheckIDs option is set, check if member canEdit($tb_id)
// if CheckIDs option is not set, and item exists, check if member canEdit($tb_id)
// if CheckIDs option is not set, and item does not exists, check if member isAdmin()
if (($checkIDs == 'yes') || ($itemExists))
return $member->canAlterItem($tb_id);
else
return $member->isAdmin();
}
/**************************************************************************************/
/* Plugin API calls, for installation, configuration and setup */
function getName() { return 'TrackBack'; }
function getAuthor() { return 'rakaz + nakahara21 + hsur'; }
function getURL() { return 'http://blog.cles.jp/np_cles/category/31/subcatid/3'; }
function getVersion() { return '2.0.3 jp10.3'; }
function getDescription() { return '[$Revision: 1.17 $]
' . _TB_DESCRIPTION; }
//modify start+++++++++
/*
function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup")); }
function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead'); }
*/
function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup"), sql_table('plugin_tb_lc')); }
function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead', 'RetrieveTrackback', 'SendTrackback', 'InitSkinParse'); }
//modify end+++++++++
function getMinNucleusVersion() { return 330; }
function supportsFeature($feature) {
switch($feature) {
case 'SqlTablePrefix':
return 1;
//modify start+++++++++
// case 'HelpPage':
// return 1;
//modify end+++++++++
default:
return 0;
}
}
function hasAdminArea() { return 1; }
function event_QuickMenu(&$data) {
global $member, $nucleus, $blogid;
// only show to admins
if (!$member->isLoggedIn() || !$member->isAdmin()) return;
array_push(
$data['options'],
array(
'title' => 'Trackback',
'url' => $this->getAdminURL(),
'tooltip' => 'Manage your trackbacks'
)
);
}
function install() {
$this->createOption('AcceptPing', _TB_AcceptPing,'yesno','yes');
$this->createOption('SendPings', _TB_SendPings,'yesno','yes');
$this->createOption('AutoXMLHttp', _TB_AutoXMLHttp, 'yesno', 'yes');
$this->createOption('CheckIDs', _TB_CheckIDs,'yesno','yes');
$this->createOption('tplHeader', _TB_tplHeader, 'textarea', _TB_tplHeader_VAL);
$this->createOption('tplEmpty', _TB_tplEmpty, 'textarea', _TB_tplEmpty_VAL);
$this->createOption('tplItem', _TB_tplItem, 'textarea', _TB_tplItem_VAL);
$this->createOption('tplFooter', _TB_tplFooter, 'textarea', _TB_tplFooter_VAL);
//mod by cles
$this->createOption('tplLocalHeader', _TB_tplLocalHeader, 'textarea', _TB_tplLocalHeader_VAL);
$this->createOption('tplLocalEmpty', _TB_tplLocalEmpty, 'textarea', _TB_tplLocalEmpty_VAL);
$this->createOption('tplLocalItem', _TB_tplLocalItem, 'textarea', _TB_tplLocalItem_VAL);
$this->createOption('tplLocalFooter', _TB_tplLocalFooter, 'textarea', _TB_tplLocalFooter_VAL);
//mod by cles end
$this->createOption('tplTbNone', _TB_tplTbNone, 'text', "No Trackbacks");
$this->createOption('tplTbOne', _TB_tplTbOne, 'text', "1 Trackback");
$this->createOption('tplTbMore', _TB_tplTbMore, 'text', "<%number%> Trackbacks");
$this->createOption('dateFormat', _TB_dateFormat, 'text', _TB_dateFormat_VAL);
$this->createOption('NotifyEmail', _TB_NotifyEmail,'text','');
$this->createOption('DropTable', _TB_DropTable,'yesno','no');
//mod by cles
$this->createOption('HideUrl',_TB_HideUrl,'yesno','yes');
$this->createOption('ajaxEnabled',_TB_ajaxEnabled,'yesno','no');
$this->createItemOption('ItemAcceptPing',_TB_ItemAcceptPing,'yesno','yes');
$this->createItemOption('isAcceptW/OLink',_TB_isAcceptWOLink,'select','default', _TB_isAcceptWOLink_VAL);
$this->createBlogOption('NotifyEmailBlog', _TB_NotifyEmailBlog,'text','');
$this->createBlogOption('isAcceptW/OLinkDef',_TB_isAcceptWOLinkDef,'select','block', _TB_isAcceptWOLinkDef_VAL);
$this->createBlogOption('AllowTrackBack',_TB_AllowTrackBack,'yesno','yes');
//mod by cles end
/* Create tables */
sql_query("
CREATE TABLE IF NOT EXISTS
".sql_table('plugin_tb')."
(
`id` INT(11) NOT NULL AUTO_INCREMENT,
`tb_id` INT(11) NOT NULL,
`url` TEXT NOT NULL,
`block` TINYINT(4) NOT NULL,
`spam` TINYINT(4) NOT NULL,
`link` TINYINT(4) NOT NULL,
`title` TEXT,
`excerpt` TEXT,
`blog_name` TEXT,
`timestamp` DATETIME,
PRIMARY KEY (`id`)
)
");
sql_query("
CREATE TABLE IF NOT EXISTS
".sql_table('plugin_tb_lookup')."
(
`link` TEXT NOT NULL,
`url` TEXT NOT NULL,
`title` TEXT,
PRIMARY KEY (`link` (100))
)
");
//modify start+++++++++
@sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
@sql_query('CREATE TABLE IF NOT EXISTS ' . sql_table('plugin_tb_lc'). ' (tb_id int(11) not null, from_id int(11) not null, PRIMARY KEY (tb_id,from_id))');
//modify end+++++++++
}
function uninstall() {
if ($this->getOption('DropTable') == 'yes') {
sql_query ('DROP TABLE '.sql_table('plugin_tb'));
sql_query ('DROP TABLE '.sql_table('plugin_tb_lookup'));
sql_query ("DROP table ".sql_table('plugin_tb_lc'));
}
}
function init() {
// include language file for this plugin
$language = ereg_replace( '[\\|/]', '', getLanguageName());
if (file_exists($this->getDirectory().'language/'.$language.'.php'))
include_once($this->getDirectory().'language/'.$language.'.php');
else
include_once($this->getDirectory().'language/'.'english.php');
$this->notificationMail = _TB_NORTIFICATION_MAIL_BODY;
$this->notificationMailTitle = _TB_NORTIFICATION_MAIL_TITLE;
$this->userAgent = 'NucleusCMS NP_TrackBack plugin ( '.$this->getVersion().' )';
}
}