2 // vim: tabstop=2:shiftwidth=2
4 /* ==========================================================================================
5 * Trackback 2.0 for Nucleus CMS
6 * ==========================================================================================
7 * This program is free software and open source software; you can redistribute
8 * it and/or modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the License,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit
20 * http://www.gnu.org/licenses/gpl.html
21 * ==========================================================================================
24 // Compatiblity with Nucleus < = 2.0
25 if (!function_exists('sql_table')) { function sql_table($name) { return 'nucleus_' . $name; } }
28 class NP_TrackBack extends NucleusPlugin {
30 var $useCurl = 1; // use curl? 2:precheck+read by curl, 1: read by curl 0: fread
32 //modify start+++++++++
33 function _createItemLink($itemid, $b){
34 global $CONF, $manager;
35 $blogurl = $b->getURL();
39 $b_tmp =& $manager->getBlog($CONF['DefaultBlog']);
40 $blogurl = $b_tmp->getURL();
43 $blogurl = $CONF['IndexURL'];
44 if ($CONF['URLMode'] != 'pathinfo'){
45 $blogurl = $CONF['Self'];
49 if ($CONF['URLMode'] == 'pathinfo'){
50 if(substr($blogurl, -1) == '/') $blogurl = substr($blogurl,0,-1);
53 $itemUrlOrg = $CONF['ItemURL'];
54 $CONF['ItemURL'] = $blogurl;
55 $itemLink = createItemLink($itemid,'');
56 $CONF['ItemURL'] = $itemUrlOrg;
62 /**************************************************************************************
63 * SKIN VARS, TEMPLATE VARS AND ACTIONS
67 * TrackBack data can be inserted using skinvars (or templatevars)
69 function doSkinVar($skinType, $what = '', $tb_id = '', $amount = 'limit-1') {
71 global $itemid, $manager, $CONF;
73 //modify start+++++++++
74 if(eregi('limit', $tb_id)){
78 $amount = eregi_replace("limit", "", $amount);
79 $amount = intval($amount);
82 if ($tb_id == '') $tb_id = intval($itemid);
85 $isAcceptPing = $this->isAcceptTrackBack($tb_id);
87 //if( $skinType == 'template' && (! $isAcceptPing ) ){
93 // Insert Auto-discovery RDF code
97 // if($skinType == 'item')
109 /* Backwards compatibility with SpamCheck API 1*/
114 //$manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
116 if (isset($spamcheck['result']) && $spamcheck['result'] == true){
120 if( ($skinType == 'item') && (!$spam) && $isAcceptPing )
122 $this->insertCode($tb_id);
125 // Insert TrackBack URL
129 // echo $this->getTrackBackUrl($tb_id);
131 echo $this->getTrackBackUrl($tb_id);
133 echo 'Sorry, no trackback pings are accepted.';
137 // Insert manual ping URL
139 case 'manualpingformlink':
140 echo $this->getManualPingUrl($tb_id);
144 echo $manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id));
147 // Insert TrackBack count
149 $count = $this->getTrackBackCount($tb_id);
151 case 0: echo TEMPLATE::fill($this->getOption('tplTbNone'), array('number' => $count)); break;
152 case 1: echo TEMPLATE::fill($this->getOption('tplTbOne'), array('number' => $count)); break;
153 default: echo TEMPLATE::fill($this->getOption('tplTbMore'), array('number' => $count)); break;
157 // Shows the TrackBack list
160 //modify start+++++++++
161 // $this->showList($tb_id);
162 $this->showList($tb_id, $amount);
163 //modify end+++++++++
168 echo $this->getRequiredURL($tb_id);
171 // shows the Local list
173 $this->showLocalList($tb_id);
183 * When used in templates, the tb_id will be determined by the itemid there
185 function doTemplateVar(&$item, $what = '') {
186 $this->doSkinVar('template', $what, $item->itemid);
190 * A trackback ping is to be received on the URL
191 * http://yourdomain.com/item/1234.trackback
192 * Extra variables to be passed along are url, title, excerpt, blog_name
194 function event_InitSkinParse(&$data) {
195 global $CONF, $itemid;
196 $format = requestVar('format');
198 if ($CONF['URLMode'] == 'pathinfo') {
199 if (preg_match('/(\/|\.)(trackback)(\/|$)/', serverVar('PATH_INFO'), $matches)) {
200 $format = $matches[2];
204 if ($format == 'trackback' && $data['type'] == 'item')
206 $errorMsg = $this->handlePing(intval($itemid));
209 $this->xmlResponse($errorMsg);
211 $this->xmlResponse();
218 * A trackback ping is to be received on the URL
219 * http://yourdomain.com/action.php?action=plugin&name=TrackBack&tb_id=1234
220 * Extra variables to be passed along are url, title, excerpt, blog_name
222 function doAction($type)
224 global $CONF,$manager;
225 $aActionsNotToCheck = array(
232 if (!in_array($type, $aActionsNotToCheck)) {
233 if (!$manager->checkTicket()) return _ERROR_BADTICKET;
238 // When no action type is given, assume it's a ping
240 $errorMsg = $this->handlePing();
243 $this->xmlResponse($errorMsg);
245 $this->xmlResponse();
250 $errorMsg = $this->handlePing();
252 $this->showManualPingError(intRequestVar('tb_id'), $errorMsg);
254 $this->showManualPingSuccess(intRequestVar('tb_id'));
257 // Show manual ping form
260 // $this->showManualPingForm(intRequestVar('tb_id'));
261 $tb_id = intRequestVar('tb_id');
262 $isAcceptPing = $this->isAcceptTrackBack($tb_id);
265 $this->showManualPingForm($tb_id);
267 echo 'Sorry, no trackback pings are accepted.';
274 $this->getURIfromLink(html_entity_decode(requestVar('tb_link')));
276 $url = addslashes($url);
277 $url = $this->_utf8_to_javascript($url);
279 $title = addslashes($title);
280 $title = $this->_utf8_to_javascript($title);
282 echo "tbDone('" . requestVar('tb_link') . "', '" . $url . "', '" . $title . "');";
288 return $this->redirect(intRequestVar('tb_id'), requestVar('urlHash'));
292 echo $this->showLeftList(intRequestVar('tb_id'), intRequestVar('amount'));
295 // delete a trackback(local)
297 $err = $this->deleteLocal(intRequestVar('tb_id'), intRequestVar('from_id'));
300 header('Location: ' . serverVar('HTTP_REFERER'));
307 function doIf($key = '', $value = '')
310 //echo "key: $key, value: $value";
312 switch( strtolower($key) ){
315 if( $value == '' ) $value = 'yes';
316 $value = ( $value == 'no' || (! $value) ) ? false : true;
320 $ret = $this->isAcceptTrackBack($itemid);
322 $ret = $this->isAcceptTrackBack();
323 return ( $value == false ) ? (! $ret) : $ret;
326 if( $value == '' ) $value = 'yes';
327 $value = ( $value == 'no' || (! $value) ) ? false : true;
331 $ret = $this->isEnableLinkCheck($itemid);
333 return ( $value == false ) ? (! $ret) : $ret;
340 /**************************************************************************************
345 * Show a list of left trackbacks for this ID
347 function showLeftList($tb_id, $offset = 0, $amount = 99999999) {
348 global $manager, $blog, $CONF;
358 UNIX_TIMESTAMP(timestamp) AS timestamp
360 '.sql_table('plugin_tb').'
362 tb_id = '.intval($tb_id).' AND
368 $query .= ' LIMIT '.intval($offset).', ' .intval($amount);
369 $res = mysql_query($query);
370 while ($row = mysql_fetch_array($res))
373 $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES);
374 $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES);
375 $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES);
376 if (_CHARSET != 'UTF-8') {
377 //modify start+++++++++
378 $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']);
379 $row['title'] = $this->_restore_to_utf8($row['title']);
380 $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']);
381 //modify end+++++++++
382 $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']);
383 $row['title'] = $this->_utf8_to_entities($row['title']);
384 $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']);
387 'action' => $this->getTrackBackUrl($tb_id),
388 'form' => $this->getManualPingUrl($tb_id),
389 'name' => $row['blog_name'],
390 'title' => $row['title'],
391 'excerpt' => $this->_cut_string($row['excerpt'], 400),
392 'url' => htmlspecialchars($row['url'], ENT_QUOTES),
393 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES)
397 if( $this->getOption('HideUrl') == 'yes' )
398 $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . $tb_id . '&urlHash=' . $row['urlHash'];
400 $iVars['url'] = $row['url'];
403 $out[] = TEMPLATE::fill($this->getOption('tplItem'), $iVars);
405 mysql_free_result($res);
407 return @join("\n",$out);
411 * Show a list of all trackbacks for this ID
413 function showList($tb_id, $amount = 0) {
414 $tb_id = intval($tb_id);
415 global $manager, $blog, $CONF, $member;
417 $enableHideurl = true;
420 strstr(serverVar('HTTP_USER_AGENT'),'Hatena Diary Track Forward Agent')
421 || strstr(serverVar('HTTP_USER_AGENT'),'NP_TrackBack')
422 || strstr(serverVar('HTTP_USER_AGENT'),'TBPingLinkLookup')
423 || strstr(serverVar('HTTP_USER_AGENT'),'MT::Plugin::BanNoReferTb')
424 || strstr(serverVar('HTTP_USER_AGENT'),'livedoorBlog')
426 $enableHideurl = false;
439 UNIX_TIMESTAMP(timestamp) AS timestamp
441 '.sql_table('plugin_tb').'
443 tb_id = '.$tb_id .' AND
456 UNIX_TIMESTAMP(timestamp) AS timestamp
458 '.sql_table('plugin_tb').'
460 tb_id = '.intval($tb_id) .' AND
465 if( $amount == '-1' )
466 $query .= ' LIMIT 9999999';
468 $query .= ' LIMIT '.intval($amount);
471 $res = mysql_query($query);
474 'action' => $this->getTrackBackUrl(intval($tb_id)),
475 'form' => $this->getManualPingUrl(intval($tb_id)),
476 'required' => $this->getRequiredURL(intval($tb_id)),
479 if ($member->isLoggedIn() && $member->isAdmin()){
480 $adminurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=list&id=' . intval($tb_id)), ENT_QUOTES);
481 $pingformurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id)), ENT_QUOTES);
482 $gVars['admin'] = '<a href="' . $adminurl . '" target="_blank">[admin]</a>';
483 $gVars['pingform'] = '<a href="' . $pingformurl . '" target="_blank">[pingform]</a>';
486 echo TEMPLATE::fill($this->getOption('tplHeader'), $gVars);
489 while ($amount != 0 && $row = mysql_fetch_array($res))
492 $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES);
493 $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES);
494 $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES);
498 if (_CHARSET != 'UTF-8') {
499 //modify start+++++++++
501 $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']);
502 $row['title'] = $this->_utf8_to_entities($row['title']);
503 $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']);
505 $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']);
506 $row['title'] = $this->_restore_to_utf8($row['title']);
507 $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']);
509 $row['blog_name'] = mb_convert_encoding($row['blog_name'], _CHARSET, 'UTF-8');
510 $row['title'] = mb_convert_encoding($row['title'], _CHARSET, 'UTF-8');
511 $row['excerpt'] = mb_convert_encoding($row['excerpt'], _CHARSET, 'UTF-8');
512 //modify end+++++++++
515 //modify start+++++++++
518 'action' => $this->getTrackBackUrl($tb_id),
519 'form' => $this->getManualPingUrl($tb_id),
520 'name' => $row['blog_name'],
521 'title' => $row['title'],
522 'excerpt' => $row['excerpt'],
523 'url' => htmlspecialchars($row['url'], ENT_QUOTES),
524 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp'] + ($blog->getTimeOffset() * 3600)), ENT_QUOTES)
528 'action' => $this->getTrackBackUrl($tb_id),
529 'form' => $this->getManualPingUrl($tb_id),
530 'name' => htmlspecialchars($row['blog_name'], ENT_QUOTES),
531 'title' => htmlspecialchars($row['title'], ENT_QUOTES),
532 'excerpt' => htmlspecialchars($this->_cut_string($row['excerpt'], 400), ENT_QUOTES),
533 'url' => htmlspecialchars($row['url'], ENT_QUOTES),
534 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES)
538 if( $enableHideurl && $this->getOption('HideUrl') == 'yes' )
539 $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . intval($tb_id) . '&urlHash=' . $row['urlHash'];
541 $iVars['url'] = $row['url'];
544 //modify end+++++++++
545 echo TEMPLATE::fill($this->getOption('tplItem'), $iVars);
549 //modify start+++++++++
554 '.sql_table('plugin_tb').'
556 tb_id = '.intval($tb_id) .' AND
561 $result = mysql_query($q);
562 $total = mysql_result($result,0,0);
564 if($amount != -1 && $total > $amount){
565 $leftcount = $total - $amount;
567 echo '<script type="text/javascript" src="' . $this->getAdminURL() . 'detectlist.php?tb_id='.intval($tb_id).'&amount='.intval($amount).'"></script>';
571 <a name="restoftrackback" id="restoftrackback"></a>
572 <div id="tbshownavi"><a href="#restoftrackback" onclick="resttbStart(); return false;" id="tbshow">Show left <?php echo $leftcount;?> Trackbacks</a></div>
573 <div id="tbhidenavi" style="display: none;"><a href="#restoftrackback" onclick="hideresttb(); return false;">Hide <?php echo $leftcount;?> Trackbacks</a></div>
574 <div id="resttb"></div>
578 //modify end+++++++++
580 if (mysql_num_rows($res) == 0)
582 echo TEMPLATE::fill($this->getOption('tplEmpty'), $gVars);
584 mysql_free_result($res);
586 echo TEMPLATE::fill($this->getOption('tplFooter'), $gVars);
591 * Returns the TrackBack count for a TrackBack item
593 function getTrackBackCount($tb_id) {
594 return quickQuery('SELECT COUNT(*) as result FROM ' . sql_table('plugin_tb') . ' WHERE tb_id='.intval($tb_id).' AND block = 0');
598 * Returns the manual ping URL
600 function getManualPingUrl($itemid) {
602 return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=form&tb_id='.$itemid;
606 * Show the manual ping form
608 function showManualPingError($itemid, $status = '') {
611 $form = true; $error = true; $success = false;
612 sendContentType('text/html', 'admin-trackback', _CHARSET);
613 //modify start+++++++++
614 // include ($this->getDirectory() . '/templates/form.html');
615 require_once($this->getDirectory() . '/template.php');
616 $mTemplate = new Trackback_Template(null, $this->getDirectory());
617 $mTemplate->set ('CONF', $CONF);
618 $mTemplate->set ('itemid', $itemid);
619 $mTemplate->set ('form', $form);
620 $mTemplate->set ('error', $error);
621 $mTemplate->set ('success', $success);
622 $mTemplate->set ('status', $status);
623 $mTemplate->template('templates/form.html');
624 echo $mTemplate->fetch();
625 //modify end+++++++++
628 function showManualPingSuccess($itemid, $status = '') {
631 $form = false; $error = false; $success = true;
632 sendContentType('text/html', 'admin-trackback', _CHARSET);
633 //modify start+++++++++
634 //include ($this->getDirectory() . '/templates/form.html');
635 require_once($this->getDirectory() . '/template.php');
636 $mTemplate = new Trackback_Template(null, $this->getDirectory());
637 $mTemplate->set ('CONF', $CONF);
638 $mTemplate->set ('itemid', $itemid);
639 $mTemplate->set ('form', $form);
640 $mTemplate->set ('error', $error);
641 $mTemplate->set ('success', $success);
642 $mTemplate->set ('status', $status);
643 $mTemplate->template('templates/form.html');
644 echo $mTemplate->fetch();
645 //modify end+++++++++
648 function showManualPingForm($itemid, $text = '') {
651 $form = true; $error = false; $success = false;
653 // Check if we are allowed to accept pings
654 if ( !$this->isAcceptTrackBack($itemid) ) {
655 $text = 'Sorry, no trackback pings are accepted';
656 $form = false; $error = true;
659 sendContentType('text/html', 'admin-trackback', _CHARSET);
660 //modify start+++++++++
661 //include ($this->getDirectory() . '/templates/form.html');
662 require_once($this->getDirectory() . '/template.php');
663 $mTemplate = new Trackback_Template(null, $this->getDirectory());
664 $mTemplate->set ('CONF', $CONF);
665 $mTemplate->set ('itemid', $itemid);
666 $mTemplate->set ('form', $form);
667 $mTemplate->set ('error', $error);
668 $mTemplate->set ('success', $success);
669 $mTemplate->set ('status', $status);
670 $mTemplate->template('templates/form.html');
671 echo $mTemplate->fetch();
672 //modify end+++++++++
676 * Returns the trackback URL
678 function getTrackBackUrl($itemid) {
679 global $CONF, $manager;
680 return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&tb_id='.$itemid;
684 * Insert RDF code for item
686 function insertCode($itemid) {
687 $itemid = intval($itemid);
688 global $manager, $CONF;
690 $item = & $manager->getItem($itemid, 0, 0);
691 $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
694 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
695 $uri = createItemLink($item['itemid'],'');
697 $uri = $this->_createItemLink($item['itemid'],$blog);
699 $title = strip_tags($item['title']);
700 $desc = strip_tags($item['body']);
701 $desc = $this->_cut_string($desc, 200);
702 $desc = htmlspecialchars($desc, ENT_QUOTES);
706 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
707 xmlns:dc="http://purl.org/dc/elements/1.1/"
708 xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
710 rdf:about="<?php echo $uri; ?>"
711 dc:identifier="<?php echo $uri; ?>"
712 dc:title="<?php echo $title; ?>"
713 dc:description="<?php echo $desc; ?>"
714 trackback:ping="<?php echo $this->getTrackBackUrl($itemid)?>"
715 dc:date="<?php echo strftime('%Y-%m-%dT%H:%M:%S')?>" />
722 * Retrieving TrackBack Pings (when __mode=rss)
724 function rssResponse($tb_id) {
725 $itemid = intval($itemid);
726 global $manager, $CONF;
727 $item =& $manager->getItem($tb_id, 0, 0);
731 $blog =& $manager->getBlog(getBlogIDFromItemID($item['itemid']));
733 $blog_name = $blog->getName();
734 $title = $item['title'];
735 $excerpt = $item['body'];
737 //modify start+++++++++
739 if (_CHARSET != 'UTF-8')
741 $title = $this->_convert_to_utf8($title, $encoding);
742 $excerpt = $this->_convert_to_utf8($excerpt, $encoding);
743 $blog_name = $this->_convert_to_utf8($blog_name, $encoding);
746 $title = $this->_decode_entities(strip_tags($title));
747 $excerpt = $this->_decode_entities(strip_tags($excerpt));
748 $blog_name = $this->_decode_entities(strip_tags($blog_name));
751 $title = $this->_restore_to_utf8($title);
752 $excerpt = $this->_restore_to_utf8($excerpt);
753 $blog_name = $this->_restore_to_utf8($blog_name);
754 //modify end+++++++++
756 $excerpt = $this->_cut_string($excerpt, 200);
759 //modify start+++++++++
761 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
762 $url = createItemLink($item['itemid'],'');
764 $url = $this->_createItemLink($item['itemid'],$blog);
765 //modify end+++++++++
767 // Use UTF-8 charset for output
768 header('Content-Type: text/xml');
769 echo "<","?xml version='1.0' encoding='UTF-8'?",">\n";
772 echo "\t<error>0</error>\n";
773 echo "\t<rss version='0.91'>\n";
774 echo "\t\t<channel>\n";
775 echo "\t\t\t<title>".htmlspecialchars($title, ENT_QUOTES)."</title>\n";
776 echo "\t\t\t<link>".htmlspecialchars($url, ENT_QUOTES)."</link>\n";
777 echo "\t\t\t<description>".htmlspecialchars($excerpt, ENT_QUOTES)."</description>\n";
779 $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';
780 $res = mysql_query($query);
781 while ($o = mysql_fetch_object($res))
783 // No need to do conversion, because it is already UTF-8
785 'url' => htmlspecialchars($o->url, ENT_QUOTES),
786 'blogname' => htmlspecialchars($this->_restore_to_utf8($o->blog_name), ENT_QUOTES),
787 'timestamp' => strftime('%Y-%m-%d',$o->timestamp),
788 'title' => htmlspecialchars($this->_restore_to_utf8($o->title), ENT_QUOTES),
789 'excerpt' => htmlspecialchars($this->_restore_to_utf8($o->excerpt), ENT_QUOTES),
790 'tburl' => $this->getTrackBackUrl($tb_id)
794 echo "\t\t\t<item>\n";
795 echo "\t\t\t\t<title>".$data['title']."</title>\n";
796 echo "\t\t\t\t<link>".$data['url']."</link>\n";
797 echo "\t\t\t\t<description>".$data['excerpt']."</description>\n";
798 echo "\t\t\t</item>\n";
800 echo "\t\t</channel>\n";
807 $this->xmlResponse(_ERROR_NOSUCHITEM);
814 /**************************************************************************************
815 * SENDING AND RECEIVING TRACKBACK PINGS
819 * Send a Trackback ping to another website
821 function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url, $utf8flag=0)
823 $tempEncording = ($utf8flag)? 'UTF-8': _CHARSET;
825 // 1. Check some basic things
826 if (!$this->canSendPing()) {
827 return 'You\'re not allowed to send pings';
830 if ($this->getOption('SendPings') == 'no') {
831 return 'Sending trackback pings is disabled';
834 if ($ping_url == '') {
835 return 'No ping URL';
838 // 2. Check if protocol is correct http URL
839 $parsed_url = parse_url($ping_url);
841 if ($parsed_url['scheme'] != 'http' || $parsed_url['host'] == '')
842 return 'Bad ping URL';
844 $port = ($parsed_url['port']) ? $parsed_url['port'] : 80;
846 // 3. Create contents
847 if($tempEncording != _CHARSET){
848 $title = mb_convert_encoding($title, $tempEncording, _CHARSET);
849 $excerpt = mb_convert_encoding($excerpt, $tempEncording, _CHARSET);
850 $blog_name = mb_convert_encoding($blog_name, $tempEncording, _CHARSET);
854 $content = 'title=' . urlencode( $title );
855 $content .= '&url=' . urlencode( $url );
856 $content .= '&excerpt=' . urlencode( $excerpt );
857 $content .= '&blog_name=' . urlencode( $blog_name );
859 # $user_agent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)';
860 $user_agent = 'NP_TrackBack/'. $this->getVersion();
862 // 4. Prepare HTTP request
863 $request = 'POST ' . $parsed_url['path'];
865 if ($parsed_url['query'] != '')
866 $request .= '?' . $parsed_url['query'];
868 $request .= " HTTP/1.1\r\n";
869 $request .= "Accept: */*\r\n";
870 $request .= "User-Agent: " . $user_agent . "\r\n";
871 $request .= ( $port == 80 )?
872 "Host: " . $parsed_url['host'] . "\r\n":
873 "Host: " . $parsed_url['host'] . ":" . $port . "\r\n";
874 $request .= "Connection: Keep-Alive\r\n";
875 $request .= "Cache-Control: no-cache\r\n";
876 $request .= "Connection: Close\r\n";
877 $request .= "Content-Length: " . strlen( $content ) . "\r\n";
878 $request .= ($utf8flag)?
879 "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n":
880 "Content-Type: application/x-www-form-urlencoded; charset="._CHARSET."\r\n";
882 $request .= $content;
884 $socket = fsockopen( $parsed_url['host'], $port, $errno, $errstr );
886 return 'Could not send ping: '.$errstr.' ('.$errno.')';
888 // 5. Execute HTTP request
889 fputs($socket, $request);
891 // 6. Receive response
893 while (!feof($socket)) {
894 $result .= fgets($socket, 4096);
899 // instead of parsing the XML, just check for the error string
900 // [TODO] extract real error message and return that
901 //modify start+++++++++
903 $DATA = split("\r\n\r\n", $result, 2);
904 preg_match("/HTTP\/1\.[0-1] ([0-9]+) ([^\r\n]*)\r?\n/",$DATA[0],$httpresp);
905 $respCd = $httpresp[1];
906 $respMsg = $httpresp[2];
908 if( $respCd != 200 ){
909 return 'An error occurred: HTTP Error: [' . $respCd . '] ' . $respMsg;
911 if ( strstr($DATA[1],'<error>0</error>') === false ){
912 preg_match("/<message>(.*?)<\/message>/",$DATA[1],$error_message);
913 if( $error_message[1] )
914 return 'An error occurred: '.htmlspecialchars($error_message[1], ENT_QUOTES);
916 return 'An error occurred: fatal error.';
919 //modify end+++++++++
922 * Handle a Trackback ping sent to this website
924 function handlePing($tb_id = 0) {
930 //modify start+++++++++
933 //modify end+++++++++
935 $tb_id = intRequestVar('tb_id');
937 $rss = requestVar('__mode') == 'rss';
939 $enableLinkCheck = $this->isEnableLinkCheck($tb_id);
940 $block = ( $enableLinkCheck ) ? true : false ;
944 return 'TrackBack ID is missing (tb_id)';
947 if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes')) {
948 return _ERROR_NOSUCHITEM;
951 // 0. Check if we need to output the list as rss
953 $this->rssResponse($tb_id);
957 // check: accept pings.
958 $blogId = getBlogIDFromItemID($tb_id);
959 $isAcceptPing = $this->isAcceptTrackBack($tb_id);
962 return 'Sorry, no trackback pings are accepted.';
966 //modify start+++++++++
967 $b =& $manager->getBlog($blogId);
968 //modify end+++++++++
969 $url = requestVar('url');
970 $title = requestVar('title');
971 $excerpt = requestVar('excerpt');
972 $blog_name = requestVar('blog_name');
974 if( $url && preg_match('/https?:\/\/([^\/]+)/', $url, $matches) ){
975 if( gethostbynamel($matches[1]) === FALSE )
976 return 'URL is invalid (url)';
978 return 'URL is missing or invalid (url)';
981 // 2. Conversion of encoding...
982 //modify start+++++++++
983 /* if (preg_match ("/;\s*charset=([^\n]+)/is", $_SERVER["CONTENT_TYPE"], $regs))
984 $encoding = strtoupper(trim($regs[1]));
986 $encoding = $this->_detect_encoding($excerpt);
988 $encoding = $this->_detect_encoding($excerpt);
989 //modify end+++++++++
991 //modify start+++++++++
992 if (_CHARSET != 'UTF-8'){
993 $title = $this->_strip_controlchar(strip_tags(mb_convert_encoding($title, _CHARSET, $encoding)));
994 $excerpt = $this->_strip_controlchar(strip_tags(mb_convert_encoding($excerpt, _CHARSET, $encoding)));
995 $blog_name = $this->_strip_controlchar(strip_tags(mb_convert_encoding($blog_name, _CHARSET, $encoding)));
997 $title = $this->_strip_controlchar($this->_convert_to_utf8($title, $encoding));
998 $excerpt = $this->_strip_controlchar($this->_convert_to_utf8($excerpt, $encoding));
999 $blog_name = $this->_strip_controlchar($this->_convert_to_utf8($blog_name, $encoding));
1001 $title = $this->_decode_entities(strip_tags($title));
1002 $excerpt = $this->_decode_entities(strip_tags($excerpt));
1003 $blog_name = $this->_decode_entities(strip_tags($blog_name));
1005 //modify end+++++++++
1007 // 4. Save data in the DB
1008 $res = @mysql_query('
1012 '.sql_table('plugin_tb').'
1014 url = \''.mysql_real_escape_string($url).'\' AND
1015 tb_id = \''.intval($tb_id).'\'
1018 if (mysql_num_rows($res) != 0)
1020 // Existing TB, update it
1022 $res = @mysql_query('
1024 '.sql_table('plugin_tb').'
1026 title = "'.mysql_real_escape_string($title).'",
1027 excerpt = "'.mysql_real_escape_string($excerpt).'",
1028 blog_name = "'.mysql_real_escape_string($blog_name).'",
1029 timestamp = '.mysqldate(time()).'
1031 url = "'.mysql_real_escape_string($url).'" AND
1032 tb_id = "'.$tb_id.'"
1035 //modify start+++++++++
1036 $rows = mysql_fetch_assoc($res);
1037 $spam = ( $rows['block'] || $rows['spam'] ) ? true : false;
1038 $res = @mysql_query('
1040 '.sql_table('plugin_tb').'
1042 title = \''.mysql_real_escape_string($title).'\',
1043 excerpt = \''.mysql_real_escape_string($excerpt).'\',
1044 blog_name = \''.mysql_real_escape_string($blog_name).'\',
1045 timestamp = '.mysqldate($b->getCorrectTime()).'
1047 url = \''.mysql_real_escape_string($url).'\' AND
1048 tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\'
1050 //modify end+++++++++
1053 return 'Could not update trackback data: '.mysql_error();
1058 // 4. SPAM check (for SpamCheck API 2 /w compat. API 1)
1059 $spamcheck = array (
1060 'type' => 'trackback',
1063 'excerpt' => $excerpt,
1064 'blogname' => $blog_name,
1069 /* Backwards compatibility with SpamCheck API 1*/
1070 'data' => $url . "\n" . $title . "\n" . $excerpt . "\n" . $blog_name . "\n" . serverVar('HTTP_USER_AGENT'),
1074 $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
1076 if (isset($spamcheck['result']) && $spamcheck['result'] == true)
1081 // 5. Content check (TO DO)
1082 if($spam == false || $enableLinkCheck == 'ignore' ) //modify
1085 // $contents = $this->retrieveUrl ($url);
1087 // if (preg_match("/(".preg_quote($_SERVER["REQUEST_URI"], '/').")|(".preg_quote($_SERVER["SERVER_NAME"], '/').")/i", $contents)) {
1090 if( $enableLinkCheck ){
1091 $contents = $this->retrieveUrl($url);
1093 $linkArray = $this->getPermaLinksFromText($contents);
1094 $itemLink = $this->_createItemLink($tb_id, $b);
1095 $itemLinkPat = '{^' . preg_quote($itemLink) .'}i';
1096 $itemLinkPat = str_replace('&','&(amp;)?', $itemLinkPat);
1098 foreach($linkArray as $l) {
1099 if(preg_match($itemLinkPat, $l)){
1100 ACTIONLOG :: add(INFO, "Trackback: LinkCheck OK. (link: $l pat: $itemLinkPat )");
1106 $cnt = @count($linkArray);
1107 if( $enableLinkCheck == 'ignore' ){
1108 ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [ignore] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat)");
1109 return 'Sorry, trackback ping is not accepted.';
1111 ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [block] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat");
1118 // 6. Determine if Trackback is safe...
1119 //modify start+++++++++
1120 // $block = $spam == true || $link == false;
1121 // $block = $spam == true ;
1122 //modify end+++++++++
1124 if ( $enableLinkCheck )
1125 $block = ($spam == true || $link == false);
1127 $block = $spam == true ;
1129 // New TB, insert it
1133 '.sql_table('plugin_tb').'
1135 tb_id = "'.$tb_id.'",
1136 block = "'.($block ? '1' : '0').'",
1137 spam = "'.($spam ? '1' : '0').'",
1138 link = "'.($link ? '1' : '0').'",
1139 url = "'.mysql_real_escape_string($url).'",
1140 title = "'.mysql_real_escape_string($title).'",
1141 excerpt = "'.mysql_real_escape_string($excerpt).'",
1142 blog_name = "'.mysql_real_escape_string($blog_name).'",
1143 timestamp = '.mysqldate(time()).'
1146 //modify start+++++++++
1149 '.sql_table('plugin_tb').'
1151 tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\',
1152 block = \''.($block ? '1' : '0').'\',
1153 spam = \''.($spam ? '1' : '0').'\',
1154 link = \''.($link ? '1' : '0').'\',
1155 url = \''.mysql_real_escape_string($url).'\',
1156 title = \''.mysql_real_escape_string($title).'\',
1157 excerpt = \''.mysql_real_escape_string($excerpt).'\',
1158 blog_name = \''.mysql_real_escape_string($blog_name).'\',
1159 timestamp = '.mysqldate($b->getCorrectTime()).'
1161 //modify end+++++++++
1163 $res = @mysql_query($query);
1166 return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error() . $query;
1170 // 7. Send notification e-mail if needed
1171 $notifyAddrs = $this->getOption('NotifyEmail');
1172 $notifyAddrs = ( $notifyAddrs ? $notifyAddrs . ';' : '')
1173 . $this->getBlogOption($blogId ,'NotifyEmailBlog');
1175 if ($notifyAddrs && $spam == false)
1182 'excerpt' => $excerpt,
1183 'blogname' => $blog_name
1186 //modify start+++++++++
1191 'title' => mb_convert_encoding($title, 'ISO-2022-JP', _CHARSET),
1192 'excerpt' => mb_convert_encoding($excerpt, 'ISO-2022-JP', _CHARSET),
1193 'blogname' => mb_convert_encoding($blog_name, 'ISO-2022-JP', _CHARSET)
1196 //maybe not needed because japanese version has "mb_send_mail" in function notify
1197 //modify end+++++++++
1199 $mailto_title = TEMPLATE::fill($this->notificationMailTitle, $vars);
1200 $mailto_msg = TEMPLATE::fill($this->notificationMail, $vars);
1202 global $CONF, $DIR_LIBS;
1204 // make sure notification class is loaded
1205 if (!class_exists('notification'))
1206 include($DIR_LIBS . 'NOTIFICATION.php');
1208 $notify = new NOTIFICATION($notifyAddrs);
1209 $notify->notify($mailto_title, $mailto_msg , $CONF['AdminEmail']);
1211 //mod by cles+++++++++++
1212 if ($manager->pluginInstalled('NP_Cache')){
1213 $p =& $manager->getPlugin('NP_Cache');
1214 $p->setCurrentBlog($tb_id);
1215 $p->cleanItem($tb_id);
1216 $p->cleanArray(array('index'));
1218 //mod by cles end +++++++++++
1222 return 'Sorry, trackback ping is not accepted.';
1226 function xmlResponse($errorMessage = '')
1228 header('Content-Type: text/xml');
1230 echo "<","?xml version='1.0' encoding='UTF-8'?",">\n";
1231 echo "<response>\n";
1234 echo "\t<error>1</error>\n\t<message>",htmlspecialchars($errorMessage, ENT_QUOTES),"</message>\n";
1236 echo "\t<error>0</error>\n";
1243 * Check if member may send ping (check if logged in)
1245 function canSendPing() {
1247 return $member->isLoggedIn() || $this->xmlrpc;
1252 function redirect($tb_id, $urlHash){
1254 $query = 'SELECT url FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' and md5(url)="'.$urlHash.'"';
1255 $res = mysql_query($query);
1257 $url = $CONF['SiteURL'];
1259 if ($o = mysql_fetch_object($res)) {
1260 $url = htmlspecialchars($o->url, ENT_QUOTES);
1263 $url = stripslashes($url);
1264 $url = str_replace('&','&',$url);
1265 $url = str_replace('<','<',$url);
1266 $url = str_replace('>','>',$url);
1267 $url = str_replace('"','"',$url);
1269 header('Location: '.$url);
1272 function getRequiredURL($itemid){
1274 $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
1275 if( $this->isEnableLinkCheck($itemid) )
1276 return $this->_createItemLink($itemid, $blog);
1280 function isEnableLinkCheck($itemid){
1281 $blogid = getBlogIDFromItemID($itemid);
1283 switch( $this->getItemOption($itemid, 'isAcceptW/OLink') ){
1285 $def = $this->getBlogOption($blogid, 'isAcceptW/OLinkDef');
1289 return $def; // block or ignore
1295 ACTIONLOG :: add(INFO, "Trackback: Unknown Option (itemid:$itemid, value:$val)");
1300 var $acceptTrackbacks = array();
1301 function isAcceptTrackBack($itemid = null){
1302 if( $itemid && isset($acceptTrackbacks[$itemid]) )
1303 return $acceptTrackbacks[$itemid] === true;
1306 if( $this->getOption('AcceptPing') == 'yes' ){
1309 $bid = getBlogIDFromItemID(intval($itemid));
1312 $bid = $blog->getID();
1315 if( $this->getBlogOption($bid, "AllowTrackBack") == 'yes' ){
1317 $ret = ( $this->getItemOption(intval($itemid), 'ItemAcceptPing') == 'yes' ) ? true : false ;
1326 $acceptTrackbacks[$itemid] = $ret;
1327 return $ret === true;
1332 /**************************************************************************************
1336 function event_SendTrackback($data) {
1339 // Enable sending trackbacks for the XML-RPC API, otherwise we would
1340 // get an error because the current user is not exactly logged in.
1341 $this->xmlrpc = true;
1343 $itemid = $data['tb_id'];
1344 $item = &$manager->getItem($itemid, 0, 0);
1345 if (!$item) return; // don't ping for draft & future
1346 if ($item['draft']) return; // don't ping on draft items
1348 // gather some more information, needed to send the ping (blog name, etc)
1349 $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
1350 $blog_name = $blog->getName();
1352 $title = $data['title'] != '' ? $data['title'] : $item['title'];
1353 $title = strip_tags($title);
1355 $excerpt = $data['body'] != '' ? $data['body'] : $item['body'];
1356 $excerpt = strip_tags($excerpt);
1357 $excerpt = $this->_cut_string($excerpt, 200);
1359 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
1360 //$url = createItemLink($itemid);
1361 $url = $this->_createItemLink($itemid, $blog);
1363 while (list(,$url) = each($data['urls'])) {
1364 $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $url);
1365 if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $url . ')');
1369 function event_RetrieveTrackback($data) {
1371 $res = mysql_query('
1375 UNIX_TIMESTAMP(timestamp) AS timestamp
1377 '.sql_table('plugin_tb').'
1379 tb_id = '.intval($data['tb_id']).' AND
1385 while ($row = mysql_fetch_array($res)) {
1388 'title' => $row['title'],
1389 'url' => $row['url'],
1393 $data['trackbacks'][] = $trackback;
1397 function event_BookmarkletExtraHead($data) {
1399 list ($NP_TB_URL,) = $this->getURIfromLink(requestVar('loglink'));
1402 function event_PrepareItemForEdit($data) {
1403 // if (!$this->getOption('AutoXMLHttp'))
1404 if ($this->getOption('AutoXMLHttp') == 'no')
1406 // The space between body and more is to make sure we didn't join 2 words accidently....
1407 $this->larray = $this->autoDiscovery($data['item']['body'].' '.$data['item']['more']);
1412 * After an item has been added to the database, send out a ping if requested
1413 * (trackback_ping_url variable in request)
1415 function event_PostAddItem($data) {
1416 $this->pingTrackback($data);
1419 function event_PreUpdateItem($data) {
1420 $this->pingTrackback($data);
1424 * Add trackback options to add item form/bookmarklet
1426 function event_AddItemFormExtras($data) {
1428 // global $NP_TB_URL;
1433 <!--modify start+++++++++-->
1434 <!-- <label for="plug_tb_url">TrackBack Ping URL:</label>
1435 <input type="text" value="<?php if (isSet($NP_TB_URL)) {echo $NP_TB_URL;} ?>" id="plug_tb_url" name="trackback_ping_url" size="60" />
1437 <!--modify end+++++++++-->
1438 <label for="plug_tb_url">TrackBack URL:</label><br />
1439 <textarea id="plug_tb_url" name="trackback_ping_url" cols="60" rows="5" style="font:normal xx-small Tahoma, Arial, verdana ;"></textarea>
1440 <input type="button" name="btnAdd" value="<?php echo _TB_LIST_IT?>" onClick="AddStart()" />
1445 // if ($this->getOption('AutoXMLHttp'))
1446 if ($this->getOption('AutoXMLHttp') == 'yes')
1450 <input type="button" name="discoverit" value="Auto Discover" onclick="tbSetup();" />
1451 <img id='tb_busy' src='<?php echo $this->getAdminURL(); ?>busy.gif' style="display:none;" /><br />
1452 <div id="tb_auto_title"></div>
1453 <table border="1"><tbody id="tb_ping_list"></tbody></table>
1454 <input type="hidden" id="tb_url_amount" name="tb_url_amount" value="0" />
1458 $this->jsautodiscovery();
1466 * Add trackback options to edit item form/bookmarklet
1468 function event_EditItemFormExtras($data) {
1471 <!-- <input type="text" value="" id="plug_tb_url" name="trackback_ping_url" size="60" /><br />-->
1474 <label for="plug_tb_url">TrackBack URL:</label><br />
1475 <textarea id="plug_tb_url" name="trackback_ping_url" cols="60" rows="5" style="font:normal xx-small Tahoma, Arial, verdana ;"></textarea>
1476 <input type="button" name="btnAdd" value="<?php echo _TB_LIST_IT?>" onClick="AddStart()" />
1479 // if ($this->getOption('AutoXMLHttp'))
1480 if ($this->getOption('AutoXMLHttp') == 'yes')
1486 <input type="button" name="discoverit" value="Auto Discover" onclick="tbSetup();" />
1487 <img id='tb_busy' src='<?php echo $this->getAdminURL(); ?>busy.gif' style="display:none;" /><br />
1488 <div id="tb_auto_title"></div>
1489 <table border="1"><tbody id="tb_ping_list"></tbody></table>
1490 <input type="hidden" id="tb_url_amount" name="tb_url_amount" value="0" />
1494 $this->jsautodiscovery();
1498 if (count($this->larray) > 0)
1501 Auto Discovered Ping URL's:<br />
1503 echo '<input type="hidden" name="tb_url_amount" value="'.count($this->larray).'" />';
1507 while (list($url, $title) = each ($this->larray))
1509 //modify start+++++++++
1510 if (_CHARSET != 'UTF-8') {
1511 $title = $this->_utf8_to_entities($title);
1512 $title = mb_convert_encoding($title, _CHARSET, 'UTF-8');
1514 //modify end+++++++++
1516 echo '<input type="checkbox" name="tb_url_'.$i.
1517 '" value="'.$url.'" id="tb_url_'.$i.
1518 '" /><label for="tb_url_'.$i.'" title="'.$url.'">'.$title.'</label><br />';
1530 * Insert Javascript AutoDiscovery routines
1532 function jsautodiscovery()
1537 <script type='text/javascript' src='<?php echo $this->getAdminURL(); ?>autodetect.php'></script>
1544 function pingTrackback($data) {
1545 global $manager, $CONF;
1547 $ping_urls_count = 0;
1548 $ping_urls = array();
1549 $utf8flag = array();
1550 $localflag = array();
1552 $ping_url = requestVar('trackback_ping_url');
1553 //modify start+++++++++
1556 $ping_urls[0] = $ping_url;
1560 if (trim($ping_url)) {
1561 $ping_urlsTemp = array();
1562 $ping_urlsTemp = preg_split("/[\s,]+/", trim($ping_url));
1563 for($i=0;$i<count($ping_urlsTemp);$i++){
1564 $ping_urls[] = trim($ping_urlsTemp[$i]);
1568 //modify end+++++++++
1570 $tb_url_amount = requestVar('tb_url_amount');
1571 for ($i=0;$i<$tb_url_amount;$i++) {
1572 $tb_temp_url = requestVar('tb_url_'.$i);
1574 $ping_urls[$ping_urls_count] = $tb_temp_url;
1575 $utf8flag[$ping_urls_count] = (requestVar('tb_url_'.$i.'_utf8') == 'on')? 1: 0;
1576 $localflag[$ping_urls_count] = (requestVar('tb_url_'.$i.'_local') == 'on')? 1: 0;
1581 if ($ping_urls_count <= 0) {
1585 $itemid = $data['itemid'];
1586 $item = &$manager->getItem($itemid, 0, 0);
1587 if (!$item) return; // don't ping for draft & future
1588 if ($item['draft']) return; // don't ping on draft items
1590 // gather some more information, needed to send the ping (blog name, etc)
1591 $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
1592 $blog_name = $blog->getName();
1594 $title = $data['title'] != '' ? $data['title'] : $item['title'];
1595 $title = strip_tags($title);
1597 $excerpt = $data['body'] != '' ? $data['body'] : $item['body'];
1598 $excerpt = strip_tags($excerpt);
1599 $excerpt = $this->_cut_string($excerpt, 200);
1602 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
1603 $url = createItemLink($itemid);
1605 $url = $this->_createItemLink($item['itemid'],$blog);
1607 // send the ping(s) (add errors to actionlog)
1608 for ($i=0; $i<count($ping_urls); $i++) {
1609 if( ! $localflag[$i] )
1610 $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_urls[$i], $utf8flag[$i]);
1612 $res = $this->handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_urls[$i]);
1613 if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $ping_urls[$i] . ')');
1620 /**************************************************************************************
1625 * Auto-Discovery of TrackBack Ping URLs based on HTML story
1627 function autoDiscovery($text)
1629 $links = $this->getPermaLinksFromText($text);
1632 for ($i = 0; $i < count($links); $i++)
1634 list ($url, $title) = $this->getURIfromLink($links[$i]);
1637 $result[$url] = $title;
1644 * Auto-Discovery of TrackBack Ping URLs based on single link
1646 function getURIfromLink($link)
1649 // Check to see if the cache contains this link
1650 $res = mysql_query('SELECT url, title FROM '.sql_table('plugin_tb_lookup').' WHERE link=\''.mysql_real_escape_string($link).'\'');
1652 if ($row = mysql_fetch_array($res))
1654 if ($row['title'] != '')
1656 //modify start+++++++++
1657 if (_CHARSET != 'UTF-8'){
1658 $row['title'] = mb_convert_encoding($row['title'], 'UTF-8', _CHARSET);
1659 $row['title'] = $this->_decode_entities($row['title']);
1661 //modify end+++++++++
1663 $row['url'], $row['title']
1669 $row['url'], $row['url']
1675 if (($rdf = $this->getRDFFromLink($link)) !== false)
1677 // Get PING attribute
1678 if (($uri = $this->getAttributeFromRDF($rdf, 'trackback:ping')) !== false)
1680 // Get TITLE attribute
1681 if (($title = $this->getAttributeFromRDF($rdf, 'dc:title')) !== false)
1683 // Get CREATOR attribute
1684 if (($author = $this->getAttributeFromRDF($rdf, 'dc:creator')) !== false)
1686 $title = $author. ": " . $title;
1689 $uri = $this->_decode_entities($uri);
1690 //modify start+++++++++
1691 if (_CHARSET != 'UTF-8')
1692 $convertedTitle = mb_convert_encoding($title, _CHARSET, 'UTF-8');
1694 $convertedTitle = $title;
1697 $res = mysql_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)."')");
1700 $res = mysql_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)."')");
1701 //modify end+++++++++
1702 $title = $this->_decode_entities($title);
1710 $uri = html_entity_decode($uri, ENT_COMPAT);
1713 $res = mysql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','')");
1723 $res = mysql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','','')");
1725 return array ('', '');
1729 * Detect links used in HTML code
1731 function getPermaLinksFromText($text)
1735 if (preg_match_all('/<[aA] +([^>]+)>/', $text, $array, PREG_SET_ORDER))
1737 for ($i = 0; $i < count($array); $i++)
1739 //if( preg_match('/s?https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+/', $array[$i][1], $matches) )
1740 if( preg_match('/s?https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/:@&=+$,%]+/', $array[$i][1], $matches) )
1741 $links[$matches[0]] = 1;
1745 return array_keys($links);
1749 * Retrieve RDF code from external link
1751 function getRDFFromLink($link)
1753 if ($content = $this->getContents($link))
1755 preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $content, $rdfs, PREG_SET_ORDER);
1757 if (count($rdfs) > 1)
1759 for ($i = 0; $i < count($rdfs); $i++)
1761 if (preg_match('|dc:identifier="'.preg_quote($link).'"|ms',$rdfs[$i][1]))
1763 return $rdfs[$i][1];
1769 // No need to check the identifier
1778 * Retrieve the contents of an external (X)HTML document
1780 function getContents($link) {
1782 // Use cURL extention if available
1783 if (function_exists("curl_init") && $this->useCurl == 2)
1785 // Make HEAD request
1787 @curl_setopt($ch, CURLOPT_URL, $link);
1788 @curl_setopt($ch, CURLOPT_HEADER, true);
1789 @curl_setopt($ch, CURLOPT_NOBODY, true);
1790 @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
1791 @curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
1792 @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1793 @curl_setopt($ch, CURLOPT_TIMEOUT, 20);
1794 @curl_setopt($ch, CURLOPT_USERAGENT, 'NP_TrackBack/'. $this->getVersion());
1796 $headers = curl_exec($ch);
1799 // Check if the link points to a (X)HTML document
1800 if (preg_match('/Content-Type: (text\/html|application\/xhtml+xml)/i', $headers))
1802 return $this->retrieveUrl ($link);
1809 return $this->retrieveUrl ($link);
1814 * Get a single attribute from RDF
1816 function getAttributeFromRDF($rdf, $attribute)
1818 if (preg_match('/'.$attribute.'="([^"]+)"/', $rdf, $matches))
1831 /**************************************************************************************/
1832 /* Internal helper functions for dealing with external file retrieval */
1834 function retrieveUrl ($url) {
1836 $ua = ini_set('user_agent', 'NP_TrackBack/'. $this->getVersion());
1838 if (function_exists('curl_init') && $this->useCurl > 0)
1842 @curl_setopt($ch, CURLOPT_URL, $url);
1843 @curl_setopt($ch, CURLOPT_HEADER, 1);
1844 @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
1845 @curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
1846 @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
1847 @curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
1848 @curl_setopt($ch, CURLOPT_TIMEOUT, 20);
1849 @curl_setopt($ch, CURLOPT_USERAGENT, 'NP_TrackBack/'. $this->getVersion());
1851 // Retrieve response
1852 $raw = curl_exec($ch);
1853 $info = curl_getinfo($ch);
1855 // Split into headers and contents
1856 $headers = substr($raw, 0, $info['header_size']);
1857 $contents = substr($raw, $info['header_size']);
1861 elseif ($fp = @fopen ($url, "r"))
1864 // $contents = fread($fp, 8192);
1866 while (!feof($fp)) {
1867 $contents .= fread($fp, 8192);
1875 ini_set('user_agent', $ua);
1878 // Next normalize the encoding to UTF8...
1879 $contents = $this->_convert_to_utf8_auto($contents, $headers);
1885 /**************************************************************************************/
1886 /* Internal helper functions for dealing with encodings and entities */
1888 var $entities_cp1251 = array (
1889 '€' => '€',
1890 '‚' => '‚',
1891 'ƒ' => 'ƒ',
1892 '„' => '„',
1893 '…' => '…',
1894 '†' => '†',
1895 '‡' => '‡',
1896 'ˆ' => 'ˆ',
1897 '‰' => '‰',
1898 'Š' => 'Š',
1899 '‹' => '‹',
1900 'Œ' => 'Œ',
1901 'Ž' => 'Ž',
1902 '‘' => '‘',
1903 '’' => '’',
1904 '“' => '“',
1905 '”' => '”',
1906 '•' => '•',
1907 '–' => '–',
1908 '—' => '—',
1909 '˜' => '˜',
1910 '™' => '™',
1911 'š' => 'š',
1912 '›' => '›',
1913 'œ' => 'œ',
1914 'ž' => 'ž',
1915 'Ÿ' => 'Ÿ',
1918 var $entities_default = array (
1919 '"' => '"',
1921 ''' => ''',
1926 var $entities_latin = array (
1927 ' ' => ' ',
1928 '¡' => '¡',
1929 '¢' => '¢',
1930 '£' => '£',
1931 '¤' => '¤',
1932 '¥' => '¥',
1933 '¦' => '¦',
1934 '§' => '§',
1935 '¨' => '¨',
1936 '©' => '©',
1937 'ª' => 'ª',
1938 '«' => '«',
1939 '¬' => '¬',
1940 '­' => '­',
1941 '®' => '®',
1942 '¯' => '¯',
1943 '°' => '°',
1944 '±' => '±',
1945 '²' => '²',
1946 '³' => '³',
1947 '´' => '´',
1948 'µ' => 'µ',
1949 '¶' => '¶',
1950 '·' => '·',
1951 '¸' => '¸',
1952 '¹' => '¹',
1953 'º' => 'º',
1954 '»' => '»',
1955 '¼' => '¼',
1956 '½' => '½',
1957 '¾' => '¾',
1958 '¿' => '¿',
1959 'À' => 'À',
1960 'Á' => 'Á',
1961 'Â' => 'Â',
1962 'Ã' => 'Ã',
1963 'Ä' => 'Ä',
1964 'Å' => 'Å',
1965 'Æ' => 'Æ',
1966 'Ç' => 'Ç',
1967 'È' => 'È',
1968 'É' => 'É',
1969 'Ê' => 'Ê',
1970 'Ë' => 'Ë',
1971 'Ì' => 'Ì',
1972 'Í' => 'Í',
1973 'Î' => 'Î',
1974 'Ï' => 'Ï',
1975 'Ð' => 'Ð',
1976 'Ñ' => 'Ñ',
1977 'Ò' => 'Ò',
1978 'Ó' => 'Ó',
1979 'Ô' => 'Ô',
1980 'Õ' => 'Õ',
1981 'Ö' => 'Ö',
1982 '×' => '×',
1983 'Ø' => 'Ø',
1984 'Ù' => 'Ù',
1985 'Ú' => 'Ú',
1986 'Û' => 'Û',
1987 'Ü' => 'Ü',
1988 'Ý' => 'Ý',
1989 'Þ' => 'Þ',
1990 'ß' => 'ß',
1991 'à' => 'à',
1992 'á' => 'á',
1993 'â' => 'â',
1994 'ã' => 'ã',
1995 'ä' => 'ä',
1996 'å' => 'å',
1997 'æ' => 'æ',
1998 'ç' => 'ç',
1999 'è' => 'è',
2000 'é' => 'é',
2001 'ê' => 'ê',
2002 'ë' => 'ë',
2003 'ì' => 'ì',
2004 'í' => 'í',
2005 'î' => 'î',
2006 'ï' => 'ï',
2007 'ð' => 'ð',
2008 'ñ' => 'ñ',
2009 'ò' => 'ò',
2010 'ó' => 'ó',
2011 'ô' => 'ô',
2012 'õ' => 'õ',
2013 'ö' => 'ö',
2014 '÷' => '÷',
2015 'ø' => 'ø',
2016 'ù' => 'ù',
2017 'ú' => 'ú',
2018 'û' => 'û',
2019 'ü' => 'ü',
2020 'ý' => 'ý',
2021 'þ' => 'þ',
2022 'ÿ' => 'ÿ',
2025 var $entities_extended = array (
2026 'Œ' => 'Œ',
2027 'œ' => 'å',
2028 'Š' => 'Š',
2029 'š' => 'š',
2030 'Ÿ' => 'Ÿ',
2031 'ˆ' => 'ˆ',
2032 '˜' => '˜',
2033 '&esnp;' => ' ',
2034 ' ' => ' ',
2035 ' ' => ' ',
2036 '‌' => '‌',
2037 '‍' => '‍',
2038 '‎' => '‎',
2039 '‏' => '‏',
2040 '–' => '–',
2041 '—' => '—',
2042 '‘' => '‘',
2043 '’' => '’',
2044 '‚' => '‚',
2045 '“' => '“',
2046 '”' => '”',
2047 '„' => '„',
2048 '†' => '†',
2049 '‡' => '‡',
2050 '‰' => '‰',
2051 '‹' => '‹',
2052 '›' => '›',
2053 '€' => '€',
2054 'ƒ' => 'ƒ',
2055 'Α' => 'Α',
2056 'Β' => 'Β',
2057 'Γ' => 'Γ',
2058 'Δ' => 'Δ',
2059 'Ε' => 'Ε',
2060 'Ζ' => 'Ζ',
2061 'Η' => 'Η',
2062 'Θ' => 'Θ',
2063 'Ι' => 'Ι',
2064 'Κ' => 'Κ',
2065 'Λ' => 'Λ',
2069 'Ο' => 'Ο',
2071 'Ρ' => 'Ρ',
2072 'Σ' => 'Σ',
2073 'Τ' => 'Τ',
2074 'Υ' => 'Υ',
2075 'Φ' => 'Φ',
2076 'Χ' => 'Χ',
2077 'Ψ' => 'Ψ',
2078 'Ω' => 'Ω',
2079 'α' => 'α',
2080 'β' => 'β',
2081 'γ' => 'γ',
2082 'δ' => 'δ',
2083 'ε' => 'ε',
2084 'ζ' => 'ζ',
2085 'η' => 'η',
2086 'θ' => 'θ',
2087 'ι' => 'ι',
2088 'κ' => 'κ',
2089 'λ' => 'λ',
2093 'ο' => 'ο',
2095 'ρ' => 'ρ',
2096 'ς' => 'ς',
2097 'σ' => 'σ',
2098 'τ' => 'τ',
2099 'υ' => 'υ',
2100 'φ' => 'φ',
2101 'χ' => 'χ',
2102 'ψ' => 'ψ',
2103 'ω' => 'ω',
2104 'ϑ' => 'ϑ',
2105 'ϒ' => 'ϒ',
2106 'ϖ' => 'ϖ',
2107 '•' => '•',
2108 '…' => '…',
2109 '′' => '′',
2110 '″' => '″',
2111 '‾' => '‾',
2112 '⁄' => '⁄',
2113 '℘' => '℘',
2114 'ℑ' => 'ℑ',
2115 'ℜ' => 'ℜ',
2116 '™' => '™',
2117 'ℵ' => 'ℵ',
2118 '←' => '←',
2119 '↑' => '↑',
2120 '→' => '→',
2121 '↓' => '↓',
2122 '↔' => '↔',
2123 '↵' => '↵',
2124 '⇐' => '⇐',
2125 '⇑' => '⇑',
2126 '⇒' => '⇒',
2127 '⇓' => '⇓',
2128 '⇔' => '⇔',
2129 '∀' => '∀',
2130 '∂' => '∂',
2131 '∃' => '∃',
2132 '∅' => '∅',
2133 '∇' => '∇',
2134 '∈' => '∈',
2135 '∉' => '∉',
2136 '∋' => '∋',
2137 '∏' => '∏',
2138 '∑' => '∑',
2139 '−' => '−',
2140 '∗' => '∗',
2141 '√' => '√',
2142 '∝' => '∝',
2143 '∞' => '∞',
2144 '∠' => '∠',
2145 '∧' => '∧',
2146 '∨' => '∨',
2147 '∩' => '∩',
2148 '∪' => '∪',
2149 '∫' => '∫',
2150 '∴' => '∴',
2151 '∼' => '∼',
2152 '≅' => '≅',
2153 '≈' => '≈',
2154 '≠' => '≠',
2155 '≡' => '≡',
2156 '≤' => '≤',
2157 '≥' => '≥',
2158 '⊂' => '⊂',
2159 '⊃' => '⊃',
2160 '⊄' => '⊄',
2161 '⊆' => '⊆',
2162 '⊇' => '⊇',
2163 '⊕' => '⊕',
2164 '⊗' => '⊗',
2165 '⊥' => '⊥',
2166 '⋅' => '⋅',
2167 '⌈' => '⌈',
2168 '⌉' => '⌉',
2169 '⌊' => '⌊',
2170 '⌋' => '⌋',
2171 '⟨' => '〈',
2172 '⟩' => '〉',
2173 '◊' => '◊',
2174 '♠' => '♠',
2175 '♣' => '♣',
2176 '♥' => '♥',
2177 '♦' => '♦',
2181 //modify start+++++++++
2182 function _restore_to_utf8($contents)
2184 if (_CHARSET != 'UTF-8')
2186 $contents = mb_convert_encoding($contents, 'UTF-8', _CHARSET);
2188 $contents = $this->_decode_entities(strip_tags($contents));
2191 //modify end+++++++++
2192 function _detect_encoding($string)
2194 //modify start+++++++++
2195 if (function_exists('mb_convert_encoding')) {
2196 $encoding = (preg_match ("/;\s*charset=([^\n]+)/is", serverVar("CONTENT_TYPE"), $regs))?
2197 strtoupper(trim($regs[1])):
2200 if ( ($encoding !="") && ((mb_http_input("P") == "") || ( strtolower( ini_get("mbstring.http_input") ) == "pass")) ) {
2203 $encoding = mb_detect_encoding($string, 'UTF-8,EUC-JP,SJIS,ISO-8859-1,ASCII,JIS');
2205 return ( $encoding ) ? $encoding : 'ISO-8859-1';
2207 //modify end+++++++++
2208 if (!ereg("[\x80-\xFF]", $string) && !ereg("\x1B", $string))
2211 if (!ereg("[\x80-\xFF]", $string) && ereg("\x1B", $string))
2212 return 'ISO-2022-JP';
2214 if (preg_match("/^([\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF])+$/", $string) == 1)
2217 if (preg_match("/^([\x01-\x7F]|\x8E[\xA0-\xDF]|\x8F[xA1-\xFE][\xA1-\xFE]|[\xA1-\xFE][\xA1-\xFE])+$/", $string) == 1)
2220 if (preg_match("/^([\x01-\x7F]|[\xA0-\xDF]|[\x81-\xFC][\x40-\xFC])+$/", $string) == 1)
2223 return 'ISO-8859-1';
2226 function _convert_to_utf8($contents, $encoding)
2230 //modify start+++++++++
2231 // if (!$done && function_exists('iconv'))
2234 // $result = @iconv($encoding, 'UTF-8//IGNORE', $contents);
2238 // $contents = $result;
2243 if(!$done && function_exists('mb_convert_encoding'))
2246 if( function_exists('mb_substitute_character') ){
2247 @mb_substitute_character('none');
2249 $result = @mb_convert_encoding($contents, 'UTF-8', $encoding );
2253 $contents = $result;
2258 if (!$done && function_exists('iconv'))
2261 $result = @iconv($encoding, 'UTF-8//IGNORE', $contents);
2265 $contents = $result;
2269 //modify end+++++++++
2273 function _convert_to_utf8_auto($contents, $headers = '')
2275 /* IN: string in unknown encoding, headers received during transfer
2276 * OUT: string in UTF-8 encoding
2279 $str = substr($contents, 0, 4096);
2280 $len = strlen($str);
2286 $ord = ord($str[$pos]);
2288 if ($ord > 32 && $ord < 128)
2294 // Detection of encoding, check headers
2295 if (preg_match ("/;\s*charset=([^\n]+)/is", $headers, $regs))
2296 $encoding = strtoupper(trim($regs[1]));
2298 // Then check meta inside document
2299 if (preg_match ("/;\s*charset=([^\"']+)/is", $out, $regs))
2300 $encoding = strtoupper(trim($regs[1]));
2302 // Then check xml declaration
2303 if (preg_match("/<\?xml.+encoding\s*=\s*[\"|']([^\"']+)[\"|']\s*\?>/i", $out, $regs))
2304 $encoding = strtoupper(trim($regs[1]));
2307 return $this->_convert_to_utf8($contents, $encoding);
2310 function _decode_entities($string)
2312 /* IN: string in UTF-8 containing entities
2313 * OUT: string in UTF-8 without entities
2316 /// Convert all hexadecimal entities to decimal entities
2317 $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "'&#'.hexdec('\\1').';'", $string);
2319 // Deal with invalid cp1251 numeric entities
2320 $string = strtr($string, $this->entities_cp1251);
2322 // Convert all named entities to numeric entities
2323 $string = strtr($string, $this->entities_default);
2324 $string = strtr($string, $this->entities_latin);
2325 $string = strtr($string, $this->entities_extended);
2327 // Convert all numeric entities to UTF-8
2328 $string = preg_replace('/&#([0-9]+);/e', "'&#x'.dechex('\\1').';'", $string);
2329 $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "NP_TrackBack::_hex_to_utf8('\\1')", $string);
2334 function _hex_to_utf8($s)
2336 /* IN: string containing one hexadecimal Unicode character
2337 * OUT: string containing one binary UTF-8 character
2345 else if ($c < 0x800) {
2346 $str = chr(0xC0 | $c>>6) . chr(0x80 | $c & 0x3F);
2348 else if ($c < 0x10000) {
2349 $str = chr(0xE0 | $c>>12) . chr(0x80 | $c>>6 & 0x3F) . chr(0x80 | $c & 0x3F);
2351 else if ($c < 0x200000) {
2352 $str = chr(0xF0 | $c>>18) . chr(0x80 | $c>>12 & 0x3F) . chr(0x80 | $c>>6 & 0x3F) . chr(0x80 | $c & 0x3F);
2358 function _utf8_to_entities($string)
2360 /* IN: string in UTF-8 encoding
2361 * OUT: string consisting of only characters ranging from 0x00 to 0x7f,
2362 * using numeric entities to represent the other characters
2365 $len = strlen ($string);
2371 $ascii = ord (substr ($string, $pos, 1));
2375 $byte[1] = ord(substr ($string, $pos, 1)) - 0xF0;
2376 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
2377 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
2378 $byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80;
2380 $char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4];
2383 elseif (($ascii >= 0xE0) && ($ascii < 0xF0))
2385 $byte[1] = ord(substr ($string, $pos, 1)) - 0xE0;
2386 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
2387 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
2389 $char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3];
2392 elseif (($ascii >= 0xC0) && ($ascii < 0xE0))
2394 $byte[1] = ord(substr ($string, $pos, 1)) - 0xC0;
2395 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
2397 $char_code = ($byte[1] << 6) + $byte[2];
2402 $char_code = ord(substr ($string, $pos, 1));
2406 if ($char_code < 0x80)
2407 $out .= chr($char_code);
2409 $out .= '&#'. str_pad($char_code, 5, '0', STR_PAD_LEFT) . ';';
2415 function _utf8_to_javascript($string)
2417 /* IN: string in UTF-8 encoding
2418 * OUT: string consisting of only characters ranging from 0x00 to 0x7f,
2419 * using javascript escapes to represent the other characters
2422 $len = strlen ($string);
2428 $ascii = ord (substr ($string, $pos, 1));
2432 $byte[1] = ord(substr ($string, $pos, 1)) - 0xF0;
2433 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
2434 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
2435 $byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80;
2437 $char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4];
2440 elseif (($ascii >= 0xE0) && ($ascii < 0xF0))
2442 $byte[1] = ord(substr ($string, $pos, 1)) - 0xE0;
2443 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
2444 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
2446 $char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3];
2449 elseif (($ascii >= 0xC0) && ($ascii < 0xE0))
2451 $byte[1] = ord(substr ($string, $pos, 1)) - 0xC0;
2452 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
2454 $char_code = ($byte[1] << 6) + $byte[2];
2459 $char_code = ord(substr ($string, $pos, 1));
2463 if ($char_code < 0x80)
2464 $out .= chr($char_code);
2466 $out .= '\\u'. str_pad(dechex($char_code), 4, '0', STR_PAD_LEFT);
2472 function _cut_string($string, $dl = 0) {
2474 $defaultLength = $dl > 0 ? $dl : $this->getOption('defaultLength');
2476 if ($defaultLength < 1)
2483 for ($i = 0; $i < strlen($string); $i++)
2485 $value = ord($string[$i]);
2489 if ($value >= 192 && $value <= 223)
2491 elseif ($value >= 224 && $value <= 239)
2493 elseif ($value >= 240 && $value <= 247)
2496 if ($lastvalue <= 223 && $value >= 223 &&
2497 $count >= $defaultLength - $border)
2499 return substr($string, 0, $i) . '...';
2502 // Chinese and Japanese characters are
2503 // wider than Latin characters
2508 elseif ($string[$i] == '/' || $string[$i] == '?' ||
2509 $string[$i] == '-' || $string[$i] == ':' ||
2510 $string[$i] == ',' || $string[$i] == ';')
2512 if ($count >= $defaultLength - $border)
2513 return substr($string, 0, $i) . '...';
2515 elseif ($string[$i] == ' ')
2517 if ($count >= $defaultLength - $border)
2518 return substr($string, 0, $i) . '...';
2521 if ($count == $defaultLength)
2522 return substr($string, 0, $i + 1) . '...';
2524 $lastvalue = $value;
2532 function _cut_string($string, $dl = 0) {
2533 $maxLength = $dl > 0 ? $dl : $this->getOption('defaultLength');
2537 if (strlen($string) > $maxLength)
2538 $string = mb_strimwidth($string, 0, $maxLength, '...', _CHARSET);
2543 function _strip_controlchar($string){
2544 $string = preg_replace("/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]+/","",$string);
2545 $string = str_replace("\0","",$string);
2549 //modify start+++++++++
2550 function checkTableVersion(){
2551 $res = sql_query("SHOW FIELDS from ".sql_table('plugin_tb') );
2552 $fieldnames = array();
2553 while ($co = mysql_fetch_assoc($res)) {
2554 if($co['Field'] == 'block') return true;
2558 //modify end+++++++++
2560 /*---------------------------------------------------------------------------------- */
2562 /*---------------------------------------------------------------------------------- */
2564 * Handle an incoming TrackBack ping and save the data in the database
2566 function handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_url){
2568 $ping_url = trim($ping_url);
2570 if( preg_match("/^.+tb_id=([0-9]+)$/",$ping_url,$idnum) ){
2571 $tb_id = intval($idnum[1]);
2572 } elseif ( preg_match("/([0-9]+)\.trackback/",$ping_url,$idnum) ){
2573 $tb_id = intval($idnum[1]);
2574 } elseif ( preg_match("/itemid=([0-9]+)/",$ping_url,$idnum) ){
2575 $tb_id = intval($idnum[1]);
2578 if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes'))
2579 return _ERROR_NOSUCHITEM . "[ $tb_id ]";
2581 // save data in the DB
2582 $query = 'INSERT INTO ' . sql_table('plugin_tb_lc') . " (tb_id, from_id) VALUES ('".intval($tb_id)."','".intval($itemid)."')";
2583 $res = @mysql_query($query);
2585 return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error();
2589 * Show the list of TrackBack pings for a certain Trackback ID
2591 function showLocalList($tb_id) {
2592 global $CONF, $manager;
2595 $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';
2596 $res = mysql_query($query);
2599 'tburl' => $this->getTrackBackUrl($tb_id)
2602 // when no TrackBack pings are found
2603 if (!$res || mysql_num_rows($res) == 0) {
2604 echo TEMPLATE::fill($this->getOption('tplLocalEmpty'), $vars);
2608 // when TrackBack pings are found
2609 echo TEMPLATE::fill($this->getOption('tplLocalHeader'), $vars);
2611 while ($o = mysql_fetch_object($res)) {
2612 $canDelete = $this->canDelete($tb_id);
2614 'url' => createItemLink($o->from_id),
2615 'blogname' => htmlspecialchars(getBlogNameFromID($o->iblog)),
2616 'timestamp' => strftime('%Y-%m-%d',strtotime($o->itime)),
2617 'title' => htmlspecialchars($o->ititle),
2618 'excerpt' => htmlspecialchars(shorten(strip_tags($o->ibody),200,'...')),
2619 'delete' => $canDelete?'<a href="'. $manager->addTicketToUrl($CONF['ActionURL'].'?action=plugin&name=TrackBack&type=deletelc&tb_id='.intval($tb_id).'&from_id='.intval($o->from_id)).'">[delete]</a>':'',
2620 'tburl' => $this->getTrackBackUrl($tb_id),
2621 'commentcount'=> quickQuery('SELECT COUNT(*) as result FROM '.sql_table('comment').' WHERE citem=' . intval($o->from_id))
2623 echo TEMPLATE::fill($this->getOption('tplLocalItem'), $data);
2625 echo TEMPLATE::fill($this->getOption('tplLocalFooter'), $vars);
2629 * Delete a TrackBack item, redirect to referer
2631 function deleteLocal($tb_id, $from_id) {
2632 if (!$this->canDelete($tb_id))
2633 return 'You\'re not allowed to delete this trackback item';
2634 $query = 'DELETE FROM ' . sql_table('plugin_tb_lc') . " WHERE tb_id='" . intval($tb_id) . "' and from_id='" . intval($from_id) ."'";
2635 mysql_query($query);
2639 function canDelete($tb_id) {
2640 global $member, $manager;
2642 if ( ! $member->isLoggedIn() ) return 0;
2644 $checkIDs = $this->getOption('CheckIDs');
2645 $itemExists =& $manager->existsItem($tb_id,0,0);
2647 // if CheckIDs option is set, check if member canEdit($tb_id)
2648 // if CheckIDs option is not set, and item exists, check if member canEdit($tb_id)
2649 // if CheckIDs option is not set, and item does not exists, check if member isAdmin()
2651 if (($checkIDs == 'yes') || ($itemExists))
2652 return $member->canAlterItem($tb_id);
2654 return $member->isAdmin();
2657 /**************************************************************************************/
2658 /* Plugin API calls, for installation, configuration and setup */
2660 function getName() { return 'TrackBack'; }
2661 function getAuthor() { return 'rakaz + nakahara21 + hsur'; }
2662 function getURL() { return 'http://blog.cles.jp/np_cles/category/31/subcatid/3'; }
2663 function getVersion() { return '2.0.3 jp9'; }
2664 function getDescription() { return _TB_DESCRIPTION; }
2666 //modify start+++++++++
2668 function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup")); }
2669 function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead'); }
2671 function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup"), sql_table('plugin_tb_lc')); }
2673 function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead', 'RetrieveTrackback', 'SendTrackback', 'InitSkinParse'); }
2674 //modify end+++++++++
2675 function getMinNucleusVersion() { return 200; }
2677 function supportsFeature($feature) {
2679 case 'SqlTablePrefix':
2681 //modify start+++++++++
2684 //modify end+++++++++
2691 function hasAdminArea() { return 1; }
2693 function event_QuickMenu(&$data) {
2694 global $member, $nucleus, $blogid;
2696 // only show to admins
2697 if (!$member->isLoggedIn() || !$member->isAdmin()) return;
2702 'title' => 'Trackback',
2703 'url' => $this->getAdminURL(),
2704 'tooltip' => 'Manage your trackbacks'
2709 function install() {
2710 $this->createOption('AcceptPing', _TB_AcceptPing,'yesno','yes');
2711 $this->createOption('SendPings', _TB_SendPings,'yesno','yes');
2712 $this->createOption('AutoXMLHttp', _TB_AutoXMLHttp, 'yesno', 'yes');
2713 $this->createOption('CheckIDs', _TB_CheckIDs,'yesno','yes');
2715 $this->createOption('tplHeader', _TB_tplHeader, 'textarea', _TB_tplHeader_VAL);
2716 $this->createOption('tplEmpty', _TB_tplEmpty, 'textarea', _TB_tplEmpty_VAL);
2717 $this->createOption('tplItem', _TB_tplItem, 'textarea', _TB_tplItem_VAL);
2718 $this->createOption('tplFooter', _TB_tplFooter, 'textarea', _TB_tplFooter_VAL);
2720 $this->createOption('tplLocalHeader', _TB_tplLocalHeader, 'textarea', _TB_tplLocalHeader_VAL);
2721 $this->createOption('tplLocalEmpty', _TB_tplLocalEmpty, 'textarea', _TB_tplLocalEmpty_VAL);
2722 $this->createOption('tplLocalItem', _TB_tplLocalItem, 'textarea', _TB_tplLocalItem_VAL);
2723 $this->createOption('tplLocalFooter', _TB_tplLocalFooter, 'textarea', _TB_tplLocalFooter_VAL);
2726 $this->createOption('tplTbNone', _TB_tplTbNone, 'text', "No Trackbacks");
2727 $this->createOption('tplTbOne', _TB_tplTbOne, 'text', "1 Trackback");
2728 $this->createOption('tplTbMore', _TB_tplTbMore, 'text', "<%number%> Trackbacks");
2729 $this->createOption('dateFormat', _TB_dateFormat, 'text', _TB_dateFormat_VAL);
2731 $this->createOption('NotifyEmail', _TB_NotifyEmail,'text','');
2732 $this->createOption('DropTable', _TB_DropTable,'yesno','no');
2734 $this->createOption('HideUrl',_TB_HideUrl,'yesno','yes');
2735 $this->createOption('ajaxEnabled',_TB_ajaxEnabled,'yesno','no');
2737 $this->createItemOption('ItemAcceptPing',_TB_ItemAcceptPing,'yesno','yes');
2738 $this->createItemOption('isAcceptW/OLink',_TB_isAcceptWOLink,'select','default', _TB_isAcceptWOLink_VAL);
2740 $this->createBlogOption('NotifyEmailBlog', _TB_NotifyEmailBlog,'text','');
2741 $this->createBlogOption('isAcceptW/OLinkDef',_TB_isAcceptWOLinkDef,'select','block', _TB_isAcceptWOLinkDef_VAL);
2742 $this->createBlogOption('AllowTrackBack',_TB_AllowTrackBack,'yesno','yes');
2747 CREATE TABLE IF NOT EXISTS
2748 ".sql_table('plugin_tb')."
2750 `id` INT(11) NOT NULL AUTO_INCREMENT,
2751 `tb_id` INT(11) NOT NULL,
2752 `url` TEXT NOT NULL,
2753 `block` TINYINT(4) NOT NULL,
2754 `spam` TINYINT(4) NOT NULL,
2755 `link` TINYINT(4) NOT NULL,
2759 `timestamp` DATETIME,
2766 CREATE TABLE IF NOT EXISTS
2767 ".sql_table('plugin_tb_lookup')."
2769 `link` TEXT NOT NULL,
2770 `url` TEXT NOT NULL,
2773 PRIMARY KEY (`link` (100))
2776 //modify start+++++++++
2777 @mysql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
2778 @mysql_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))');
2779 //modify end+++++++++
2782 function uninstall() {
2783 if ($this->getOption('DropTable') == 'yes') {
2784 mysql_query ('DROP TABLE '.sql_table('plugin_tb'));
2785 mysql_query ('DROP TABLE '.sql_table('plugin_tb_lookup'));
2786 mysql_query ("DROP table ".sql_table('plugin_tb_lc'));
2791 // include language file for this plugin
2792 $language = ereg_replace( '[\\|/]', '', getLanguageName());
2793 if (file_exists($this->getDirectory().'language/'.$language.'.php'))
2794 include_once($this->getDirectory().'language/'.$language.'.php');
2796 include_once($this->getDirectory().'language/'.'english.php');
2797 $this->notificationMail = _TB_NORTIFICATION_MAIL_BODY;
2798 $this->notificationMailTitle = _TB_NORTIFICATION_MAIL_TITLE;