PageRenderTime 49ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/inc/bx/filters/formwizard/methods/blogcomment.php

https://github.com/chregu/fluxcms
PHP | 329 lines | 271 code | 28 blank | 30 comment | 31 complexity | 57877b218de721ef850ea4eb8ad82c35 MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, Apache-2.0, LGPL-2.1
  1. <?php
  2. class bxfw_blogcomment {
  3. private $allowedTags = array('b','i','a','ul','li','ol','pre','blockquote','br','p');
  4. private $knownspammers = array();
  5. private $tidyOptions = array(
  6. "output-xhtml" => true,
  7. "show-body-only" => true,
  8. "clean" => true,
  9. "wrap" => "350",
  10. "indent" => true,
  11. "indent-spaces" => 1,
  12. "ascii-chars" => false,
  13. "wrap-attributes" => false,
  14. "alt-text" => "",
  15. "doctype" => "loose",
  16. "numeric-entities" => true,
  17. "drop-proprietary-attributes" => true
  18. );
  19. public function __construct($fw) {
  20. $this->parent = $fw;
  21. }
  22. function emailFields($emailBodyID = '') {
  23. // not needed anymore;
  24. return true;
  25. $timezone = bx_helpers_config::getTimezoneAsSeconds();
  26. $fields = $this->parent->getFields();
  27. $isok = false;
  28. //add some more fields and clean some others
  29. $fields['remote_ip'] = $_SERVER['REMOTE_ADDR'];
  30. $fields['name'] = strip_tags($fields['name'] );
  31. $fields['email'] = strip_tags($fields['email'] );
  32. $fields['base'] = strip_tags($fields['base'] );
  33. foreach($fields as $name => $value) {
  34. $fields[$name] = bx_helpers_string::utf2entities(str_replace("&","&amp;",trim($value)));
  35. }
  36. /*
  37. FIXME: can't set cookies, due to the location redirect at the end...
  38. if (isset($fields['comment_remember'])) {
  39. $remember = array('name' => $fields['name'],'email' => $fields['email'],'base' => $fields['base'],'comment_notify' => @$fields['comment_notify'],'comment_remember' => $fields['comment_remember']);
  40. setcookie("blog_remember", serialize($remember), 3600*24*60,"/");
  41. } else if (isset($_COOKIE['blog_remember'])) {
  42. setcookie("blog_remember", null);
  43. }
  44. */
  45. //get TablePrefix
  46. $parts = bx_collections::getCollectionAndFileParts($this->parent->collUri, "output");
  47. $p = $parts['coll']->getFirstPluginMapByRequest("index","html");
  48. $p = $p['plugin'];
  49. $tablePrefix = $GLOBALS['POOL']->config->getTablePrefix();
  50. $blogTablePrefix = $tablePrefix.$p->getParameter($parts['coll']->uri,"tableprefix");
  51. $query = 'SELECT blogposts.post_uri, blogposts.id,
  52. blogposts.post_title,
  53. blogposts.post_uri,
  54. users.user_login,
  55. unix_timestamp(blogposts.post_date) as unixtime,
  56. blogposts.post_comment_mode
  57. from '.$blogTablePrefix.'blogposts as blogposts left join '.$tablePrefix.'users as users on blogposts.post_author = users.user_login
  58. where blogposts.id = "'.$fields['id'].'" ';
  59. $res = $GLOBALS['POOL']->db->query($query);
  60. $row = $res->fetchRow(MDB2_FETCHMODE_ASSOC);
  61. if(isset($fields['captcha'])) {
  62. if (!$this->checkCaptcha($fields['captcha'], $fields['imgid'])) {
  63. return false;
  64. }
  65. }
  66. if ($row['post_comment_mode'] == 99) {
  67. $row['post_comment_mode'] = $GLOBALS['POOL']->config->blogDefaultPostCommentMode;
  68. }
  69. if (!($row['post_comment_mode'] == 2 || ($row['post_comment_mode'] == 1 && (time() - 2678800) < $row['unixtime']))) {
  70. die("No comments allowed anymore...");
  71. }
  72. /* flood-protection */
  73. /*$query = "SELECT unix_timestamp(comment_date) FROM ".$blogTablePrefix."blogcomments WHERE comment_author_IP='".$_SERVER['REMOTE_ADDR']."' ORDER BY comment_date DESC LIMIT 1";
  74. $res = $GLOBALS['POOL']->db->query($query);
  75. $time_lastcomment = $res->fetchOne(0);
  76. if (time() - $time_lastcomment) < 60){
  77. die ("Flood protection! You're not allowed to post comments within that short of a timespan");
  78. } */
  79. /* end flood-protection */
  80. $fields['uri'] = BX_WEBROOT_W.$parts['coll']->uri.'archive/'.date('Y',$row['unixtime']).'/'.date('m',$row['unixtime']).'/'.date('d',$row['unixtime']).'/'.$row['post_uri'].'.html';
  81. $screenNode = $this->parent->confctxt->query("/bxco:wizard/bxco:screen[@emailTo]");
  82. $screenNode = $screenNode->item(0);
  83. // clean up comment
  84. if (class_exists('tidy')) {
  85. $tidy = new tidy();
  86. if(!$tidy) {
  87. throw new Exception("Something went wrong with tidy initialisation. Maybe you didn't enable ext/tidy in your PHP installation. Either install it or remove the tidy transformer from your sitemap.xml");
  88. }
  89. } else {
  90. $tidy = false;
  91. }
  92. // this preg escapes all not allowed tags...
  93. $_tags = implode("|",$this->allowedTags).")])#i";
  94. $fields['comments'] = preg_replace("#\<(/[^(".$_tags,"&lt;$1", $fields['comments']);
  95. $fields['comments'] = preg_replace("#\<([^(/|".$_tags,"&lt;$1", $fields['comments']);
  96. $allowedTagsString = "<".implode("><",$this->allowedTags).">";
  97. if ($tidy) {
  98. $tidy->parseString(strip_tags(nl2br($fields['comments']),$allowedTagsString ),$this->tidyOptions,"utf8");
  99. $tidy->cleanRepair();
  100. $fields['comments'] = popoon_classes_externalinput::basicClean((string) $tidy);
  101. // and tidy it again
  102. $tidy->parseString($fields['comments']);
  103. $tidy->cleanRepair();
  104. $fields['comments'] = (string) $tidy;
  105. } else {
  106. $fields['comments'] = popoon_classes_externalinput::basicClean(strip_tags(nl2br($fields['comments']),$allowedTagsString));
  107. }
  108. $commentRejected = "";
  109. /* known spammer user */
  110. $simplecache = popoon_helpers_simplecache::getInstance();
  111. $simplecache->cacheDir = BX_TEMP_DIR;
  112. $deleteIt = false;
  113. //check for pineapleproxy
  114. if (isset($_SERVER['HTTP_VIA']) && stripos($_SERVER['HTTP_VIA'],'pinappleproxy') !== false) {
  115. $commentRejected .= "* Uses known spammer proxy: ". $_SERVER['HTTP_VIA'] . "\n";
  116. }
  117. //get latest spammer name list every 6 hours
  118. /*
  119. $this->knownspammers = $simplecache->simpleCacheRemoteArrayRead("http://www.bitflux.org/download/antispam/knownspammer.dat",21600);
  120. if (in_array(strtolower(preg_replace("#[^a-z]#i","",$fields['name'])),$this->knownspammers)) {
  121. $commentRejected .= "* Known spammer name: " . $fields['name'] ."\n";
  122. $deleteIt = true;
  123. }*/
  124. /* If url field is filled in, it was a bot ...*/
  125. if (isset($fields['url']) && $fields['url'] != "") {
  126. $commentRejected .= "* URL field was not empty, assuming bot: " . $fields['url']."\n";
  127. $deleteIt = true;
  128. }
  129. /* Max 5 links per post and SURBL check */
  130. if (preg_match_all("#http://[\/\w\.\-]+#",$fields['comments'], $matches) || $fields['base'] != '') {
  131. if ($fields['base'] != '') {
  132. $matches[0][] = $fields['base'] ;
  133. }
  134. if (isset($matches[0])) {
  135. $urls = array_unique($matches[0]);
  136. if ( count($urls) > 5) {
  137. $commentRejected .= "* More than 5 unique links in comment (".count($urls) .")\n";
  138. if (count($urls) > 10) {
  139. $deleteIt = true;
  140. }
  141. }
  142. $commentRejected .= bx_plugins_blog_spam::checkRBLs($urls);
  143. }
  144. }
  145. //check sender IP against xbl.spamhaus.org
  146. $xblcheck = bx_plugins_blog_spam::checkSenderIPBLs($_SERVER['REMOTE_ADDR']);
  147. if (!$commentRejected) {
  148. // insert comment
  149. $comment_status = 1;
  150. } else if ($deleteIt) {
  151. $comment_status = 3;
  152. } else {
  153. $comment_status = 2;
  154. }
  155. //delete all rejected comments older than 3 days...
  156. $query = 'delete from '.$blogTablePrefix.'blogcomments where comment_status = 3 and now() - comment_date > 3600 * 24 * 3';
  157. $res = $GLOBALS['POOL']->dbwrite->query($query);
  158. //delete all moderated comments older than 14 days...
  159. $query = 'delete from '.$blogTablePrefix.'blogcomments where comment_status = 2 and now() - comment_date > 3600 * 24 * 14';
  160. $res = $GLOBALS['POOL']->dbwrite->query($query);
  161. $emailFrom = str_replace(":"," ",html_entity_decode($fields['name'],ENT_QUOTES,'ISO-8859-1'));
  162. if ($fields['email']) {
  163. $emailFrom .= ' <'.html_entity_decode($fields['email'],ENT_QUOTES,'ISO-8859-1').'>';
  164. } else {
  165. $emailFrom .= ' <unknown@example.org>';
  166. }
  167. // check if emailFrom is a valid input. if not -> reject!!!
  168. if(strpos($emailFrom, "\n") !== FALSE or strpos($emailFrom, "\r") !== FALSE) {
  169. print ("Comment rejected. Looks like you're trying to spam the world....");
  170. die();
  171. }
  172. $comment_notification_hash = bx_helpers_int::getRandomHex(var_export($fields,true));
  173. $db = $GLOBALS['POOL']->dbwrite;
  174. if (!isset($fields['comment_notification'])) {
  175. $fields['comment_notification'] = 0;
  176. }
  177. $query = 'insert into '.$blogTablePrefix.'blogcomments (comment_posts_id, comment_author, comment_author_email, comment_author_ip,
  178. comment_date, comment_content,comment_status, comment_notification, comment_notification_hash,
  179. comment_author_url
  180. ) VALUES ("'.$row['id'].'",'.$db->quote($fields['name'])
  181. .','.$db->quote($fields['email'],'text').','.$db->quote($fields['remote_ip']).',"'.gmdate('c').'",'.$db->quote(bx_helpers_string::utf2entities($fields['comments'])).','.$comment_status.','.$db->quote($fields['comment_notification']).',"'.$comment_notification_hash.'",'.$db->quote($fields['base'],'text').')';
  182. $res = $GLOBALS['POOL']->dbwrite->query($query);
  183. $GLOBALS['POOL']->dbwrite->loadModule('Extended');
  184. $lastID = $GLOBALS['POOL']->dbwrite->getAfterID(null,$blogTablePrefix.'blogcomments');
  185. $fields['edituri'] = BX_WEBROOT.'admin/?edit=/forms/blogcomments/?id='.$lastID;
  186. $fields['uri'] .= '#comment'.$lastID;
  187. //get email et al
  188. $emailTo = $row['user_login'];
  189. //if ($row['user_email'] && !$deleteIt) {
  190. $emailSubject = '['.bx_helpers_config::getBlogName().'] ' ;
  191. if ($commentRejected) {
  192. $hashPrefix = "a";
  193. if ($deleteIt) {
  194. $emailSubject .= "(Rej) ";
  195. } else {
  196. $emailSubject .= "(Mod) ";
  197. }
  198. $fields['accepturi'] = "(Click the link to accept this comment [1]):\n";
  199. } else {
  200. $hashPrefix = "r";
  201. $fields['accepturi'] = "(Click the link to reject this comment [1]) :\n";
  202. }
  203. // insert hash
  204. if ($GLOBALS['POOL']->config->lastdbversion >= 5266) {
  205. $hash = bx_helpers_int::getRandomHex(var_export($fields,true));
  206. $query = 'update '.$blogTablePrefix.'blogcomments set comment_hash = ' . $GLOBALS['POOL']->db->quote($hashPrefix . $hash) . ' where id = ' . $lastID;
  207. $GLOBALS['POOL']->dbwrite->query($query);
  208. $fields['accepturi'] .= " ".BX_WEBROOT.'admin/webinc/approval/?hash='.$hashPrefix.$hash;
  209. } else {
  210. $fields['accepturi'] .= " Please update your Flux CMS DB to use that feature.";
  211. }
  212. $fields['edituri'] = BX_WEBROOT.'admin/edit/blog/sub/comments/?id='.$lastID;
  213. $emailSubject .= "New comment on '" . html_entity_decode($row['post_title'],ENT_QUOTES,'ISO-8859-1') . "'";
  214. $bodyID = $screenNode->getAttribute('emailBodyID');
  215. if(!empty($bodyID)) {
  216. $emailBodyID = $bodyID;
  217. }
  218. $emailBody = "";
  219. if ($commentRejected) {
  220. $emailBody .= "Comment rejected, due to:\n";
  221. $emailBody .= $commentRejected ."\n";
  222. }
  223. if ($xblcheck) {
  224. $emailBody .= $xblcheck ."\n";
  225. }
  226. if(!empty($emailBodyID)) {
  227. $emailBody .= utf8_decode($this->parent->lookup($emailBodyID));
  228. $this->parent->_replaceTextFields($emailBody, $fields);
  229. $emailBody = html_entity_decode($emailBody,ENT_QUOTES,'UTF-8');
  230. } else {
  231. foreach ($fields as $key => $value) {
  232. $emailBody .= html_entity_decode("$key: $value",ENT_QUOTES,'UTF-8')."\n";
  233. }
  234. }
  235. $headers = '';
  236. if(!empty($emailFrom)) {
  237. $headers .= "From: $emailFrom\r\n";
  238. }
  239. //utf 8 encoded...
  240. //FIXME: do the same for subjects with quoted printable
  241. $headers .= "Content-Type: text/plain; charset=UTF-8\r\nContent-Transfer-Encoding: 8bit\r\n";
  242. $emailBody = str_replace('<br />','',$emailBody);
  243. //don't send mails on rejects for the time beeing
  244. if ($GLOBALS['POOL']->config->blogSendRejectedCommentNotification == "true" || !$deleteIt) {
  245. bx_notificationmanager::sendToDefault($emailTo,$emailSubject, $emailBody,$emailFrom);
  246. }
  247. $_SESSION["bx_wizard"] = array();
  248. if(!$commentRejected) {
  249. bx_plugins_blog_commentsnotification::sendNotificationMails($lastID,$row['id'],$parts['coll']->uri);
  250. header ('Location: '. bx_helpers_uri::getLocationUri($row["post_uri"]) . '.html?sent='.time().'#comment'.$lastID);
  251. } else {
  252. //put it in the db;
  253. $query = 'update '.$blogTablePrefix.'blogcomments set comment_rejectreason = ' . $GLOBALS['POOL']->db->quote(htmlspecialchars($commentRejected)) . ' where id = ' . $lastID;
  254. $res = $GLOBALS['POOL']->dbwrite->query($query);
  255. if ($deleteIt) {
  256. print ("Comment rejected. Looks like blogspam.");
  257. } else {
  258. print ("<h1>Possible blogspam</h1>Your comment is considered as possible blogspam and therefore moderated. <br/> If it's legitimate, the author will make it available later.<br/> Your message is not lost ;) <br/>Thanks for your understanding.<p/>");
  259. print ("The reasons are: <br/>");
  260. print nl2br(htmlspecialchars($commentRejected));
  261. }
  262. }
  263. exit();
  264. return TRUE;
  265. }
  266. protected function checkCaptcha($captcha, $imgid) {
  267. $days = $GLOBALS['POOL']->config->blogCaptchaAfterDays;
  268. $ok = false;
  269. $magickey = $GLOBALS['POOL']->config->magicKey;
  270. preg_match("#.*.html#", $_SERVER['REQUEST_URI'], $matches);
  271. if($imgid == md5($captcha.floor(time()/(60*15)).$magickey.$_SERVER['REMOTE_ADDR'].$matches['0']) or $imgid == md5($captcha.floor(time()/(60*15-1)).$magickey.$_SERVER['REMOTE_ADDR'].$matches['0'])) {
  272. unlink(BX_PROJECT_DIR.'dynimages/'.$imgid . '.png');
  273. return true;
  274. } else {
  275. unlink(BX_PROJECT_DIR.'dynimages/'.$imgid . '.png');
  276. echo '<script type="text/javascript">alert("False captcha code!!! Please enter the right one from image")</script>';
  277. return false;
  278. }
  279. }
  280. }
  281. ?>