2 // vim: tabstop=2:shiftwidth=2
\r
4 /* ==========================================================================================
\r
5 * Trackback 2.0 for Nucleus CMS
\r
6 * ==========================================================================================
\r
7 * This program is free software and open source software; you can redistribute
\r
8 * it and/or modify it under the terms of the GNU General Public License as
\r
9 * published by the Free Software Foundation; either version 2 of the License,
\r
10 * or (at your option) any later version.
\r
12 * This program is distributed in the hope that it will be useful, but WITHOUT
\r
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
\r
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
\r
17 * You should have received a copy of the GNU General Public License along
\r
18 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA or visit
\r
20 * http://www.gnu.org/licenses/gpl.html
\r
21 * ==========================================================================================
\r
24 define('NP_TRACKBACK_LINKCHECK_STRICT', 1);
\r
25 define('NP_TRACKBACK_USE_XML_PARSER', 1);
\r
26 define('NP_TRACKBACK_ENCODING_DETECT_ORDER', 'ASCII,ISO-2022-JP,UTF-8,EUC-JP,SJIS');
\r
28 class NP_TrackBack_XMLParser {
\r
29 function NP_TrackBack_XMLParser(){
\r
30 $this->isError = false;
\r
31 $this->inTarget = false;
\r
34 function parse($data){
\r
35 $rx = '/(<'.'?xml.*encoding=[\'"])(.*?)([\'"].*?'.'>)/m';
\r
36 if (preg_match($rx, $data, $m)) {
\r
37 $encoding = strtoupper($m[2]);
\r
39 $encoding = mb_detect_encoding($data, NP_TRACKBACK_ENCODING_DETECT_ORDER);
\r
42 if($encoding == "UTF-8" || $encoding == "ISO-8859-1") {
\r
45 $data = @mb_convert_encoding($data, "UTF-8", $encoding);
\r
46 $data = str_replace ( $m[0], $m[1].'UTF-8'.$m[3], $data);
\r
47 $encoding = 'UTF-8';
\r
50 $this->parser = xml_parser_create($encoding);
\r
51 xml_set_object($this->parser, $this);
\r
52 xml_set_element_handler($this->parser, "_open", "_close");
\r
53 xml_set_character_data_handler($this->parser, "_cdata");
\r
54 xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, 'UTF-8').
\r
56 $this->words = array();
\r
57 xml_parse($this->parser, $data);
\r
58 $errcode = xml_get_error_code($this->parser);
\r
59 if ( $errcode != XML_ERROR_NONE ) {
\r
60 $this->isError = true;
\r
61 $this->message = 'XML Parse Error: ' . xml_error_string($errcode) . ' in '. xml_get_current_line_number($this->parser);
\r
63 return $this->message;
\r
67 xml_parser_free($this->parser);
\r
70 function _open($parser, $name, $attribute){
\r
73 $this->inTarget = 'MESSAGE';
\r
76 $this->inTarget = 'ERROR';
\r
81 function _close($parser, $name){
\r
82 if( $name == $this->inTarget ) $this->inTarget = null;
\r
85 function _cdata($parser, $data){
\r
86 switch( $this->inTarget ){
\r
88 $this->message = trim($data);
\r
91 $this->isError = ($data ? true : false);
\r
97 class NP_TrackBack extends NucleusPlugin {
\r
98 var $useCurl = 1; // use curl? 2:precheck+read by curl, 1: read by curl 0: fread
\r
100 //modify start+++++++++
\r
101 function _createItemLink($itemid, $b){
\r
102 global $CONF, $manager;
\r
104 $itemLink = createItemLink($itemid,'');
\r
105 if( strpos($itemLink, 'http') === 0 ){
\r
109 $blogurl = $b->getURL();
\r
111 $b =& $manager->getBlog($CONF['DefaultBlog']);
\r
112 $blogurl = $b->getURL();
\r
114 $blogurl = $CONF['IndexURL'];
\r
118 if(substr($blogurl, -1) == '/') $blogurl = substr($blogurl, 0, -1);
\r
119 $usePathInfo = ($CONF['URLMode'] == 'pathinfo');
\r
120 $itemUrlOrg = $CONF['ItemURL'];
\r
121 if( ! ($usePathInfo || substr($blogurl, -4) == '.php') ) $blogurl .= '/index.php';
\r
122 $CONF['ItemURL'] = $blogurl;
\r
124 $itemLink = createItemLink($itemid,'');
\r
125 $CONF['ItemURL'] = $itemUrlOrg;
\r
129 //modify end+++++++++
\r
131 /**************************************************************************************
\r
132 * SKIN VARS, TEMPLATE VARS AND ACTIONS
\r
136 * TrackBack data can be inserted using skinvars (or templatevars)
\r
138 function doSkinVar($skinType, $what = '', $tb_id = '', $amount = 'limit-1') {
\r
140 global $itemid, $manager, $CONF;
\r
142 //modify start+++++++++
\r
143 if(preg_match('/limit/i', $tb_id)){
\r
147 $amount = intval(str_replace('limit', '', $amount));
\r
148 //modify end+++++++++
\r
150 if ($tb_id == '') $tb_id = intval($itemid);
\r
153 $isAcceptPing = $this->isAcceptTrackBack($tb_id);
\r
155 //if( $skinType == 'template' && (! $isAcceptPing ) ){
\r
161 // Insert Auto-discovery RDF code
\r
165 // if($skinType == 'item')
\r
167 $spamcheck = array (
\r
168 'type' => 'tbcode',
\r
177 /* Backwards compatibility with SpamCheck API 1*/
\r
182 //$manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
\r
184 if (isset($spamcheck['result']) && $spamcheck['result'] == true){
\r
188 if( ($skinType == 'item') && (!$spam) && $isAcceptPing )
\r
190 $this->insertCode($tb_id);
\r
193 // Insert TrackBack URL
\r
197 // echo $this->getTrackBackUrl($tb_id);
\r
199 echo $this->getTrackBackUrl($tb_id);
\r
201 echo 'Sorry, no trackback pings are accepted.';
\r
205 // Insert manual ping URL
\r
207 case 'manualpingformlink':
\r
208 echo $this->getManualPingUrl($tb_id);
\r
211 case 'sendpinglink':
\r
212 echo $manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id));
\r
215 // Insert TrackBack count
\r
217 $count = $this->getTrackBackCount($tb_id);
\r
219 case 0: echo TEMPLATE::fill($this->getOption('tplTbNone'), array('number' => $count)); break;
\r
220 case 1: echo TEMPLATE::fill($this->getOption('tplTbOne'), array('number' => $count)); break;
\r
221 default: echo TEMPLATE::fill($this->getOption('tplTbMore'), array('number' => $count)); break;
\r
225 // Shows the TrackBack list
\r
228 //modify start+++++++++
\r
229 // $this->showList($tb_id);
\r
230 $this->showList($tb_id, $amount);
\r
231 //modify end+++++++++
\r
234 // show requred URL
\r
236 echo $this->getRequiredURL($tb_id);
\r
239 // shows the Local list
\r
241 $this->showLocalList($tb_id);
\r
251 * When used in templates, the tb_id will be determined by the itemid there
\r
253 function doTemplateVar(&$item, $what = '') {
\r
254 $this->doSkinVar('template', $what, $item->itemid);
\r
257 function doTemplateCommentsVar(&$item, &$comment, $what = ''){
\r
258 $this->doSkinVar('templatecomments', $what, $item->itemid);
\r
262 * A trackback ping is to be received on the URL
\r
263 * http://yourdomain.com/item/1234.trackback
\r
264 * Extra variables to be passed along are url, title, excerpt, blog_name
\r
266 function event_InitSkinParse(&$data) {
\r
267 global $CONF, $itemid;
\r
268 $format = requestVar('format');
\r
270 if ($CONF['URLMode'] == 'pathinfo') {
\r
271 if (preg_match('/(\/|\.)(trackback)(\/|$)/', serverVar('PATH_INFO'), $matches)) {
\r
272 $format = $matches[2];
\r
276 if ($format == 'trackback' && $data['type'] == 'item')
\r
278 $errorMsg = $this->handlePing(intval($itemid));
\r
280 if ($errorMsg != '')
\r
281 $this->xmlResponse($errorMsg);
\r
283 $this->xmlResponse();
\r
290 * A trackback ping is to be received on the URL
\r
291 * http://yourdomain.com/action.php?action=plugin&name=TrackBack&tb_id=1234
\r
292 * Extra variables to be passed along are url, title, excerpt, blog_name
\r
294 function doAction($type)
\r
296 global $CONF,$manager;
\r
297 $aActionsNotToCheck = array(
\r
304 if (!in_array($type, $aActionsNotToCheck)) {
\r
305 if (!$manager->checkTicket()) return _ERROR_BADTICKET;
\r
310 // When no action type is given, assume it's a ping
\r
312 $errorMsg = $this->handlePing();
\r
313 $this->xmlResponse($errorMsg);
\r
318 $errorMsg = $this->handlePing();
\r
319 if ($errorMsg != '')
\r
320 $this->showManualPingError(intRequestVar('tb_id'), $errorMsg);
\r
322 $this->showManualPingSuccess(intRequestVar('tb_id'));
\r
325 // Show manual ping form
\r
328 // $this->showManualPingForm(intRequestVar('tb_id'));
\r
329 $tb_id = intRequestVar('tb_id');
\r
330 $isAcceptPing = $this->isAcceptTrackBack($tb_id);
\r
332 if( $isAcceptPing )
\r
333 $this->showManualPingForm($tb_id);
\r
335 echo 'Sorry, no trackback pings are accepted.';
\r
339 // Detect trackback
\r
341 list($url, $title) =
\r
342 $this->getURIfromLink(html_entity_decode(requestVar('tb_link')));
\r
344 $url = addslashes($url);
\r
345 $url = $this->_utf8_to_javascript($url);
\r
347 $title = addslashes($title);
\r
348 $title = $this->_utf8_to_javascript($title);
\r
350 echo "tbDone('" . requestVar('tb_link') . "', '" . $url . "', '" . $title . "');";
\r
356 return $this->redirect(intRequestVar('tb_id'), requestVar('urlHash'));
\r
360 echo $this->showLeftList(intRequestVar('tb_id'), intRequestVar('amount'));
\r
363 // delete a trackback(local)
\r
365 $err = $this->deleteLocal(intRequestVar('tb_id'), intRequestVar('from_id'));
\r
368 header('Location: ' . serverVar('HTTP_REFERER'));
\r
375 function doIf($key = '', $value = '')
\r
378 //echo "key: $key, value: $value";
\r
380 switch( strtolower($key) ){
\r
383 if( $value == '' ) $value = 'yes';
\r
384 $value = ( $value == 'no' || (! $value) ) ? false : true;
\r
388 $ret = $this->isAcceptTrackBack($itemid);
\r
390 $ret = $this->isAcceptTrackBack();
\r
391 return ( $value == false ) ? (! $ret) : $ret;
\r
394 if( $value == '' ) $value = 'yes';
\r
395 $value = ( $value == 'no' || (! $value) ) ? false : true;
\r
399 $ret = $this->isEnableLinkCheck($itemid);
\r
401 return ( $value == false ) ? (! $ret) : $ret;
\r
408 /**************************************************************************************
\r
413 * Show a list of left trackbacks for this ID
\r
415 function showLeftList($tb_id, $offset = 0, $amount = 99999999) {
\r
416 global $manager, $blog, $CONF;
\r
422 md5(url) as urlHash,
\r
426 UNIX_TIMESTAMP(timestamp) AS timestamp
\r
428 '.sql_table('plugin_tb').'
\r
430 tb_id = '.intval($tb_id).' AND
\r
436 $query .= ' LIMIT '.intval($offset).', ' .intval($amount);
\r
437 $res = sql_query($query);
\r
438 while ($row = mysql_fetch_array($res))
\r
441 $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES);
\r
442 $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES);
\r
443 $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES);
\r
444 if (_CHARSET != 'UTF-8') {
\r
445 //modify start+++++++++
\r
446 $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']);
\r
447 $row['title'] = $this->_restore_to_utf8($row['title']);
\r
448 $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']);
\r
449 //modify end+++++++++
\r
450 $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']);
\r
451 $row['title'] = $this->_utf8_to_entities($row['title']);
\r
452 $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']);
\r
455 'action' => $this->getTrackBackUrl($tb_id),
\r
456 'form' => $this->getManualPingUrl($tb_id),
\r
457 'name' => $row['blog_name'],
\r
458 'title' => $row['title'],
\r
459 'excerpt' => $this->_cut_string($row['excerpt'], 400),
\r
460 'url' => htmlspecialchars($row['url'], ENT_QUOTES),
\r
461 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES)
\r
465 if( $this->getOption('HideUrl') == 'yes' )
\r
466 $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . $tb_id . '&urlHash=' . $row['urlHash'];
\r
468 $iVars['url'] = $row['url'];
\r
471 $out[] = TEMPLATE::fill($this->getOption('tplItem'), $iVars);
\r
473 mysql_free_result($res);
\r
475 return @join("\n",$out);
\r
479 * Show a list of all trackbacks for this ID
\r
481 function showList($tb_id, $amount = 0) {
\r
482 $tb_id = intval($tb_id);
\r
483 global $manager, $blog, $CONF, $member;
\r
485 $enableHideurl = true;
\r
486 // for TB LinkLookup
\r
488 strpos(serverVar('HTTP_USER_AGENT'),'Hatena Diary Track') === false
\r
489 || strpos(serverVar('HTTP_USER_AGENT'),'NP_TrackBack') === false
\r
490 || strpos(serverVar('HTTP_USER_AGENT'),'TBPingLinkLookup') === false
\r
491 || strpos(serverVar('HTTP_USER_AGENT'),'MT::Plugin::BanNoReferTb') === false
\r
492 || strpos(serverVar('HTTP_USER_AGENT'),'livedoorBlog') === false
\r
494 $enableHideurl = false;
\r
503 md5(url) as urlHash,
\r
507 UNIX_TIMESTAMP(timestamp) AS timestamp
\r
509 '.sql_table('plugin_tb').'
\r
511 tb_id = '.$tb_id .' AND
\r
520 md5(url) as urlHash,
\r
524 UNIX_TIMESTAMP(timestamp) AS timestamp
\r
526 '.sql_table('plugin_tb').'
\r
528 tb_id = '.intval($tb_id) .' AND
\r
533 if( $amount == '-1' )
\r
534 $query .= ' LIMIT 9999999';
\r
536 $query .= ' LIMIT '.intval($amount);
\r
539 $res = sql_query($query);
\r
542 'action' => $this->getTrackBackUrl(intval($tb_id)),
\r
543 'form' => $this->getManualPingUrl(intval($tb_id)),
\r
544 'required' => $this->getRequiredURL(intval($tb_id)),
\r
547 if ( $member->isLoggedIn() ){
\r
548 $adminurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=list&id=' . intval($tb_id)), ENT_QUOTES);
\r
549 $pingformurl = htmlspecialchars($manager->addTicketToUrl($CONF['PluginURL'] . 'trackback/index.php?action=ping&id=' . intval($tb_id)), ENT_QUOTES);
\r
550 $gVars['admin'] = '<a href="' . $adminurl . '" target="_blank">[admin]</a>';
\r
551 $gVars['pingform'] = '<a href="' . $pingformurl . '" target="_blank">[pingform]</a>';
\r
554 echo TEMPLATE::fill($this->getOption('tplHeader'), $gVars);
\r
557 while ($amount != 0 && $row = mysql_fetch_array($res))
\r
560 $row['blog_name'] = htmlspecialchars($row['blog_name'], ENT_QUOTES);
\r
561 $row['title'] = htmlspecialchars($row['title'], ENT_QUOTES);
\r
562 $row['excerpt'] = htmlspecialchars($row['excerpt'], ENT_QUOTES);
\r
566 if (_CHARSET != 'UTF-8') {
\r
567 //modify start+++++++++
\r
569 $row['blog_name'] = $this->_utf8_to_entities($row['blog_name']);
\r
570 $row['title'] = $this->_utf8_to_entities($row['title']);
\r
571 $row['excerpt'] = $this->_utf8_to_entities($row['excerpt']);
\r
573 $row['blog_name'] = $this->_restore_to_utf8($row['blog_name']);
\r
574 $row['title'] = $this->_restore_to_utf8($row['title']);
\r
575 $row['excerpt'] = $this->_restore_to_utf8($row['excerpt']);
\r
577 $row['blog_name'] = mb_convert_encoding($row['blog_name'], _CHARSET, 'UTF-8');
\r
578 $row['title'] = mb_convert_encoding($row['title'], _CHARSET, 'UTF-8');
\r
579 $row['excerpt'] = mb_convert_encoding($row['excerpt'], _CHARSET, 'UTF-8');
\r
580 //modify end+++++++++
\r
583 //modify start+++++++++
\r
586 'action' => $this->getTrackBackUrl($tb_id),
\r
587 'form' => $this->getManualPingUrl($tb_id),
\r
588 'name' => $row['blog_name'],
\r
589 'title' => $row['title'],
\r
590 'excerpt' => $row['excerpt'],
\r
591 'url' => htmlspecialchars($row['url'], ENT_QUOTES),
\r
592 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp'] + ($blog->getTimeOffset() * 3600)), ENT_QUOTES)
\r
596 'action' => $this->getTrackBackUrl($tb_id),
\r
597 'form' => $this->getManualPingUrl($tb_id),
\r
598 'name' => htmlspecialchars($row['blog_name'], ENT_QUOTES),
\r
599 'title' => htmlspecialchars($row['title'], ENT_QUOTES),
\r
600 'excerpt' => htmlspecialchars($this->_cut_string($row['excerpt'], 400), ENT_QUOTES),
\r
601 'url' => htmlspecialchars($row['url'], ENT_QUOTES),
\r
602 'date' => htmlspecialchars(strftime($this->getOption('dateFormat'), $row['timestamp']), ENT_QUOTES)
\r
606 if( $enableHideurl && $this->getOption('HideUrl') == 'yes' )
\r
607 $iVars['url'] = $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=redirect&tb_id=' . intval($tb_id) . '&urlHash=' . $row['urlHash'];
\r
609 $iVars['url'] = $row['url'];
\r
612 //modify end+++++++++
\r
613 echo TEMPLATE::fill($this->getOption('tplItem'), $iVars);
\r
617 //modify start+++++++++
\r
622 '.sql_table('plugin_tb').'
\r
624 tb_id = '.intval($tb_id) .' AND
\r
629 $result = sql_query($q);
\r
630 $total = mysql_result($result,0,0);
\r
632 if($amount != -1 && $total > $amount){
\r
633 $leftcount = $total - $amount;
\r
635 echo '<script type="text/javascript" src="' . $this->getAdminURL() . 'detectlist.php?tb_id='.intval($tb_id).'&amount='.intval($amount).'"></script>';
\r
639 <a name="restoftrackback" id="restoftrackback"></a>
\r
640 <div id="tbshownavi"><a href="#restoftrackback" onclick="resttbStart(); return false;" id="tbshow">Show left <?php echo $leftcount;?> Trackbacks</a></div>
\r
641 <div id="tbhidenavi" style="display: none;"><a href="#restoftrackback" onclick="hideresttb(); return false;">Hide <?php echo $leftcount;?> Trackbacks</a></div>
\r
642 <div id="resttb"></div>
\r
646 //modify end+++++++++
\r
648 if (mysql_num_rows($res) == 0)
\r
650 echo TEMPLATE::fill($this->getOption('tplEmpty'), $gVars);
\r
652 mysql_free_result($res);
\r
654 echo TEMPLATE::fill($this->getOption('tplFooter'), $gVars);
\r
659 * Returns the TrackBack count for a TrackBack item
\r
661 function getTrackBackCount($tb_id) {
\r
662 return quickQuery('SELECT COUNT(*) as result FROM ' . sql_table('plugin_tb') . ' WHERE tb_id='.intval($tb_id).' AND block = 0');
\r
666 * Returns the manual ping URL
\r
668 function getManualPingUrl($itemid) {
\r
670 return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&type=form&tb_id='.$itemid;
\r
674 * Show the manual ping form
\r
676 function showManualPingError($itemid, $status = '') {
\r
679 $form = true; $error = true; $success = false;
\r
680 sendContentType('text/html', 'admin-trackback', _CHARSET);
\r
681 //modify start+++++++++
\r
682 // include ($this->getDirectory() . '/templates/form.html');
\r
683 require_once($this->getDirectory() . '/template.php');
\r
684 $mTemplate = new Trackback_Template(null, $this->getDirectory());
\r
685 $mTemplate->set ('CONF', $CONF);
\r
686 $mTemplate->set ('itemid', $itemid);
\r
687 $mTemplate->set ('form', $form);
\r
688 $mTemplate->set ('error', $error);
\r
689 $mTemplate->set ('success', $success);
\r
690 $mTemplate->set ('status', $status);
\r
691 $mTemplate->template('templates/form.html');
\r
692 echo $mTemplate->fetch();
\r
693 //modify end+++++++++
\r
696 function showManualPingSuccess($itemid, $status = '') {
\r
699 $form = false; $error = false; $success = true;
\r
700 sendContentType('text/html', 'admin-trackback', _CHARSET);
\r
701 //modify start+++++++++
\r
702 //include ($this->getDirectory() . '/templates/form.html');
\r
703 require_once($this->getDirectory() . '/template.php');
\r
704 $mTemplate = new Trackback_Template(null, $this->getDirectory());
\r
705 $mTemplate->set ('CONF', $CONF);
\r
706 $mTemplate->set ('itemid', $itemid);
\r
707 $mTemplate->set ('form', $form);
\r
708 $mTemplate->set ('error', $error);
\r
709 $mTemplate->set ('success', $success);
\r
710 $mTemplate->set ('status', $status);
\r
711 $mTemplate->template('templates/form.html');
\r
712 echo $mTemplate->fetch();
\r
713 //modify end+++++++++
\r
716 function showManualPingForm($itemid, $text = '') {
\r
719 $form = true; $error = false; $success = false;
\r
721 // Check if we are allowed to accept pings
\r
722 if ( !$this->isAcceptTrackBack($itemid) ) {
\r
723 $text = 'Sorry, no trackback pings are accepted';
\r
724 $form = false; $error = true;
\r
727 sendContentType('text/html', 'admin-trackback', _CHARSET);
\r
728 //modify start+++++++++
\r
729 //include ($this->getDirectory() . '/templates/form.html');
\r
730 require_once($this->getDirectory() . '/template.php');
\r
731 $mTemplate = new Trackback_Template(null, $this->getDirectory());
\r
732 $mTemplate->set ('CONF', $CONF);
\r
733 $mTemplate->set ('itemid', $itemid);
\r
734 $mTemplate->set ('form', $form);
\r
735 $mTemplate->set ('error', $error);
\r
736 $mTemplate->set ('success', $success);
\r
737 $mTemplate->set ('status', $status);
\r
738 $mTemplate->template('templates/form.html');
\r
739 echo $mTemplate->fetch();
\r
740 //modify end+++++++++
\r
744 * Returns the trackback URL
\r
746 function getTrackBackUrl($itemid) {
\r
747 global $CONF, $manager;
\r
748 return $CONF['ActionURL'] . '?action=plugin&name=TrackBack&tb_id='.$itemid;
\r
752 * Insert RDF code for item
\r
754 function insertCode($itemid) {
\r
755 $itemid = intval($itemid);
\r
756 global $manager, $CONF;
\r
758 $item = & $manager->getItem($itemid, 0, 0);
\r
759 $blog = & $manager->getBlog(getBlogIDFromItemID($item['itemid']));
\r
762 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
\r
763 $uri = createItemLink($item['itemid'],'');
\r
765 $uri = $this->_createItemLink($item['itemid'],$blog);
\r
767 $title = strip_tags($item['title']);
\r
768 $desc = strip_tags($item['body']);
\r
769 $desc = $this->_cut_string($desc, 200);
\r
770 $desc = htmlspecialchars($desc, ENT_QUOTES);
\r
774 <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
775 xmlns:dc="http://purl.org/dc/elements/1.1/"
776 xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
778 rdf:about="<?php echo $uri; ?>"
779 dc:identifier="<?php echo $uri; ?>"
780 dc:title="<?php echo $title; ?>"
781 dc:description="<?php echo $desc; ?>"
782 trackback:ping="<?php echo $this->getTrackBackUrl($itemid)?>"
783 dc:date="<?php echo strftime('%Y-%m-%dT%H:%M:%S')?>" />
790 * Retrieving TrackBack Pings (when __mode=rss)
\r
792 function rssResponse($tb_id) {
\r
793 $itemid = intval($itemid);
\r
794 global $manager, $CONF;
\r
795 $item =& $manager->getItem($tb_id, 0, 0);
\r
799 $blog =& $manager->getBlog(getBlogIDFromItemID($item['itemid']));
\r
801 $blog_name = $blog->getName();
\r
802 $title = $item['title'];
\r
803 $excerpt = $item['body'];
\r
805 //modify start+++++++++
\r
807 if (_CHARSET != 'UTF-8')
\r
809 $title = $this->_convert_to_utf8($title, $encoding);
\r
810 $excerpt = $this->_convert_to_utf8($excerpt, $encoding);
\r
811 $blog_name = $this->_convert_to_utf8($blog_name, $encoding);
\r
814 $title = $this->_decode_entities(strip_tags($title));
\r
815 $excerpt = $this->_decode_entities(strip_tags($excerpt));
\r
816 $blog_name = $this->_decode_entities(strip_tags($blog_name));
\r
819 $title = $this->_restore_to_utf8($title);
\r
820 $excerpt = $this->_restore_to_utf8($excerpt);
\r
821 $blog_name = $this->_restore_to_utf8($blog_name);
\r
822 //modify end+++++++++
\r
824 $excerpt = $this->_cut_string($excerpt, 200);
\r
827 //modify start+++++++++
\r
829 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
\r
830 $url = createItemLink($item['itemid'],'');
\r
832 $url = $this->_createItemLink($item['itemid'],$blog);
\r
833 //modify end+++++++++
\r
835 // Use UTF-8 charset for output
\r
836 header('Content-Type: text/xml');
\r
837 echo "<","?xml version='1.0' encoding='UTF-8'?",">\n";
\r
839 echo "<response>\n";
\r
840 echo "\t<error>0</error>\n";
\r
841 echo "\t<rss version='0.91'>\n";
\r
842 echo "\t\t<channel>\n";
\r
843 echo "\t\t\t<title>".htmlspecialchars($title, ENT_QUOTES)."</title>\n";
\r
844 echo "\t\t\t<link>".htmlspecialchars($url, ENT_QUOTES)."</link>\n";
\r
845 echo "\t\t\t<description>".htmlspecialchars($excerpt, ENT_QUOTES)."</description>\n";
\r
847 $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';
\r
848 $res = sql_query($query);
\r
849 while ($o = mysql_fetch_object($res))
\r
851 // No need to do conversion, because it is already UTF-8
\r
853 'url' => htmlspecialchars($o->url, ENT_QUOTES),
\r
854 'blogname' => htmlspecialchars($this->_restore_to_utf8($o->blog_name), ENT_QUOTES),
\r
855 'timestamp' => strftime('%Y-%m-%d',$o->timestamp),
\r
856 'title' => htmlspecialchars($this->_restore_to_utf8($o->title), ENT_QUOTES),
\r
857 'excerpt' => htmlspecialchars($this->_restore_to_utf8($o->excerpt), ENT_QUOTES),
\r
858 'tburl' => $this->getTrackBackUrl($tb_id)
\r
862 echo "\t\t\t<item>\n";
\r
863 echo "\t\t\t\t<title>".$data['title']."</title>\n";
\r
864 echo "\t\t\t\t<link>".$data['url']."</link>\n";
\r
865 echo "\t\t\t\t<description>".$data['excerpt']."</description>\n";
\r
866 echo "\t\t\t</item>\n";
\r
868 echo "\t\t</channel>\n";
\r
870 echo "</response>";
\r
875 $this->xmlResponse(_ERROR_NOSUCHITEM);
\r
882 /**************************************************************************************
\r
883 * SENDING AND RECEIVING TRACKBACK PINGS
\r
887 * Send a Trackback ping to another website
\r
889 function sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_url)
\r
891 $sendEncoding = 'UTF-8';
\r
893 // 1. Check some basic things
\r
894 if (!$this->canSendPing()) {
\r
895 return 'You\'re not allowed to send pings';
\r
898 if ($this->getOption('SendPings') == 'no') {
\r
899 return 'Sending trackback pings is disabled';
\r
902 if ($ping_url == '') {
\r
903 return 'No ping URL';
\r
906 // 2. Check if protocol is correct http URL
\r
907 $parsed_url = parse_url($ping_url);
\r
909 if ($parsed_url['scheme'] != 'http' || $parsed_url['host'] == '')
\r
910 return 'Bad ping URL';
\r
912 $port = ($parsed_url['port']) ? $parsed_url['port'] : 80;
\r
914 // 3. Create contents
\r
915 if($sendEncoding != _CHARSET){
\r
916 $title = mb_convert_encoding($title, $sendEncoding, _CHARSET);
\r
917 $excerpt = mb_convert_encoding($excerpt, $sendEncoding, _CHARSET);
\r
918 $blog_name = mb_convert_encoding($blog_name, $sendEncoding, _CHARSET);
\r
922 $content = 'title=' . urlencode( $title );
\r
923 $content .= '&url=' . urlencode( $url );
\r
924 $content .= '&excerpt=' . urlencode( $excerpt );
\r
925 $content .= '&blog_name=' . urlencode( $blog_name );
\r
927 // 4. Prepare HTTP request
\r
928 $request = 'POST ' . $parsed_url['path'];
\r
930 if ($parsed_url['query'] != '')
\r
931 $request .= '?' . $parsed_url['query'];
\r
933 $request .= " HTTP/1.1\r\n";
\r
934 $request .= "Accept: */*\r\n";
\r
935 $request .= "User-Agent: " . $this->userAgent . "\r\n";
\r
936 $request .= ( $port == 80 )?
\r
937 "Host: " . $parsed_url['host'] . "\r\n":
\r
938 "Host: " . $parsed_url['host'] . ":" . $port . "\r\n";
\r
939 $request .= "Cache-Control: no-cache\r\n";
\r
940 $request .= "Connection: Close\r\n";
\r
941 $request .= "Content-Length: " . strlen( $content ) . "\r\n";
\r
942 $request .= "Content-Type: application/x-www-form-urlencoded; charset=UTF-8\r\n";
\r
943 $request .= "\r\n";
\r
944 $request .= $content;
\r
946 $socket = fsockopen( $parsed_url['host'], $port, $errno, $errstr );
\r
948 return 'Could not send ping: '.$errstr.' ('.$errno.')';
\r
950 // 5. Execute HTTP request
\r
951 fputs($socket, $request);
\r
953 // 6. Receive response
\r
955 while (!feof($socket)) {
\r
956 $result .= fgets($socket, 4096);
\r
961 //modify start+++++++++
\r
962 list($header, $body) = split("\r\n\r\n", $result, 2);
\r
963 preg_match("/HTTP\/1\.[0-1] ([0-9]+) ([^\r\n]*)\r?\n/", $header, $httpresp);
\r
964 $respCd = $httpresp[1];
\r
965 $respMsg = $httpresp[2];
\r
967 if( $respCd != 200 ){
\r
968 return 'An error occurred: HTTP Error: [' . $respCd . '] ' . $respMsg;
\r
971 if( defined('NP_TRACKBACK_USE_XML_PARSER') && function_exists('xml_parser_create') ){
\r
972 $p = new NP_TrackBack_XMLParser();
\r
974 # remove invalid string
\r
975 $body = strstr($body, '<');
\r
976 $body = substr($body, 0, strrpos($body,'>') === false ? 0 : strrpos($body,'>') + 1 );
\r
981 $errorMessage = mb_convert_encoding($p->message, _CHARSET, 'UTF-8');
\r
982 return 'An error occurred: ' . htmlspecialchars($errorMessage, ENT_QUOTES);
\r
985 if ( strpos($DATA[1],'<error>0</error>') === false ){
\r
986 preg_match("/<message>(.*?)<\/message>/",$DATA[1],$error_message);
\r
987 if( $error_message[1] ){
\r
988 $errorMessage = mb_convert_encoding($error_message[1], _CHARSET);
\r
989 return 'An error occurred: '.htmlspecialchars($errorMessage, ENT_QUOTES);
\r
991 return 'An error occurred: fatal error.';
\r
998 //modify end+++++++++
\r
1001 * Handle a Trackback ping sent to this website
\r
1003 function handlePing($tb_id = 0) {
\r
1009 //modify start+++++++++
\r
1012 //modify end+++++++++
\r
1014 $tb_id = intRequestVar('tb_id');
\r
1016 $rss = requestVar('__mode') == 'rss';
\r
1018 $enableLinkCheck = $this->isEnableLinkCheck($tb_id);
\r
1019 $block = ( $enableLinkCheck ) ? true : false ;
\r
1023 return 'TrackBack ID is missing (tb_id)';
\r
1026 if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes')) {
\r
1027 return _ERROR_NOSUCHITEM;
\r
1030 // 0. Check if we need to output the list as rss
\r
1032 $this->rssResponse($tb_id);
\r
1036 // check: accept pings.
\r
1037 $blogId = getBlogIDFromItemID($tb_id);
\r
1038 $isAcceptPing = $this->isAcceptTrackBack($tb_id);
\r
1040 if (! $isAcceptPing)
\r
1041 return 'Sorry, no trackback pings are accepted.';
\r
1044 // 1. Get attributes
\r
1045 //modify start+++++++++
\r
1046 $b =& $manager->getBlog($blogId);
\r
1047 //modify end+++++++++
\r
1048 $url = requestVar('url');
\r
1049 $title = requestVar('title');
\r
1050 $excerpt = requestVar('excerpt');
\r
1051 $blog_name = requestVar('blog_name');
\r
1053 if( $url && preg_match('/https?:\/\/([^\/]+)/', $url, $matches) ){
\r
1054 if( gethostbynamel($matches[1]) === FALSE )
\r
1055 return 'URL is invalid (url)';
\r
1057 return 'URL is missing or invalid (url)';
\r
1060 // 2. Conversion of encoding...
\r
1061 //modify start+++++++++
\r
1062 /* if (preg_match ("/;\s*charset=([^\n]+)/is", $_SERVER["CONTENT_TYPE"], $regs))
\r
1063 $encoding = strtoupper(trim($regs[1]));
\r
1065 $encoding = $this->_detect_encoding($excerpt);
\r
1067 $encoding = $this->_detect_encoding($excerpt);
\r
1068 //modify end+++++++++
\r
1070 //modify start+++++++++
\r
1071 if (_CHARSET != 'UTF-8'){
\r
1072 $title = $this->_strip_controlchar(strip_tags(mb_convert_encoding($title, _CHARSET, $encoding)));
\r
1073 $excerpt = $this->_strip_controlchar(strip_tags(mb_convert_encoding($excerpt, _CHARSET, $encoding)));
\r
1074 $blog_name = $this->_strip_controlchar(strip_tags(mb_convert_encoding($blog_name, _CHARSET, $encoding)));
\r
1076 $title = $this->_strip_controlchar($this->_convert_to_utf8($title, $encoding));
\r
1077 $excerpt = $this->_strip_controlchar($this->_convert_to_utf8($excerpt, $encoding));
\r
1078 $blog_name = $this->_strip_controlchar($this->_convert_to_utf8($blog_name, $encoding));
\r
1080 $title = $this->_decode_entities(strip_tags($title));
\r
1081 $excerpt = $this->_decode_entities(strip_tags($excerpt));
\r
1082 $blog_name = $this->_decode_entities(strip_tags($blog_name));
\r
1084 //modify end+++++++++
\r
1086 // 4. Save data in the DB
\r
1087 $res = @sql_query('
\r
1089 tb_id, block, spam
\r
1091 '.sql_table('plugin_tb').'
\r
1093 url = \''.mysql_real_escape_string($url).'\' AND
\r
1094 tb_id = \''.intval($tb_id).'\'
\r
1097 if (mysql_num_rows($res) != 0)
\r
1099 // Existing TB, update it
\r
1101 $res = @sql_query('
\r
1103 '.sql_table('plugin_tb').'
\r
1105 title = "'.mysql_real_escape_string($title).'",
\r
1106 excerpt = "'.mysql_real_escape_string($excerpt).'",
\r
1107 blog_name = "'.mysql_real_escape_string($blog_name).'",
\r
1108 timestamp = '.mysqldate(time()).'
\r
1110 url = "'.mysql_real_escape_string($url).'" AND
\r
1111 tb_id = "'.$tb_id.'"
\r
1114 //modify start+++++++++
\r
1115 $rows = mysql_fetch_assoc($res);
\r
1116 $spam = ( $rows['block'] || $rows['spam'] ) ? true : false;
\r
1117 $res = @sql_query('
\r
1119 '.sql_table('plugin_tb').'
\r
1121 title = \''.mysql_real_escape_string($title).'\',
\r
1122 excerpt = \''.mysql_real_escape_string($excerpt).'\',
\r
1123 blog_name = \''.mysql_real_escape_string($blog_name).'\',
\r
1124 timestamp = '.mysqldate($b->getCorrectTime()).'
\r
1126 url = \''.mysql_real_escape_string($url).'\' AND
\r
1127 tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\'
\r
1129 //modify end+++++++++
\r
1132 return 'Could not update trackback data: '.mysql_error();
\r
1139 $res = @sql_query('SELECT id FROM '.sql_table('plugin_tb').' WHERE block = 1 and url = \''.mysql_real_escape_string($url).'\'' );
\r
1140 if (mysql_num_rows($res) != 0) {
\r
1141 // NP_Trackback has blocked tb !
\r
1142 ACTIONLOG :: add(INFO, "Trackback: Duplicated Blocked Trackback [ignore] (itemid:$tb_id from: $url)");
\r
1143 return 'Sorry, trackback ping is not accepted.';
\r
1147 // 4. SPAM check (for SpamCheck API 2 /w compat. API 1)
\r
1148 $spamcheck = array (
\r
1149 'type' => 'trackback',
\r
1151 'title' => $title,
\r
1152 'excerpt' => $excerpt,
\r
1153 'blogname' => $blog_name,
\r
1158 /* Backwards compatibility with SpamCheck API 1*/
\r
1159 'data' => $url . "\n" . $title . "\n" . $excerpt . "\n" . $blog_name . "\n" . serverVar('HTTP_USER_AGENT'),
\r
1160 'ipblock' => true,
\r
1163 $manager->notify('SpamCheck', array ('spamcheck' => & $spamcheck));
\r
1165 if (isset($spamcheck['result']) && $spamcheck['result'] == true)
\r
1170 // 5. Content check (TO DO)
\r
1171 if($spam == false || $enableLinkCheck == 'ignore' ) //modify
\r
1174 // $contents = $this->retrieveUrl ($url);
\r
1176 // if (preg_match("/(".preg_quote($_SERVER["REQUEST_URI"], '/').")|(".preg_quote($_SERVER["SERVER_NAME"], '/').")/i", $contents)) {
\r
1179 if( $enableLinkCheck ){
\r
1180 $contents = $this->retrieveUrl($url);
\r
1182 $linkArray = $this->getPermaLinksFromText($contents);
\r
1184 if( defined('NP_TRACKBACK_LINKCHECK_STRICT') )
\r
1185 $itemLink = $this->_createItemLink($tb_id, $b);
\r
1187 $itemLink = $b->getURL();
\r
1189 $itemLinkPat = '{^' . preg_quote($itemLink) .'}i';
\r
1190 $itemLinkPat = str_replace('&','&(amp;)?', $itemLinkPat);
\r
1192 foreach($linkArray as $l) {
\r
1193 if(preg_match($itemLinkPat, $l)){
\r
1194 ACTIONLOG :: add(INFO, "Trackback: LinkCheck OK. (link: $l pat: $itemLinkPat )");
\r
1200 $cnt = @count($linkArray);
\r
1201 if( $enableLinkCheck == 'ignore' ){
\r
1202 ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [ignore] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat)");
\r
1203 return 'Sorry, trackback ping is not accepted.';
\r
1205 ACTIONLOG :: add(INFO, "Trackback: LinkCheck NG. [block] (itemid:$tb_id from: $url cnt: $cnt pat: $itemLinkPat");
\r
1212 // 6. Determine if Trackback is safe...
\r
1213 //modify start+++++++++
\r
1214 // $block = $spam == true || $link == false;
\r
1215 // $block = $spam == true ;
\r
1216 //modify end+++++++++
\r
1218 if ( $enableLinkCheck )
\r
1219 $block = ($spam == true || $link == false);
\r
1221 $block = $spam == true ;
\r
1223 // New TB, insert it
\r
1227 '.sql_table('plugin_tb').'
\r
1229 tb_id = "'.$tb_id.'",
\r
1230 block = "'.($block ? '1' : '0').'",
\r
1231 spam = "'.($spam ? '1' : '0').'",
\r
1232 link = "'.($link ? '1' : '0').'",
\r
1233 url = "'.mysql_real_escape_string($url).'",
\r
1234 title = "'.mysql_real_escape_string($title).'",
\r
1235 excerpt = "'.mysql_real_escape_string($excerpt).'",
\r
1236 blog_name = "'.mysql_real_escape_string($blog_name).'",
\r
1237 timestamp = '.mysqldate(time()).'
\r
1240 //modify start+++++++++
\r
1243 '.sql_table('plugin_tb').'
\r
1245 tb_id = \''.mysql_real_escape_string(intval($tb_id)).'\',
\r
1246 block = \''.($block ? '1' : '0').'\',
\r
1247 spam = \''.($spam ? '1' : '0').'\',
\r
1248 link = \''.($link ? '1' : '0').'\',
\r
1249 url = \''.mysql_real_escape_string($url).'\',
\r
1250 title = \''.mysql_real_escape_string($title).'\',
\r
1251 excerpt = \''.mysql_real_escape_string($excerpt).'\',
\r
1252 blog_name = \''.mysql_real_escape_string($blog_name).'\',
\r
1253 timestamp = '.mysqldate($b->getCorrectTime()).'
\r
1255 //modify end+++++++++
\r
1257 $res = @sql_query($query);
\r
1260 return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error() . $query;
\r
1264 // 7. Send notification e-mail if needed
\r
1265 $notifyAddrs = $this->getOption('NotifyEmail');
\r
1266 $notifyAddrs = ( $notifyAddrs ? $notifyAddrs . ';' : '')
\r
1267 . $this->getBlogOption($blogId ,'NotifyEmailBlog');
\r
1269 if ($notifyAddrs && $spam == false)
\r
1273 'tb_id' => $tb_id,
\r
1275 'title' => $title,
\r
1276 'excerpt' => $excerpt,
\r
1277 'blogname' => $blog_name
\r
1280 //modify start+++++++++
\r
1283 'tb_id' => $tb_id,
\r
1285 'title' => mb_convert_encoding($title, 'ISO-2022-JP', _CHARSET),
\r
1286 'excerpt' => mb_convert_encoding($excerpt, 'ISO-2022-JP', _CHARSET),
\r
1287 'blogname' => mb_convert_encoding($blog_name, 'ISO-2022-JP', _CHARSET)
\r
1290 //maybe not needed because japanese version has "mb_send_mail" in function notify
\r
1291 //modify end+++++++++
\r
1293 $mailto_title = TEMPLATE::fill($this->notificationMailTitle, $vars);
\r
1294 $mailto_msg = TEMPLATE::fill($this->notificationMail, $vars);
\r
1296 global $CONF, $DIR_LIBS;
\r
1298 // make sure notification class is loaded
\r
1299 if (!class_exists('notification'))
\r
1300 include($DIR_LIBS . 'NOTIFICATION.php');
\r
1302 $notify = new NOTIFICATION($notifyAddrs);
\r
1303 $notify->notify($mailto_title, $mailto_msg , $CONF['AdminEmail']);
\r
1305 //mod by cles+++++++++++
\r
1306 if ($manager->pluginInstalled('NP_Cache')){
\r
1307 $p =& $manager->getPlugin('NP_Cache');
\r
1308 $p->setCurrentBlog($tb_id);
\r
1309 $p->cleanItem($tb_id);
\r
1310 $p->cleanArray(array('index'));
\r
1312 //mod by cles end +++++++++++
\r
1316 return 'Sorry, trackback ping is not accepted.';
\r
1320 function xmlResponse($errorMessage = '')
\r
1322 header('Content-type: application/xml; charset=utf-8');
\r
1323 echo "<"."?xml version='1.0' encoding='UTF-8'?".">\n";
\r
1324 echo "<response>\n";
\r
1326 if ($errorMessage){
\r
1327 if (_CHARSET != 'UTF-8')
\r
1328 $errorMessage = mb_convert_encoding($errorMessage, 'UTF-8');
\r
1329 echo "<error>1</error>\n";
\r
1330 echo "<message>".htmlspecialchars($errorMessage, ENT_QUOTES)."</message>\n";
\r
1332 echo "<error>0</error>\n";
\r
1335 echo "</response>";
\r
1340 * Check if member may send ping (check if logged in)
\r
1342 function canSendPing() {
\r
1344 return $member->isLoggedIn() || $this->xmlrpc;
\r
1349 function redirect($tb_id, $urlHash){
\r
1351 $query = 'SELECT url FROM '.sql_table('plugin_tb').' WHERE tb_id='.intval($tb_id).' and md5(url)="'.$urlHash.'"';
\r
1352 $res = sql_query($query);
\r
1354 $url = $CONF['SiteURL'];
\r
1356 if ($o = mysql_fetch_object($res)) {
\r
1357 $url = htmlspecialchars($o->url, ENT_QUOTES);
\r
1360 $url = stripslashes($url);
\r
1361 $url = str_replace('&','&',$url);
\r
1362 $url = str_replace('<','<',$url);
\r
1363 $url = str_replace('>','>',$url);
\r
1364 $url = str_replace('"','"',$url);
\r
1366 header('Location: '.$url);
\r
1369 function getRequiredURL($itemid){
\r
1371 $blog = & $manager->getBlog(getBlogIDFromItemID($itemid));
\r
1372 if( $this->isEnableLinkCheck($itemid) )
\r
1373 return $this->_createItemLink($itemid, $blog);
\r
1377 function isEnableLinkCheck($itemid){
\r
1378 $blogid = getBlogIDFromItemID($itemid);
\r
1380 switch( $this->getItemOption($itemid, 'isAcceptW/OLink') ){
\r
1382 $def = $this->getBlogOption($blogid, 'isAcceptW/OLinkDef');
\r
1386 return $def; // block or ignore
\r
1392 ACTIONLOG :: add(INFO, "Trackback: Unknown Option (itemid:$itemid, value:$val)");
\r
1397 function isAcceptTrackBack($itemid = null){
\r
1399 if( $this->getOption('AcceptPing') == 'yes' ){
\r
1402 $bid = getBlogIDFromItemID(intval($itemid));
\r
1405 $bid = $blog->getID();
\r
1408 if( $this->getBlogOption($bid, "AllowTrackBack") == 'yes' ){
\r
1410 $ret = ( $this->getItemOption(intval($itemid), 'ItemAcceptPing') == 'yes' ) ? true : false ;
\r
1423 /**************************************************************************************
\r
1427 function event_SendTrackback($data) {
\r
1430 // Enable sending trackbacks for the XML-RPC API, otherwise we would
\r
1431 // get an error because the current user is not exactly logged in.
\r
1432 $this->xmlrpc = true;
\r
1434 $itemid = $data['tb_id'];
\r
1435 $item = &$manager->getItem($itemid, 0, 0);
\r
1436 if (!$item) return; // don't ping for draft & future
\r
1437 if ($item['draft']) return; // don't ping on draft items
\r
1439 // gather some more information, needed to send the ping (blog name, etc)
\r
1440 $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
\r
1441 $blog_name = $blog->getName();
\r
1443 $title = $data['title'] != '' ? $data['title'] : $item['title'];
\r
1444 $title = strip_tags($title);
\r
1446 $excerpt = $data['body'] != '' ? $data['body'] : $item['body'];
\r
1447 $excerpt = strip_tags($excerpt);
\r
1448 $excerpt = $this->_cut_string($excerpt, 200);
\r
1450 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
\r
1451 //$url = createItemLink($itemid);
\r
1452 $url = $this->_createItemLink($itemid, $blog);
\r
1454 while (list(,$url) = each($data['urls'])) {
\r
1455 $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $url);
\r
1456 if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $url . ')');
\r
1460 function event_RetrieveTrackback($data) {
\r
1462 $res = sql_query('
\r
1466 UNIX_TIMESTAMP(timestamp) AS timestamp
\r
1468 '.sql_table('plugin_tb').'
\r
1470 tb_id = '.intval($data['tb_id']).' AND
\r
1476 while ($row = mysql_fetch_array($res)) {
\r
1478 $trackback = array(
\r
1479 'title' => $row['title'],
\r
1480 'url' => $row['url'],
\r
1484 $data['trackbacks'][] = $trackback;
\r
1488 function event_BookmarkletExtraHead($data) {
\r
1489 global $NP_TB_URL;
\r
1490 list ($NP_TB_URL,) = $this->getURIfromLink(requestVar('loglink'));
\r
1493 function event_PrepareItemForEdit($data) {
\r
1494 // if (!$this->getOption('AutoXMLHttp'))
\r
1495 if ($this->getOption('AutoXMLHttp') == 'no')
\r
1497 // The space between body and more is to make sure we didn't join 2 words accidently....
\r
1498 $this->larray = $this->autoDiscovery($data['item']['body'].' '.$data['item']['more']);
\r
1503 * After an item has been added to the database, send out a ping if requested
\r
1504 * (trackback_ping_url variable in request)
\r
1506 function event_PostAddItem($data) {
\r
1507 $this->pingTrackback($data);
\r
1510 function event_PreUpdateItem($data) {
\r
1511 $this->pingTrackback($data);
\r
1515 * Add trackback options to add item form/bookmarklet
\r
1517 function event_AddItemFormExtras($data) {
\r
1519 // global $NP_TB_URL;
\r
1522 <h3>TrackBack</h3>
\r
1524 <!--modify start+++++++++-->
\r
1525 <!-- <label for="plug_tb_url">TrackBack Ping URL:</label>
\r
1526 <input type="text" value="<?php if (isSet($NP_TB_URL)) {echo $NP_TB_URL;} ?>" id="plug_tb_url" name="trackback_ping_url" size="60" />
\r
1528 <!--modify end+++++++++-->
\r
1529 <label for="plug_tb_url">TrackBack URL:</label><br />
\r
1530 <textarea id="plug_tb_url" name="trackback_ping_url" cols="60" rows="5" style="font:normal xx-small Tahoma, Arial, verdana ;"></textarea>
\r
1531 <input type="button" name="btnAdd" value="<?php echo _TB_LIST_IT?>" onClick="AddStart()" />
\r
1536 // if ($this->getOption('AutoXMLHttp'))
\r
1537 if ($this->getOption('AutoXMLHttp') == 'yes')
\r
1540 <div id="tb_auto">
\r
1541 <input type="button" name="discoverit" value="Auto Discover" onclick="tbSetup();" />
\r
1542 <img id='tb_busy' src='<?php echo $this->getAdminURL(); ?>busy.gif' style="display:none;" /><br />
\r
1543 <div id="tb_auto_title"></div>
\r
1544 <table border="1"><tbody id="tb_ping_list"></tbody></table>
\r
1545 <input type="hidden" id="tb_url_amount" name="tb_url_amount" value="0" />
\r
1549 $this->jsautodiscovery();
\r
1557 * Add trackback options to edit item form/bookmarklet
\r
1559 function event_EditItemFormExtras($data) {
\r
1562 <!-- <input type="text" value="" id="plug_tb_url" name="trackback_ping_url" size="60" /><br />-->
\r
1563 <h3>TrackBack</h3>
\r
1565 <label for="plug_tb_url">TrackBack URL:</label><br />
\r
1566 <textarea id="plug_tb_url" name="trackback_ping_url" cols="60" rows="5" style="font:normal xx-small Tahoma, Arial, verdana ;"></textarea>
\r
1567 <input type="button" name="btnAdd" value="<?php echo _TB_LIST_IT?>" onClick="AddStart()" />
\r
1570 // if ($this->getOption('AutoXMLHttp'))
\r
1571 if ($this->getOption('AutoXMLHttp') == 'yes')
\r
1576 <div id="tb_auto">
\r
1577 <input type="button" name="discoverit" value="Auto Discover" onclick="tbSetup();" />
\r
1578 <img id='tb_busy' src='<?php echo $this->getAdminURL(); ?>busy.gif' style="display:none;" /><br />
\r
1579 <div id="tb_auto_title"></div>
\r
1580 <table border="1"><tbody id="tb_ping_list"></tbody></table>
\r
1581 <input type="hidden" id="tb_url_amount" name="tb_url_amount" value="0" />
\r
1585 $this->jsautodiscovery();
\r
1589 if (count($this->larray) > 0)
\r
1592 Auto Discovered Ping URL's:<br />
\r
1594 echo '<input type="hidden" name="tb_url_amount" value="'.count($this->larray).'" />';
\r
1598 while (list($url, $title) = each ($this->larray))
\r
1600 //modify start+++++++++
\r
1601 if (_CHARSET != 'UTF-8') {
\r
1602 $title = $this->_utf8_to_entities($title);
\r
1603 $title = mb_convert_encoding($title, _CHARSET, 'UTF-8');
\r
1605 //modify end+++++++++
\r
1607 echo '<input type="checkbox" name="tb_url_'.$i.
\r
1608 '" value="'.$url.'" id="tb_url_'.$i.
\r
1609 '" /><label for="tb_url_'.$i.'" title="'.$url.'">'.$title.'</label><br />';
\r
1621 * Insert Javascript AutoDiscovery routines
\r
1623 function jsautodiscovery()
\r
1628 <script type='text/javascript' src='<?php echo $this->getAdminURL(); ?>autodetect.php'></script>
\r
1635 function pingTrackback($data) {
\r
1636 global $manager, $CONF;
\r
1638 $ping_urls_count = 0;
\r
1639 $ping_urls = array();
\r
1640 $localflag = array();
\r
1642 $ping_url = requestVar('trackback_ping_url');
\r
1643 //modify start+++++++++
\r
1646 $ping_urls[0] = $ping_url;
\r
1647 $ping_urls_count++;
\r
1650 if (trim($ping_url)) {
\r
1651 $ping_urlsTemp = array();
\r
1652 $ping_urlsTemp = preg_split("/[\s,]+/", trim($ping_url));
\r
1653 for($i=0;$i<count($ping_urlsTemp);$i++){
\r
1654 $ping_urls[] = trim($ping_urlsTemp[$i]);
\r
1655 $ping_urls_count++;
\r
1658 //modify end+++++++++
\r
1660 $tb_url_amount = requestVar('tb_url_amount');
\r
1661 for ($i=0;$i<$tb_url_amount;$i++) {
\r
1662 $tb_temp_url = requestVar('tb_url_'.$i);
\r
1663 if ($tb_temp_url) {
\r
1664 $ping_urls[$ping_urls_count] = $tb_temp_url;
\r
1665 $localflag[$ping_urls_count] = (requestVar('tb_url_'.$i.'_local') == 'on')? 1: 0;
\r
1666 $ping_urls_count++;
\r
1670 if ($ping_urls_count <= 0) {
\r
1674 $itemid = $data['itemid'];
\r
1675 $item = &$manager->getItem($itemid, 0, 0);
\r
1676 if (!$item) return; // don't ping for draft & future
\r
1677 if ($item['draft']) return; // don't ping on draft items
\r
1679 // gather some more information, needed to send the ping (blog name, etc)
\r
1680 $blog =& $manager->getBlog(getBlogIDFromItemID($itemid));
\r
1681 $blog_name = $blog->getName();
\r
1683 $title = $data['title'] != '' ? $data['title'] : $item['title'];
\r
1684 $title = strip_tags($title);
\r
1686 $excerpt = $data['body'] != '' ? $data['body'] : $item['body'];
\r
1687 $excerpt = strip_tags($excerpt);
\r
1688 $excerpt = $this->_cut_string($excerpt, 200);
\r
1691 $CONF['ItemURL'] = preg_replace('/\/$/', '', $blog->getURL());
\r
1692 $url = createItemLink($itemid);
\r
1694 $url = $this->_createItemLink($item['itemid'],$blog);
\r
1696 // send the ping(s) (add errors to actionlog)
\r
1697 for ($i=0; $i<count($ping_urls); $i++) {
\r
1698 if( ! $localflag[$i] )
\r
1699 $res = $this->sendPing($itemid, $title, $url, $excerpt, $blog_name, $ping_urls[$i]);
\r
1701 $res = $this->handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_urls[$i]);
\r
1702 if ($res) ACTIONLOG::add(WARNING, 'TrackBack Error:' . $res . ' (' . $ping_urls[$i] . ')');
\r
1709 /**************************************************************************************
\r
1714 * Auto-Discovery of TrackBack Ping URLs based on HTML story
\r
1716 function autoDiscovery($text)
\r
1718 $links = $this->getPermaLinksFromText($text);
\r
1719 $result = array();
\r
1721 for ($i = 0; $i < count($links); $i++)
\r
1723 list ($url, $title) = $this->getURIfromLink($links[$i]);
\r
1726 $result[$url] = $title;
\r
1733 * Auto-Discovery of TrackBack Ping URLs based on single link
\r
1735 function getURIfromLink($link)
\r
1738 // Check to see if the cache contains this link
\r
1739 $res = sql_query('SELECT url, title FROM '.sql_table('plugin_tb_lookup').' WHERE link=\''.mysql_real_escape_string($link).'\'');
\r
1741 if ($row = mysql_fetch_array($res))
\r
1743 if ($row['title'] != '')
\r
1745 //modify start+++++++++
\r
1746 if (_CHARSET != 'UTF-8'){
\r
1747 $row['title'] = mb_convert_encoding($row['title'], 'UTF-8', _CHARSET);
\r
1748 $row['title'] = $this->_decode_entities($row['title']);
\r
1750 //modify end+++++++++
\r
1752 $row['url'], $row['title']
\r
1758 $row['url'], $row['url']
\r
1764 if (($rdf = $this->getRDFFromLink($link)) !== false)
\r
1766 // Get PING attribute
\r
1767 if (($uri = $this->getAttributeFromRDF($rdf, 'trackback:ping')) !== false)
\r
1769 // Get TITLE attribute
\r
1770 if (($title = $this->getAttributeFromRDF($rdf, 'dc:title')) !== false)
\r
1772 // Get CREATOR attribute
\r
1773 if (($author = $this->getAttributeFromRDF($rdf, 'dc:creator')) !== false)
\r
1775 $title = $author. ": " . $title;
\r
1778 $uri = $this->_decode_entities($uri);
\r
1779 //modify start+++++++++
\r
1780 if (_CHARSET != 'UTF-8')
\r
1781 $convertedTitle = mb_convert_encoding($title, _CHARSET, 'UTF-8');
\r
1783 $convertedTitle = $title;
\r
1786 $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)."')");
\r
1789 $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)."')");
\r
1790 //modify end+++++++++
\r
1791 $title = $this->_decode_entities($title);
\r
1799 $uri = html_entity_decode($uri, ENT_COMPAT);
\r
1802 $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','".mysql_real_escape_string($uri)."','')");
\r
1812 $res = sql_query("INSERT INTO ".sql_table('plugin_tb_lookup')." (link, url, title) VALUES ('".mysql_real_escape_string($link)."','','')");
\r
1814 return array ('', '');
\r
1818 * Detect links used in HTML code
\r
1820 function getPermaLinksFromText($text)
\r
1824 if (preg_match_all('/<a +([^>]+)>/i', $text, $array, PREG_SET_ORDER))
\r
1826 $count = count($array);
\r
1827 for ($i = 0; $i < $count; $i++)
\r
1829 if( preg_match('/https?:\/\/[-_.!~*\'()a-z0-9;\/?:@&=+$,%]+/i', $array[$i][1], $matches) )
\r
1830 $links[$matches[0]] = 1;
\r
1834 return array_keys($links);
\r
1838 * Retrieve RDF code from external link
\r
1840 function getRDFFromLink($link)
\r
1842 if ($content = $this->getContents($link))
\r
1844 preg_match_all('/(<rdf:RDF.*?<\/rdf:RDF>)/sm', $content, $rdfs, PREG_SET_ORDER);
\r
1846 if (count($rdfs) > 1)
\r
1848 for ($i = 0; $i < count($rdfs); $i++)
\r
1850 if (preg_match('|dc:identifier="'.preg_quote($link).'"|ms',$rdfs[$i][1]))
\r
1852 return $rdfs[$i][1];
\r
1858 // No need to check the identifier
\r
1859 return $rdfs[0][1];
\r
1867 * Retrieve the contents of an external (X)HTML document
\r
1869 function getContents($link) {
\r
1871 // Use cURL extention if available
\r
1872 if (function_exists("curl_init") && $this->useCurl == 2)
\r
1874 // Make HEAD request
\r
1875 $ch = curl_init();
\r
1876 @curl_setopt($ch, CURLOPT_URL, $link);
\r
1877 @curl_setopt($ch, CURLOPT_HEADER, true);
\r
1878 @curl_setopt($ch, CURLOPT_NOBODY, true);
\r
1879 @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
\r
1880 @curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
\r
1881 @curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
\r
1882 @curl_setopt($ch, CURLOPT_TIMEOUT, 20);
\r
1883 @curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
\r
1885 $headers = curl_exec($ch);
\r
1888 // Check if the link points to a (X)HTML document
\r
1889 if (preg_match('/Content-Type: (text\/html|application\/xhtml+xml)/i', $headers))
\r
1891 return $this->retrieveUrl ($link);
\r
1898 return $this->retrieveUrl ($link);
\r
1903 * Get a single attribute from RDF
\r
1905 function getAttributeFromRDF($rdf, $attribute)
\r
1907 if (preg_match('/'.$attribute.'="([^"]+)"/', $rdf, $matches))
\r
1909 return $matches[1];
\r
1920 /**************************************************************************************/
\r
1921 /* Internal helper functions for dealing with external file retrieval */
\r
1923 function retrieveUrl ($url) {
\r
1925 $ua = ini_set('user_agent', $this->userAgent);
\r
1927 if (function_exists('curl_init') && $this->useCurl > 0)
\r
1930 $ch = curl_init();
\r
1931 @curl_setopt($ch, CURLOPT_URL, $url);
\r
1932 @curl_setopt($ch, CURLOPT_HEADER, 1);
\r
1933 @curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
\r
1934 @curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
\r
1935 @curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
\r
1936 @curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
\r
1937 @curl_setopt($ch, CURLOPT_TIMEOUT, 20);
\r
1938 @curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent);
\r
1940 // Retrieve response
\r
1941 $raw = curl_exec($ch);
\r
1942 $info = curl_getinfo($ch);
\r
1944 // Split into headers and contents
\r
1945 $headers = substr($raw, 0, $info['header_size']);
\r
1946 $contents = substr($raw, $info['header_size']);
\r
1950 elseif ($fp = @fopen ($url, "rb"))
\r
1953 // $contents = fread($fp, 8192);
\r
1955 while (!feof($fp)) {
\r
1956 $contents .= fread($fp, 8192);
\r
1964 ini_set('user_agent', $ua);
\r
1967 // Next normalize the encoding to UTF8...
\r
1968 $contents = $this->_convert_to_utf8_auto($contents, $headers);
\r
1974 /**************************************************************************************/
\r
1975 /* Internal helper functions for dealing with encodings and entities */
\r
1977 var $entities_default = array (
\r
1978 '"' => '"',
\r
1979 '&' => '&',
\r
1980 ''' => ''',
\r
1981 '<' => '<',
\r
1982 '>' => '>',
\r
1985 //modify start+++++++++
\r
1986 function _restore_to_utf8($contents)
\r
1988 if (_CHARSET != 'UTF-8')
\r
1990 $contents = mb_convert_encoding($contents, 'UTF-8', _CHARSET);
\r
1992 $contents = $this->_decode_entities(strip_tags($contents));
\r
1995 //modify end+++++++++
\r
1996 function _detect_encoding($string)
\r
1998 //modify start+++++++++
\r
1999 if (function_exists('mb_convert_encoding')) {
\r
2000 $encoding = (preg_match ("/;\s*charset=([^\n]+)/is", serverVar("CONTENT_TYPE"), $regs))?
\r
2001 strtoupper(trim($regs[1])):
\r
2004 if ( ($encoding !="") && ((mb_http_input("P") == "") || ( strtolower( ini_get("mbstring.http_input") ) == "pass")) ) {
\r
2007 $encoding = mb_detect_encoding($string, NP_TRACKBACK_ENCODING_DETECT_ORDER);
\r
2009 return ( $encoding ) ? $encoding : _CHARSET;
\r
2011 //modify end+++++++++
\r
2012 if (!ereg("[\x80-\xFF]", $string) && !ereg("\x1B", $string))
\r
2013 return 'US-ASCII';
\r
2015 if (!ereg("[\x80-\xFF]", $string) && ereg("\x1B", $string))
\r
2016 return 'ISO-2022-JP';
\r
2018 if (preg_match("/^([\x01-\x7F]|[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF][\x80-\xBF])+$/", $string) == 1)
\r
2021 if (preg_match("/^([\x01-\x7F]|\x8E[\xA0-\xDF]|\x8F[xA1-\xFE][\xA1-\xFE]|[\xA1-\xFE][\xA1-\xFE])+$/", $string) == 1)
\r
2024 if (preg_match("/^([\x01-\x7F]|[\xA0-\xDF]|[\x81-\xFC][\x40-\xFC])+$/", $string) == 1)
\r
2025 return 'Shift_JIS';
\r
2027 return 'ISO-8859-1';
\r
2030 function _convert_to_utf8($contents, $encoding)
\r
2034 //modify start+++++++++
\r
2035 // if (!$done && function_exists('iconv'))
\r
2038 // $result = @iconv($encoding, 'UTF-8//IGNORE', $contents);
\r
2042 // $contents = $result;
\r
2047 if(!$done && function_exists('mb_convert_encoding'))
\r
2050 if( function_exists('mb_substitute_character') ){
\r
2051 @mb_substitute_character('none');
\r
2053 $result = @mb_convert_encoding($contents, 'UTF-8', $encoding );
\r
2057 $contents = $result;
\r
2062 if (!$done && function_exists('iconv'))
\r
2065 $result = @iconv($encoding, 'UTF-8//IGNORE', $contents);
\r
2069 $contents = $result;
\r
2073 //modify end+++++++++
\r
2077 function _convert_to_utf8_auto($contents, $headers = '')
\r
2079 /* IN: string in unknown encoding, headers received during transfer
\r
2080 * OUT: string in UTF-8 encoding
\r
2083 $str = substr($contents, 0, 4096);
\r
2084 $len = strlen($str);
\r
2088 while ($pos < $len)
\r
2090 $ord = ord($str[$pos]);
\r
2092 if ($ord > 32 && $ord < 128)
\r
2093 $out .= $str[$pos];
\r
2098 // Detection of encoding, check headers
\r
2099 if (preg_match ("/;\s*charset=([^\n]+)/is", $headers, $regs))
\r
2100 $encoding = strtoupper(trim($regs[1]));
\r
2102 // Then check meta inside document
\r
2103 if (preg_match ("/;\s*charset=([^\"']+)/is", $out, $regs))
\r
2104 $encoding = strtoupper(trim($regs[1]));
\r
2106 // Then check xml declaration
\r
2107 if (preg_match("/<\?xml.+encoding\s*=\s*[\"|']([^\"']+)[\"|']\s*\?>/i", $out, $regs))
\r
2108 $encoding = strtoupper(trim($regs[1]));
\r
2111 return $this->_convert_to_utf8($contents, $encoding);
\r
2114 function _decode_entities($string)
\r
2116 /* IN: string in UTF-8 containing entities
\r
2117 * OUT: string in UTF-8 without entities
\r
2120 /// Convert all hexadecimal entities to decimal entities
\r
2121 $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "'&#'.hexdec('\\1').';'", $string);
\r
2123 global $_entities;
\r
2124 // Deal with invalid cp1251 numeric entities
\r
2125 $string = strtr($string, $_entities['cp1251']);
\r
2127 // Convert all named entities to numeric entities
\r
2128 $string = strtr($string, $this->entities_default);
\r
2129 $string = strtr($string, $_entities['named']);
\r
2131 // Convert all numeric entities to UTF-8
\r
2132 $string = preg_replace('/&#([0-9]+);/e', "'&#x'.dechex('\\1').';'", $string);
\r
2133 $string = preg_replace('/&#[Xx]([0-9A-Fa-f]+);/e', "NP_TrackBack::_hex_to_utf8('\\1')", $string);
\r
2138 function _hex_to_utf8($s){
\r
2139 return entity::_hex_to_utf8($s);
\r
2142 function _utf8_to_entities($string)
\r
2144 /* IN: string in UTF-8 encoding
\r
2145 * OUT: string consisting of only characters ranging from 0x00 to 0x7f,
\r
2146 * using numeric entities to represent the other characters
\r
2149 $len = strlen ($string);
\r
2153 while ($pos < $len)
\r
2155 $ascii = ord (substr ($string, $pos, 1));
\r
2157 if ($ascii >= 0xF0)
\r
2159 $byte[1] = ord(substr ($string, $pos, 1)) - 0xF0;
\r
2160 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
\r
2161 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
\r
2162 $byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80;
\r
2164 $char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4];
\r
2167 elseif (($ascii >= 0xE0) && ($ascii < 0xF0))
\r
2169 $byte[1] = ord(substr ($string, $pos, 1)) - 0xE0;
\r
2170 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
\r
2171 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
\r
2173 $char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3];
\r
2176 elseif (($ascii >= 0xC0) && ($ascii < 0xE0))
\r
2178 $byte[1] = ord(substr ($string, $pos, 1)) - 0xC0;
\r
2179 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
\r
2181 $char_code = ($byte[1] << 6) + $byte[2];
\r
2186 $char_code = ord(substr ($string, $pos, 1));
\r
2190 if ($char_code < 0x80)
\r
2191 $out .= chr($char_code);
\r
2193 $out .= '&#'. str_pad($char_code, 5, '0', STR_PAD_LEFT) . ';';
\r
2199 function _utf8_to_javascript($string)
\r
2201 /* IN: string in UTF-8 encoding
\r
2202 * OUT: string consisting of only characters ranging from 0x00 to 0x7f,
\r
2203 * using javascript escapes to represent the other characters
\r
2206 $len = strlen ($string);
\r
2210 while ($pos < $len)
\r
2212 $ascii = ord (substr ($string, $pos, 1));
\r
2214 if ($ascii >= 0xF0)
\r
2216 $byte[1] = ord(substr ($string, $pos, 1)) - 0xF0;
\r
2217 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
\r
2218 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
\r
2219 $byte[4] = ord(substr ($string, $pos + 3, 1)) - 0x80;
\r
2221 $char_code = ($byte[1] << 18) + ($byte[2] << 12) + ($byte[3] << 6) + $byte[4];
\r
2224 elseif (($ascii >= 0xE0) && ($ascii < 0xF0))
\r
2226 $byte[1] = ord(substr ($string, $pos, 1)) - 0xE0;
\r
2227 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
\r
2228 $byte[3] = ord(substr ($string, $pos + 2, 1)) - 0x80;
\r
2230 $char_code = ($byte[1] << 12) + ($byte[2] << 6) + $byte[3];
\r
2233 elseif (($ascii >= 0xC0) && ($ascii < 0xE0))
\r
2235 $byte[1] = ord(substr ($string, $pos, 1)) - 0xC0;
\r
2236 $byte[2] = ord(substr ($string, $pos + 1, 1)) - 0x80;
\r
2238 $char_code = ($byte[1] << 6) + $byte[2];
\r
2243 $char_code = ord(substr ($string, $pos, 1));
\r
2247 if ($char_code < 0x80)
\r
2248 $out .= chr($char_code);
\r
2250 $out .= '\\u'. str_pad(dechex($char_code), 4, '0', STR_PAD_LEFT);
\r
2256 function _cut_string($string, $dl = 0) {
\r
2258 $defaultLength = $dl > 0 ? $dl : $this->getOption('defaultLength');
\r
2260 if ($defaultLength < 1)
\r
2267 for ($i = 0; $i < strlen($string); $i++)
\r
2269 $value = ord($string[$i]);
\r
2273 if ($value >= 192 && $value <= 223)
\r
2275 elseif ($value >= 224 && $value <= 239)
\r
2277 elseif ($value >= 240 && $value <= 247)
\r
2280 if ($lastvalue <= 223 && $value >= 223 &&
\r
2281 $count >= $defaultLength - $border)
\r
2283 return substr($string, 0, $i) . '...';
\r
2286 // Chinese and Japanese characters are
\r
2287 // wider than Latin characters
\r
2288 if ($value >= 224)
\r
2292 elseif ($string[$i] == '/' || $string[$i] == '?' ||
\r
2293 $string[$i] == '-' || $string[$i] == ':' ||
\r
2294 $string[$i] == ',' || $string[$i] == ';')
\r
2296 if ($count >= $defaultLength - $border)
\r
2297 return substr($string, 0, $i) . '...';
\r
2299 elseif ($string[$i] == ' ')
\r
2301 if ($count >= $defaultLength - $border)
\r
2302 return substr($string, 0, $i) . '...';
\r
2305 if ($count == $defaultLength)
\r
2306 return substr($string, 0, $i + 1) . '...';
\r
2308 $lastvalue = $value;
\r
2316 function _cut_string($string, $dl = 0) {
\r
2317 $maxLength = $dl > 0 ? $dl : $this->getOption('defaultLength');
\r
2319 if ($maxLength < 1)
\r
2321 if (strlen($string) > $maxLength)
\r
2322 $string = mb_strimwidth($string, 0, $maxLength, '...', _CHARSET);
\r
2327 function _strip_controlchar($string){
\r
2328 $string = preg_replace("/[\x01-\x08\x0b\x0c\x0e-\x1f\x7f]+/","",$string);
\r
2329 $string = str_replace("\0","",$string);
\r
2333 //modify start+++++++++
\r
2334 function checkTableVersion(){
\r
2335 $res = sql_query("SHOW FIELDS from ".sql_table('plugin_tb') );
\r
2336 $fieldnames = array();
\r
2337 while ($co = mysql_fetch_assoc($res)) {
\r
2338 if($co['Field'] == 'block') return true;
\r
2342 //modify end+++++++++
\r
2344 /*---------------------------------------------------------------------------------- */
\r
2346 /*---------------------------------------------------------------------------------- */
\r
2348 * Handle an incoming TrackBack ping and save the data in the database
\r
2350 function handleLocalPing($itemid, $title, $excerpt, $blog_name, $ping_url){
\r
2352 $ping_url = trim($ping_url);
\r
2354 if( preg_match("/^.+tb_id=([0-9]+)$/",$ping_url,$idnum) ){
\r
2355 $tb_id = intval($idnum[1]);
\r
2356 } elseif ( preg_match("/([0-9]+)\.trackback/",$ping_url,$idnum) ){
\r
2357 $tb_id = intval($idnum[1]);
\r
2358 } elseif ( preg_match("/itemid=([0-9]+)/",$ping_url,$idnum) ){
\r
2359 $tb_id = intval($idnum[1]);
\r
2362 if ((!$manager->existsItem($tb_id,0,0)) && ($this->getOption('CheckIDs') == 'yes'))
\r
2363 return _ERROR_NOSUCHITEM . "[ $tb_id ]";
\r
2365 // save data in the DB
\r
2366 $query = 'INSERT INTO ' . sql_table('plugin_tb_lc') . " (tb_id, from_id) VALUES ('".intval($tb_id)."','".intval($itemid)."')";
\r
2367 $res = @sql_query($query);
\r
2369 return 'Could not save trackback data, possibly because of a double entry: ' . mysql_error();
\r
2373 * Show the list of TrackBack pings for a certain Trackback ID
\r
2375 function showLocalList($tb_id) {
\r
2376 global $CONF, $manager;
\r
2378 // create SQL query
\r
2379 $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';
\r
2380 $res = sql_query($query);
\r
2383 'tburl' => $this->getTrackBackUrl($tb_id)
\r
2386 // when no TrackBack pings are found
\r
2387 if (!$res || mysql_num_rows($res) == 0) {
\r
2388 echo TEMPLATE::fill($this->getOption('tplLocalEmpty'), $vars);
\r
2392 // when TrackBack pings are found
\r
2393 echo TEMPLATE::fill($this->getOption('tplLocalHeader'), $vars);
\r
2395 while ($o = mysql_fetch_object($res)) {
\r
2396 $canDelete = $this->canDelete($tb_id);
\r
2398 'url' => createItemLink($o->from_id),
\r
2399 'blogname' => htmlspecialchars(getBlogNameFromID($o->iblog)),
\r
2400 'timestamp' => strftime('%Y-%m-%d',strtotime($o->itime)),
\r
2401 'title' => htmlspecialchars($o->ititle),
\r
2402 'excerpt' => htmlspecialchars(shorten(strip_tags($o->ibody),200,'...')),
\r
2403 '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>':'',
\r
2404 'tburl' => $this->getTrackBackUrl($tb_id),
\r
2405 'commentcount'=> quickQuery('SELECT COUNT(*) as result FROM '.sql_table('comment').' WHERE citem=' . intval($o->from_id))
\r
2407 echo TEMPLATE::fill($this->getOption('tplLocalItem'), $data);
\r
2409 echo TEMPLATE::fill($this->getOption('tplLocalFooter'), $vars);
\r
2413 * Delete a TrackBack item, redirect to referer
\r
2415 function deleteLocal($tb_id, $from_id) {
\r
2416 if (!$this->canDelete($tb_id))
\r
2417 return 'You\'re not allowed to delete this trackback item';
\r
2418 $query = 'DELETE FROM ' . sql_table('plugin_tb_lc') . " WHERE tb_id='" . intval($tb_id) . "' and from_id='" . intval($from_id) ."'";
\r
2419 sql_query($query);
\r
2423 function canDelete($tb_id) {
\r
2424 global $member, $manager;
\r
2426 if ( ! $member->isLoggedIn() ) return 0;
\r
2428 $checkIDs = $this->getOption('CheckIDs');
\r
2429 $itemExists =& $manager->existsItem($tb_id,0,0);
\r
2431 // if CheckIDs option is set, check if member canEdit($tb_id)
\r
2432 // if CheckIDs option is not set, and item exists, check if member canEdit($tb_id)
\r
2433 // if CheckIDs option is not set, and item does not exists, check if member isAdmin()
\r
2435 if (($checkIDs == 'yes') || ($itemExists))
\r
2436 return $member->canAlterItem($tb_id);
\r
2438 return $member->isAdmin();
\r
2441 /**************************************************************************************/
\r
2442 /* Plugin API calls, for installation, configuration and setup */
\r
2444 function getName() { return 'TrackBack'; }
\r
2445 function getAuthor() { return 'rakaz + nakahara21 + hsur'; }
\r
2446 function getURL() { return 'http://blog.cles.jp/np_cles/category/31/subcatid/3'; }
\r
2447 function getVersion() { return '2.0.3 jp13'; }
\r
2448 function getDescription() { return '[$Revision: 1.311 $]<br />' . _TB_DESCRIPTION; }
\r
2450 //modify start+++++++++
\r
2452 function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup")); }
\r
2453 function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead'); }
\r
2455 function getTableList() { return array(sql_table("plugin_tb"), sql_table("plugin_tb_lookup"), sql_table('plugin_tb_lc')); }
\r
2457 function getEventList() { return array('QuickMenu','PostAddItem','AddItemFormExtras','EditItemFormExtras','PreUpdateItem','PrepareItemForEdit', 'BookmarkletExtraHead', 'RetrieveTrackback', 'SendTrackback', 'InitSkinParse'); }
\r
2458 //modify end+++++++++
\r
2459 function getMinNucleusVersion() { return 330; }
\r
2461 function supportsFeature($feature) {
\r
2462 switch($feature) {
\r
2463 case 'SqlTablePrefix':
\r
2465 //modify start+++++++++
\r
2466 // case 'HelpPage':
\r
2468 //modify end+++++++++
\r
2475 function hasAdminArea() { return 1; }
\r
2477 function event_QuickMenu(&$data) {
\r
2478 global $member, $nucleus, $blogid;
\r
2480 // only show to admins
\r
2481 if (!$member->isLoggedIn()) return;
\r
2486 'title' => 'Trackback',
\r
2487 'url' => $this->getAdminURL(),
\r
2488 'tooltip' => 'Manage your trackbacks'
\r
2493 function install() {
\r
2494 $this->createOption('AcceptPing', _TB_AcceptPing,'yesno','yes');
\r
2495 $this->createOption('SendPings', _TB_SendPings,'yesno','yes');
\r
2496 $this->createOption('AutoXMLHttp', _TB_AutoXMLHttp, 'yesno', 'yes');
\r
2497 $this->createOption('CheckIDs', _TB_CheckIDs,'yesno','yes');
\r
2499 $this->createOption('tplHeader', _TB_tplHeader, 'textarea', _TB_tplHeader_VAL);
\r
2500 $this->createOption('tplEmpty', _TB_tplEmpty, 'textarea', _TB_tplEmpty_VAL);
\r
2501 $this->createOption('tplItem', _TB_tplItem, 'textarea', _TB_tplItem_VAL);
\r
2502 $this->createOption('tplFooter', _TB_tplFooter, 'textarea', _TB_tplFooter_VAL);
\r
2504 $this->createOption('tplLocalHeader', _TB_tplLocalHeader, 'textarea', _TB_tplLocalHeader_VAL);
\r
2505 $this->createOption('tplLocalEmpty', _TB_tplLocalEmpty, 'textarea', _TB_tplLocalEmpty_VAL);
\r
2506 $this->createOption('tplLocalItem', _TB_tplLocalItem, 'textarea', _TB_tplLocalItem_VAL);
\r
2507 $this->createOption('tplLocalFooter', _TB_tplLocalFooter, 'textarea', _TB_tplLocalFooter_VAL);
\r
2510 $this->createOption('tplTbNone', _TB_tplTbNone, 'text', "No Trackbacks");
\r
2511 $this->createOption('tplTbOne', _TB_tplTbOne, 'text', "1 Trackback");
\r
2512 $this->createOption('tplTbMore', _TB_tplTbMore, 'text', "<%number%> Trackbacks");
\r
2513 $this->createOption('dateFormat', _TB_dateFormat, 'text', _TB_dateFormat_VAL);
\r
2515 $this->createOption('NotifyEmail', _TB_NotifyEmail,'text','');
\r
2516 $this->createOption('DropTable', _TB_DropTable,'yesno','no');
\r
2518 $this->createOption('HideUrl',_TB_HideUrl,'yesno','yes');
\r
2519 $this->createOption('ajaxEnabled',_TB_ajaxEnabled,'yesno','no');
\r
2521 $this->createItemOption('ItemAcceptPing',_TB_ItemAcceptPing,'yesno','yes');
\r
2522 $this->createItemOption('isAcceptW/OLink',_TB_isAcceptWOLink,'select','default', _TB_isAcceptWOLink_VAL);
\r
2524 $this->createBlogOption('NotifyEmailBlog', _TB_NotifyEmailBlog,'text','');
\r
2525 $this->createBlogOption('isAcceptW/OLinkDef',_TB_isAcceptWOLinkDef,'select','block', _TB_isAcceptWOLinkDef_VAL);
\r
2526 $this->createBlogOption('AllowTrackBack',_TB_AllowTrackBack,'yesno','yes');
\r
2529 /* Create tables */
\r
2531 CREATE TABLE IF NOT EXISTS
\r
2532 ".sql_table('plugin_tb')."
\r
2534 `id` INT(11) NOT NULL AUTO_INCREMENT,
\r
2535 `tb_id` INT(11) NOT NULL,
\r
2536 `url` TEXT NOT NULL,
\r
2537 `block` TINYINT(4) NOT NULL,
\r
2538 `spam` TINYINT(4) NOT NULL,
\r
2539 `link` TINYINT(4) NOT NULL,
\r
2542 `blog_name` TEXT,
\r
2543 `timestamp` DATETIME,
\r
2545 PRIMARY KEY (`id`)
\r
2550 CREATE TABLE IF NOT EXISTS
\r
2551 ".sql_table('plugin_tb_lookup')."
\r
2553 `link` TEXT NOT NULL,
\r
2554 `url` TEXT NOT NULL,
\r
2557 PRIMARY KEY (`link` (100))
\r
2560 //modify start+++++++++
\r
2561 @sql_query('ALTER TABLE `' . sql_table('plugin_tb') . '` ADD INDEX `tb_id_block_timestamp_idx` ( `tb_id`, `block`, `timestamp` DESC )');
\r
2562 @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))');
\r
2563 //modify end+++++++++
\r
2566 function uninstall() {
\r
2567 if ($this->getOption('DropTable') == 'yes') {
\r
2568 sql_query ('DROP TABLE '.sql_table('plugin_tb'));
\r
2569 sql_query ('DROP TABLE '.sql_table('plugin_tb_lookup'));
\r
2570 sql_query ("DROP table ".sql_table('plugin_tb_lc'));
\r
2575 // include language file for this plugin
\r
2576 $language = ereg_replace( '[\\|/]', '', getLanguageName());
\r
2577 if (file_exists($this->getDirectory().'language/'.$language.'.php'))
\r
2578 include_once($this->getDirectory().'language/'.$language.'.php');
\r
2580 include_once($this->getDirectory().'language/'.'english.php');
\r
2581 $this->notificationMail = _TB_NORTIFICATION_MAIL_BODY;
\r
2582 $this->notificationMailTitle = _TB_NORTIFICATION_MAIL_TITLE;
\r
2584 $this->userAgent = 'NucleusCMS NP_TrackBack plugin ( '.$this->getVersion().' )';
\r