add('name', PLUGIN_EVENT_COMMENTSPICE_TITLE); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_DESC); $propbag->add('stackable', false); $propbag->add('author', 'Grischa Brockhaus'); $propbag->add('requirements', array( 'serendipity' => '0.8', 'smarty' => '2.6.7', 'php' => '4.1.0' )); $propbag->add('version', '1.0'); $propbag->add('event_hooks', array( 'frontend_footer' => true, 'frontend_comment' => true, 'frontend_display' => true, 'frontend_saveComment' => true, 'frontend_saveComment_finish' => true, 'backend_deletecomment' => true, 'external_plugin' => true, 'css' => true, )); $propbag->add('groups', array('FRONTEND_VIEWS')); $propbag->add('configuration', array('twitterinput','twitterinput_nofollow', 'announcerss', 'announcerssmax','announcerss_nofollow','plugin_path')); } function generate_content(&$title) { $title = PLUGIN_EVENT_EMOTICONCHOOSER_TITLE; } function introspect_config_item($name, &$propbag) { global $serendipity; switch($name) { case 'twitterinput': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_COMMENTSPICE_TWITTERINPUT); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_TWITTERINPUT_DESC); $propbag->add('default', true); return true; break; case 'twitterinput_nofollow': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_COMMENTSPICE_TWITTERINPUT_NOFOLLOW); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_TWITTERINPUT_NOFOLLOW_DESC); $propbag->add('default', true); return true; break; case 'announcerss': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_COMMENTSPICE_ANNOUNCE_RSS); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_ANNOUNCE_RSS_DESC); $propbag->add('default', false); return true; break; case 'announcerss_nofollow': $propbag->add('type', 'boolean'); $propbag->add('name', PLUGIN_EVENT_COMMENTSPICE_ANNOUNCE_RSS_NOFOLLOW); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_ANNOUNCE_RSS_NOFOLLOW_DESC); $propbag->add('default', false); return true; break; case 'announcerssmax': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_COMMENTSPICE_ANNOUNCE_RSS_MAXSELECT); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_ANNOUNCE_RSS_MAXSELECT_DESC); $propbag->add('default', 3); return true; case 'plugin_path': $propbag->add('type', 'string'); $propbag->add('name', PLUGIN_EVENT_COMMENTSPICE_PATH); $propbag->add('description', PLUGIN_EVENT_COMMENTSPICE_PATH_DESC); $propbag->add('default', $serendipity['serendipityHTTPPath'] . 'plugins/serendipity_event_commentspice/'); return true; break; } return false; } function event_hook($event, &$bag, &$eventData, &$addData) { global $serendipity; $hooks = &$bag->get('event_hooks'); if (isset($hooks[$event])) { switch($event) { case 'external_plugin': switch($eventData) { case 'spiceicotwitter.png': header('Content-Type: image/png'); echo file_get_contents(dirname(__FILE__). '/img/twitter_icon.png'); break; case 'spiceicorss.png': header('Content-Type: image/png'); echo file_get_contents(dirname(__FILE__). '/img/rss_icon.png'); break; case 'commentspice.png': header('Content-Type: image/png'); echo file_get_contents(dirname(__FILE__). '/img/commentspice.png'); break; case 'commentspicefrss': if (!serendipity_db_bool($this->get_config('announcerss', false))) break; $this->readRss(); break; } break; case 'frontend_saveComment': return $this->checkComment($eventData, $addData); break; case 'frontend_saveComment_finish' : $this->commentSaved($eventData, $addData); break; case 'frontend_footer': $this->printHeader(); break; case 'frontend_display': $this->spiceComment($eventData, $addData); break; case 'frontend_comment': $this->printCommentEditExtras($eventData, $addData); break; case 'backend_deletecomment' : $this->commentDeleted($eventData, $addData); break; case 'css': $this->writeCss($eventData, $addData); break; default: return false; break; } return true; } else { return false; } } function install() { DbSpice::install($this); } function cleanup() { DbSpice::install($this); $announcerssmax = $this->get_config('announcerssmax',3); if (!is_numeric($announcerssmax)) { $this->set_config('announcerssmax',3); } } function printHeader() { global $serendipity; if (serendipity_db_bool($this->get_config('announcerss',false))) { $path = $this->path = $this->get_config('plugin_path', $serendipity['serendipityHTTPPath'] . 'plugins/serendipity_event_commentspice/'); echo " "; } } function commentSaved($eventData, $addData) { global $serendipity; if ("NORMAL" == $addData['type']) { // only supported for normal comments $promo_name = null; $promo_url = null; if (isset($serendipity['POST']['promorss']) && !empty($serendipity['POST']['promorss'])) { $promorss = $serendipity['POST']['promorss']; $parts = explode("\n", $promorss); $promo_hash = trim($parts[0]); $promo_name = trim($parts[1]); $promo_url = trim($parts[2]); if (!$this->hashString($promo_name.$promo_url) == $promo_hash) return false; } $result = DbSpice::saveCommentSpice($addData['comment_cid'], $serendipity['POST']['twitter'], $promo_name, $promo_url); $this->rememberInputs(); } return true; } function rememberInputs() { global $serendipity; // Remember twitter name value into cookie, if user ordered to, else clear cookie if (isset($serendipity['POST']['remember'])) { serendipity_rememberCommentDetails(array ('twitter' => $serendipity['POST']['twitter'])); } else { serendipity_forgetCommentDetails(array('twitter')); } } function checkComment(&$eventData, &$addData) { global $serendipity; if ("NORMAL" == $addData['type']) { // only supported for normal comments $this->rememberInputs(); $promo_name = null; $promo_url = null; if (isset($serendipity['POST']['promorss']) && !empty($serendipity['POST']['promorss'])) { $promorss = $serendipity['POST']['promorss']; $parts = explode("\n", $promorss); $promo_hash = trim($parts[0]); $promo_name = trim($parts[1]); $promo_url = trim($parts[2]); if ($this->hashString($promo_name.$promo_url) != $promo_hash) { $eventData = array ('allow_comments' => false); $serendipity ['messagestack'] ['comments'] [] = PLUGIN_EVENT_COMMENTSPICE_PROMOTE_ARTICLE_CORRUPTED; return false; } } } return true; } function readRss() { global $serendipity; $comment_url = $_REQUEST ['coment_url']; $this->log("readRss for $comment_url"); if (empty($comment_url)) return; require_once (defined('S9Y_PEAR_PATH') ? S9Y_PEAR_PATH : S9Y_INCLUDE_PATH . 'bundled-libs/') . 'HTTP/Request.php'; $req = new HTTP_Request($comment_url, array('allowRedirects' => true, 'maxRedirects' => 3)); if (PEAR::isError($req->sendRequest()) || $req->getResponseCode() != '200') { $this->log("Error reading $comment_url"); return; } # Fetch html content: $data = $req->getResponseBody(); $this->log("Have data!"); // Check if page defines a RSS link $matches = array(); if (preg_match('@]*? type="application/rss\+xml"[^>]*? href="([^"]*?)"@Usi', $data, $matches)) { $this->log("rss link found, matches: " . print_r($matches[1],TRUE)); $rssUrl = $matches[1]; } else { $this->log("rss link not found"); return; } // Now fetch the RSS feed: require_once (defined('S9Y_PEAR_PATH') ? S9Y_PEAR_PATH : S9Y_INCLUDE_PATH . 'bundled-libs/') . 'Onyx/RSS.php'; # test multiple likely charsets $charsets = array( "utf-8", "ISO-8859-1"); $retry = false; foreach ($charsets as $ch) { if ($retry) $this->log("Retrying charset $ch"); $retry = true; $rss = new Onyx_RSS($ch); # does it parse? if so, all is fine... if ($rss->parse($rssUrl)) break; } $articles = array(); $article = array(); $article['title'] = PLUGIN_EVENT_COMMENTSPICE_PROMOTE_ARTICLE_CHOOSE; $article['url'] = ""; $articles[] = $article; $itemCount = 0; $maxItems = $announcerssmax = $this->get_config('announcerssmax',3); // Iterate the items while ($item = $rss->getNextItem()) { if ($itemCount>=$maxItems) break; $article = array(); $article['title'] = $item['title']; $hash = $this->hashString($item['title'].$item['link']); $article['url'] = $hash . "\n" . $item['title'] . "\n" . $item['link']; $articles[] = $article; $itemCount++; } if ($itemCount==0) return; $result['articles'] = $articles; $result['url'] = $comment_url; echo json_encode($result); } function commentDeleted($eventData, $addData) { $this->log('commentDeleted'); $this->log(print_r($eventData, true)); $this->log(print_r($addData, true)); $reult = DbSpice::deleteCommentSpice($addData['cid']); $this->log("delete result: $reult"); } function spiceComment(&$eventData, &$addData) { global $serendipity; if (!isset($eventData['comment']) || !serendipity_db_bool($this->get_config('twitterinput', true))) { return true; } // Called from sidbar: if ($addData['from'] == 'serendipity_plugin_comments:generate_content') { return true; } $spice = DbSpice::loadCommentSpice($eventData['id']); if (!is_array($spice)) { return true; } $twittername = $spice['twittername']; $eventData['comment'] = 'get_config('twitterinput_nofollow', true)?' rel="nofollow"':'') . '>' . PLUGIN_EVENT_COMMENTSPICE_PROMOTE_TWITTER . ': ' . $twittername . '
' . $eventData['comment']; if ($spice['promo_name'] && $spice['promo_url']) { $eventData['comment'] .= "

" . sprintf(PLUGIN_EVENT_COMMENTSPICE_PROMOTE_ARTICLE_RESCENT, $eventData['author']) . ": get_config('announcerss_nofollow', false)?' rel="nofollow"':'') . ">{$spice['promo_name']}

"; } } function printCommentEditExtras(&$eventData, &$addData) { global $serendipity; if (serendipity_db_bool($this->get_config('twitterinput', true))) { if (isset($serendipity['COOKIE']['twitter'])) $twittername = $serendipity['COOKIE']['twitter']; else $twittername = ''; echo '
'; echo ''; echo '
'; } if (serendipity_db_bool($this->get_config('announcerss', false))) { echo ''; } if (serendipity_db_bool($this->get_config('twitterinput', true))) { echo '
'; echo ''; echo PLUGIN_EVENT_COMMENTSPICE_PROMOTE_TWITTER_FOOTER; echo '
'; } if (serendipity_db_bool($this->get_config('announcerss', false))) { echo '
'; echo ''; echo PLUGIN_EVENT_COMMENTSPICE_PROMOTE_ARTICLE_FOOTER; echo '
'; } } function writeCss(&$eventData, &$addData) { global $serendipity; if (!(strpos($eventData, '.commentspice_ico'))) { ?> .commentspice_ico { float:right; margin-right:0px; margin-left:10px; } .commentspice_twitter_input { background: url('index.php?/plugin/spiceicotwitter.png') left no-repeat; padding-left: 1.5em; max-width: 18.5em; margin-bottom: 1em; } .commentspice_rss_input { max-width: 22em; min-width: 13.5em; width: 100%; background: url('index.php?/plugin/spiceicorss.png') no-repeat left #444444; overflow: hidden; border: 0.1em solid #000000; border-radius: 3px 3px 3px 3px; color: #FFFFFF; padding-left: 1.5em; margin-bottom: 1em; } get_config('installation_secret'); if (empty($installation_secret)) { $installation_secret = md5(date('l jS \of F Y h:i:s A')); $this->set_config('installation_secret', $installation_secret); } return md5($installation_secret . ':' . $what); } function log($message){ if (!PLUGIN_EVENT_COMMENTSPICE_DEBUG) return; $fp = fopen(dirname(__FILE__) . '/spice.log','a'); fwrite($fp, date('Y.m.d H:i:s') . " - " . $message . "\n"); fflush($fp); fclose($fp); } }