PageRenderTime 59ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/administrator/components/com_kunena/libraries/forum/message/message.php

https://bitbucket.org/ceoaliongroo/joomla-kunena-points
PHP | 834 lines | 625 code | 84 blank | 125 comment | 177 complexity | 37432f04dd073b602a10ca35861e3b9b MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, JSON, GPL-2.0
  1. <?php
  2. /**
  3. * Kunena Component
  4. * @package Kunena.Framework
  5. * @subpackage Forum.Message
  6. *
  7. * @copyright (C) 2008 - 2012 Kunena Team. All rights reserved.
  8. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
  9. * @link http://www.kunena.org
  10. **/
  11. defined ( '_JEXEC' ) or die ();
  12. jimport ('joomla.user.helper');
  13. jimport ('joomla.mail.helper');
  14. /**
  15. * Kunena Forum Message Class
  16. */
  17. class KunenaForumMessage extends KunenaDatabaseObject {
  18. public $id = null;
  19. protected $_table = 'KunenaMessages';
  20. protected $_db = null;
  21. protected $_attachments_add = array();
  22. protected $_attachments_del = array();
  23. protected $_topic = null;
  24. protected $_hold = 1;
  25. protected $_thread = 0;
  26. /**
  27. * Constructor
  28. *
  29. * @access protected
  30. */
  31. public function __construct($properties = null) {
  32. $this->_db = JFactory::getDBO ();
  33. parent::__construct($properties);
  34. }
  35. public function __destruct() {
  36. unset($this->_db);
  37. unset($this->_topic);
  38. }
  39. /**
  40. * Returns KunenaForumMessage object
  41. *
  42. * @access public
  43. * @param identifier The message to load - Can be only an integer.
  44. * @return KunenaForumMessage The message object.
  45. * @since 1.7
  46. */
  47. static public function getInstance($identifier = null, $reload = false) {
  48. return KunenaForumMessageHelper::get($identifier, $reload);
  49. }
  50. public function isNew($user = null) {
  51. $user = KunenaUserHelper::get($user);
  52. if (!KunenaFactory::getConfig()->shownew || !$user->exists()) {
  53. return false;
  54. }
  55. $session = KunenaFactory::getSession ();
  56. if ($this->time < $session->lasttime) {
  57. return false;
  58. }
  59. $allreadtime = KunenaForumCategoryUserHelper::get($this->getCategory(), $user)->allreadtime;
  60. if ($allreadtime && $this->time < JFactory::getDate($allreadtime)->toUnix()) {
  61. return false;
  62. }
  63. $read = KunenaForumTopicUserReadHelper::get($this->getTopic(), $user);
  64. if ($this->id == $read->message_id || $this->time < $read->time) {
  65. return false;
  66. }
  67. return true;
  68. }
  69. public function getUrl($category = null, $xhtml = true) {
  70. return $this->getTopic()->getUrl($category, $xhtml, $this);
  71. }
  72. public function getUri($category = null) {
  73. return $this->getTopic()->getUri($category, $this);
  74. }
  75. /**
  76. * Get permament topic URL without domain.
  77. *
  78. * If you want to add domain (for email etc), you can prepend the output with this:
  79. * JUri::getInstance()->toString(array('scheme', 'host', 'port'))
  80. *
  81. * @param KunenaForumCategory $category
  82. * @param bool $xhtml
  83. * @param mixed $action
  84. * @return string
  85. */
  86. public function getPermaUrl($category = null, $xhtml = true) {
  87. $uri = $this->getPermaUri($category);
  88. return KunenaRoute::_($uri, $xhtml);
  89. }
  90. public function getPermaUri($category = null) {
  91. $category = $category ? KunenaForumCategoryHelper::get($category) : $this->getCategory();
  92. if (!$this->exists() || !$category->exists()) return null;
  93. $uri = JURI::getInstance("index.php?option=com_kunena&view=topic&catid={$category->id}&id={$this->thread}&mesid={$this->id}");
  94. return $uri;
  95. }
  96. public function newReply($fields=array(), $user=null, $safefields=null) {
  97. $user = KunenaUserHelper::get($user);
  98. $topic = $this->getTopic();
  99. $category = $this->getCategory();
  100. $message = new KunenaForumMessage();
  101. $message->setTopic($topic);
  102. $message->parent = $this->id;
  103. $message->thread = $topic->id;
  104. $message->catid = $topic->category_id;
  105. $message->name = $user->getName('');
  106. $message->userid = $user->userid;
  107. $message->subject = $this->subject;
  108. $message->ip = $_SERVER ["REMOTE_ADDR"];
  109. if ($topic->hold) {
  110. // If topic was unapproved or deleted, use the same state for the new message
  111. $message->hold = $topic->hold;
  112. } else {
  113. // Otherwise message is either unapproved or published depending if the category is moderated or not
  114. $message->hold = $category->review ? (int)!$category->authorise ('moderate', $user, true) : 0;
  115. }
  116. if ($fields === true) {
  117. $user = KunenaFactory::getUser($this->userid);
  118. $text = preg_replace('/\[confidential\](.*?)\[\/confidential\]/su', '', $this->message );
  119. $message->message = "[quote=\"{$user->getName($this->name)}\" post={$this->id}]" . $text . "[/quote]";
  120. } else {
  121. if (is_array($safefields)) $message->bind($safefields);
  122. if (is_array($fields)) $message->bind($fields, array ('name', 'email', 'subject', 'message' ), true);
  123. }
  124. return array($topic, $message);
  125. }
  126. /**
  127. * Send email notifications from the message.
  128. *
  129. * @param string $url
  130. */
  131. public function sendNotification($url=null) {
  132. $config = KunenaFactory::getConfig();
  133. if (!$config->get('send_emails')) {
  134. return;
  135. }
  136. if ($this->hold > 1) {
  137. return;
  138. } elseif ($this->hold == 1) {
  139. $mailsubs = 0;
  140. $mailmods = $config->mailmod >= 0;
  141. $mailadmins = $config->mailadmin >= 0;
  142. } else {
  143. $mailsubs = (bool) $config->allowsubscriptions;
  144. $mailmods = $config->mailmod >= 1;
  145. $mailadmins = $config->mailadmin >= 1;
  146. }
  147. $once = false;
  148. if ($mailsubs) {
  149. if (!$this->parent) {
  150. // New topic: Send email only to category subscribers
  151. $mailsubs = $config->category_subscriptions != 'disabled' ? KunenaAccess::CATEGORY_SUBSCRIPTION : 0;
  152. $once = $config->category_subscriptions == 'topic';
  153. } elseif ($config->category_subscriptions != 'post') {
  154. // Existing topic: Send email only to topic subscribers
  155. $mailsubs = $config->topic_subscriptions != 'disabled' ? KunenaAccess::TOPIC_SUBSCRIPTION : 0;
  156. $once = $config->topic_subscriptions == 'first';
  157. } else {
  158. // Existing topic: Send email to both category and topic subscribers
  159. $mailsubs = $config->topic_subscriptions == 'disabled' ? KunenaAccess::CATEGORY_SUBSCRIPTION : KunenaAccess::CATEGORY_SUBSCRIPTION | KunenaAccess::TOPIC_SUBSCRIPTION;
  160. // FIXME: category subcription can override topic
  161. $once = $config->topic_subscriptions == 'first';
  162. }
  163. }
  164. if (!$url) {
  165. $url = JUri::getInstance()->toString(array('scheme', 'host', 'port')) . $this->getPermaUrl(null);
  166. }
  167. //get all subscribers, moderators and admins who will get the email
  168. $me = KunenaUserHelper::get();
  169. $acl = KunenaAccess::getInstance();
  170. $emailToList = $acl->getSubscribers($this->catid, $this->thread, $mailsubs, $mailmods, $mailadmins, $me->userid);
  171. $topic = $this->getTopic();
  172. if (count ( $emailToList )) {
  173. jimport('joomla.mail.helper');
  174. if (! $config->getEmail() ) {
  175. KunenaError::warning ( JText::_ ( 'COM_KUNENA_EMAIL_DISABLED' ) );
  176. return false;
  177. } elseif ( ! JMailHelper::isEmailAddress ( $config->getEmail() ) ) {
  178. KunenaError::warning ( JText::_ ( 'COM_KUNENA_EMAIL_INVALID' ) );
  179. return false;
  180. }
  181. // clean up the message for review
  182. $message = KunenaHtmlParser::stripBBCode ( $this->message, 0, false );
  183. $mailsender = JMailHelper::cleanAddress ( $config->board_title );
  184. $mailsubject = JMailHelper::cleanSubject ( "[" . $config->board_title . "] " . $topic->subject . " (" . $this->getCategory()->name . ")" );
  185. $subject = $this->subject ? $this->subject : $topic->subject;
  186. // Make a list from all receivers
  187. $sentusers = array();
  188. $receivers = array(0=>array(), 1=>array());
  189. foreach ( $emailToList as $emailTo ) {
  190. if (! $emailTo->email || ! JMailHelper::isEmailAddress ( $emailTo->email )) {
  191. continue;
  192. }
  193. $receivers[$emailTo->subscription][] = $emailTo->email;
  194. $sentusers[] = $emailTo->id;
  195. }
  196. // Create email
  197. $mail = JFactory::getMailer();
  198. $mail->setSubject($mailsubject);
  199. $mail->setSender(array($config->getEmail(), $mailsender));
  200. // Send email to all subscribers
  201. if (!empty($receivers[1])) {
  202. $mail->setBody($this->createEmailBody(1, $subject, $url, $message, $once));
  203. $this->sendEmail($mail, $receivers[1]);
  204. }
  205. // Send email to all moderators
  206. if (!empty($receivers[0])) {
  207. $mail->setBody($this->createEmailBody(0, $subject, $url, $message, $once));
  208. $this->sendEmail($mail, $receivers[0]);
  209. }
  210. // Update subscriptions
  211. if ($once && $sentusers) {
  212. $sentusers = implode (',', $sentusers);
  213. $db = JFactory::getDBO();
  214. $query = "UPDATE #__kunena_user_topics SET subscribed=2 WHERE topic_id={$this->thread} AND user_id IN ({$sentusers}) AND subscribed=1";
  215. $db->setQuery ($query);
  216. $db->query ();
  217. KunenaError::checkDatabaseError();
  218. }
  219. }
  220. }
  221. public function publish($value=KunenaForum::PUBLISHED) {
  222. if ($this->hold == $value)
  223. return true;
  224. $this->hold = (int)$value;
  225. $result = $this->save();
  226. return $result;
  227. }
  228. public function getTopic() {
  229. if (!$this->_topic) {
  230. $this->_topic = KunenaForumTopicHelper::get($this->thread);
  231. }
  232. return $this->_topic;
  233. }
  234. public function setTopic($topic) {
  235. $this->_topic = $topic;
  236. if ($topic->id) $this->thread = $topic->id;
  237. }
  238. public function getUserTopic($user=null) {
  239. return $this->getTopic()->getUserTopic($user);
  240. }
  241. public function getThankyou() {
  242. return KunenaForumMessageThankyouHelper::get($this->id);
  243. }
  244. public function getCategory() {
  245. return KunenaForumCategoryHelper::get($this->catid);
  246. }
  247. public function getParent() {
  248. return KunenaForumMessageHelper::get($this->parent);
  249. }
  250. public function getAuthor() {
  251. return KunenaUserHelper::getAuthor($this->userid, $this->name);
  252. }
  253. public function getModifier() {
  254. return KunenaUserHelper::get($this->modified_by);
  255. }
  256. public function displayField($field) {
  257. switch ($field) {
  258. case 'id':
  259. return intval($this->id);
  260. case 'subject':
  261. return KunenaHtmlParser::parseText($this->subject);
  262. case 'message':
  263. // FIXME: add context to BBCode parser (and fix logic in the parser)
  264. return KunenaHtmlParser::parseBBCode($this->message);
  265. }
  266. }
  267. public function authorise($action='read', $user=null, $silent=false) {
  268. if ($action == 'none') return true;
  269. static $actions = array(
  270. 'none'=>array(),
  271. 'read'=>array('Read'),
  272. 'reply'=>array('Read','NotHold'),
  273. 'edit'=>array('Read','Own','EditTime'),
  274. 'move'=>array('Read'),
  275. 'approve'=>array('Read'),
  276. 'delete'=>array('Read','Own','EditTime', 'Delete'),
  277. 'thankyou'=>array('Read', 'Thankyou'),
  278. 'unthankyou'=>array('Read'),
  279. 'undelete'=>array('Read'),
  280. 'permdelete'=>array('Read'),
  281. 'attachment.read'=>array('Read'),
  282. 'attachment.create'=>array('Read','Own','EditTime'),
  283. 'attachment.delete'=>array(), // TODO: In the future we might want to restrict this: array('Read','EditTime'),
  284. );
  285. $user = KunenaUserHelper::get($user);
  286. if (!isset($actions[$action])) {
  287. if (!$silent) $this->setError ( __CLASS__.'::'.__FUNCTION__.'(): '.JText::sprintf ( 'COM_KUNENA_LIB_AUTHORISE_INVALID_ACTION', $action ) );
  288. return false;
  289. }
  290. $topic = $this->getTopic();
  291. $auth = $topic->authorise('post.'.$action, $user, $silent);
  292. if (!$auth) {
  293. if (!$silent) $this->setError ( $topic->getError() );
  294. return false;
  295. }
  296. foreach ($actions[$action] as $function) {
  297. $authFunction = 'authorise'.$function;
  298. if (! method_exists($this, $authFunction) || ! $this->$authFunction($user)) {
  299. if (!$silent) $this->setError ( JText::_ ( 'COM_KUNENA_NO_ACCESS' ) );
  300. return false;
  301. }
  302. }
  303. return true;
  304. }
  305. public function edit($fields = array(), $user=null) {
  306. $user = KunenaUserHelper::get($user);
  307. $this->bind($fields, array ('name', 'email', 'subject', 'message', 'modified_reason' ), true);
  308. // Update rest of the information
  309. $category = $this->getCategory();
  310. $this->hold = $category->review ? (int)!$category->authorise ('moderate', $user, true) : 0;
  311. $this->modified_by = $user->userid;
  312. $this->modified_time = JFactory::getDate()->toUnix();
  313. }
  314. public function makeAnonymous($user=null) {
  315. $user = KunenaUserHelper::get($user);
  316. if ($user->userid == $this->userid && $this->modified_by == $this->userid) {
  317. // I am the author and previous modification was made by me => delete modification information to hide my personality
  318. $this->modified_by = 0;
  319. $this->modified_time = 0;
  320. $this->modified_reason = '';
  321. } else if ($user->userid == $this->userid) {
  322. // I am the author, but somebody else has modified the message => leave modification information intact
  323. $this->modified_by = null;
  324. $this->modified_time = null;
  325. $this->modified_reason = null;
  326. }
  327. // Remove userid, email and ip address
  328. $this->userid = 0;
  329. $this->ip = '';
  330. $this->email = '';
  331. }
  332. public function uploadAttachment($tmpid, $postvar, $catid=null) {
  333. $attachment = new KunenaForumMessageAttachment();
  334. $attachment->mesid = $this->id;
  335. $attachment->userid = $this->userid;
  336. $success = $attachment->upload($postvar, $catid);
  337. $this->_attachments_add[$tmpid] = $attachment;
  338. return $success;
  339. }
  340. public function removeAttachment($ids=false) {
  341. if ($ids === false) {
  342. $this->_attachments_del = $this->getAttachments();
  343. } elseif (is_array($ids)) {
  344. if (!empty($ids)) $this->_attachments_del += array_combine($ids, $ids);
  345. } else {
  346. $this->_attachments_del[$ids] = $ids;
  347. }
  348. }
  349. public function getAttachments($ids=false) {
  350. if ($ids === false) {
  351. return KunenaForumMessageAttachmentHelper::getByMessage($this->id);
  352. } else {
  353. $attachments = KunenaForumMessageAttachmentHelper::getById($ids);
  354. foreach ($attachments as $id=>$attachment) if ($attachment->mesid != $this->id) unset($attachments[$id]);
  355. return $attachments;
  356. }
  357. }
  358. protected function updateAttachments() {
  359. // Save new attachments and update message text
  360. $message = $this->message;
  361. foreach ($this->_attachments_add as $tmpid=>$attachment) {
  362. $attachment->mesid = $this->id;
  363. if (!$attachment->save()) {
  364. $this->setError ( $attachment->getError() );
  365. }
  366. // Update attachments count and fix attachment name inside message
  367. if ($attachment->exists()) {
  368. $this->getTopic()->attachments++;
  369. $this->message = preg_replace('/\[attachment\:'.$tmpid.'\].*?\[\/attachment\]/u', "[attachment={$attachment->id}]{$attachment->filename}[/attachment]", $this->message);
  370. }
  371. }
  372. // Delete removed attachments and update attachments count and message text
  373. $attachments = $this->getAttachments(array_keys($this->_attachments_del));
  374. foreach ($attachments as $attachment) {
  375. if (!$attachment->delete()) {
  376. $this->setError ( $attachment->getError() );
  377. } else {
  378. $this->getTopic()->attachments--;
  379. }
  380. $this->message = preg_replace('/\[attachment\='.$attachment->id.'\].*?\[\/attachment\]/u', '', $this->message);
  381. $this->message = preg_replace('/\[attachment\]'.$attachment->filename.'\[\/attachment\]/u', '', $this->message);
  382. }
  383. // Remove missing temporary attachments from the message text
  384. $this->message = trim(preg_replace('/\[attachment\:\d+\].*?\[\/attachment\]/u', '', $this->message));
  385. // Return true if we changed the message contents
  386. return ($this->message != $message);
  387. }
  388. /**
  389. * Method to load a KunenaForumMessage object by id
  390. *
  391. * @param mixed $id The message id to be loaded
  392. * @return boolean True on success
  393. */
  394. public function load($id = null) {
  395. $exists = parent::load($id);
  396. $this->_hold = $exists ? $this->hold : 1;
  397. $this->_thread = $this->thread;
  398. return $exists;
  399. }
  400. /**
  401. * Method to save the KunenaForumMessage object to the database
  402. *
  403. * @return boolean True on success
  404. */
  405. public function save() {
  406. $isNew = ! $this->_exists;
  407. $topic = $this->getTopic();
  408. if (!$topic->exists()) {
  409. // Create topic, but do not cascade changes to category etc..
  410. if (!$topic->save(false)) {
  411. $this->setError ( $topic->getError () );
  412. return false;
  413. }
  414. $this->_thread = $this->thread = $topic->id;
  415. }
  416. // Create message
  417. if (! parent::save ()) {
  418. return false;
  419. }
  420. if ($isNew) {
  421. $this->_hold = 1;
  422. }
  423. // Update attachments and message text
  424. $update = $this->updateAttachments();
  425. // Did we change anything?
  426. if ($update) {
  427. $table = $this->getTable ();
  428. $table->bind ( $this->getProperties () );
  429. $table->exists(true);
  430. if (! $table->store ()) {
  431. $this->setError ( $table->getError () );
  432. return false;
  433. }
  434. }
  435. // Cascade changes to other tables
  436. $this->update();
  437. return true;
  438. }
  439. /**
  440. * Method to delete the KunenaForumMessage object from the database
  441. *
  442. * @access public
  443. * @return boolean True on success
  444. * @since 1.6
  445. */
  446. public function delete() {
  447. if (!$this->exists()) {
  448. return true;
  449. }
  450. if (!parent::delete()) {
  451. return false;
  452. }
  453. $this->hold = 1;
  454. $attachments = $this->getAttachments();
  455. foreach ($attachments as $attachment) {
  456. if (!$attachment->delete()) {
  457. $this->setError ( $attachment->getError() );
  458. }
  459. }
  460. $db = JFactory::getDBO ();
  461. // Delete thank yous
  462. $queries[] = "DELETE FROM #__kunena_thankyou WHERE postid={$db->quote($this->id)}";
  463. // Delete message
  464. $queries[] = "DELETE FROM #__kunena_messages_text WHERE mesid={$db->quote($this->id)}";
  465. // Cascade changes into other tables
  466. $this->update();
  467. foreach ($queries as $query) {
  468. $db->setQuery($query);
  469. $db->query();
  470. KunenaError::checkDatabaseError ();
  471. }
  472. KunenaForumMessageThankyouHelper::recount();
  473. return true;
  474. }
  475. public function check() {
  476. $author = KunenaUserHelper::get($this->userid);
  477. // Check username
  478. if (! $this->userid) {
  479. $this->name = trim($this->name);
  480. // Unregistered or anonymous users: Do not allow existing username
  481. $nicktaken = JUserHelper::getUserId ( $this->name );
  482. if (empty ( $this->name ) || $nicktaken) {
  483. $this->name = JText::_ ( 'COM_KUNENA_USERNAME_ANONYMOUS' );
  484. }
  485. } else {
  486. $this->name = $author->getName();
  487. }
  488. // Check email address
  489. $this->email = trim($this->email);
  490. if ($this->email) {
  491. // Email address must be valid
  492. if (! JMailHelper::isEmailAddress ( $this->email )) {
  493. $this->setError ( JText::sprintf ( 'COM_KUNENA_LIB_MESSAGE_ERROR_EMAIL_INVALID' ) );
  494. return false;
  495. }
  496. } else if (! KunenaUserHelper::getMyself()->exists() && KunenaFactory::getConfig()->askemail) {
  497. $this->setError ( JText::_ ( 'COM_KUNENA_LIB_MESSAGE_ERROR_EMAIL_EMPTY' ) );
  498. return false;
  499. }
  500. // Do not allow no posting date or dates from the future
  501. $now = JFactory::getDate()->toUnix();
  502. if (!$this->time || $this->time > $now) {
  503. $this->time = $now;
  504. }
  505. // Do not allow indentical posting times inside topic (simplifies logic)
  506. $topic = $this->getTopic();
  507. if (!$this->exists() && $topic->exists() && $this->time <= $topic->last_post_time) {
  508. $this->time = $topic->last_post_time + 1;
  509. }
  510. if ($this->modified_time > $now) {
  511. $this->modified_time = $now;
  512. }
  513. if ($this->modified_time && $this->modified_time < $this->time) {
  514. $this->modified_time = $this->time;
  515. }
  516. if ($this->hold < 0 || $this->hold > 3) {
  517. $this->setError ( JText::_ ( 'COM_KUNENA_LIB_MESSAGE_ERROR_HOLD_INVALID' ) );
  518. return false;
  519. }
  520. if ($this->modified_by !== null) {
  521. if (!$this->modified_by) {
  522. $this->modified_time = 0;
  523. $this->modified_reason = '';
  524. } elseif (!$this->modified_time) {
  525. $this->modified_time = JFactory::getDate()->toUnix();
  526. }
  527. }
  528. // Flood protection
  529. $config = KunenaFactory::getConfig();
  530. if ($config->floodprotection && ! $this->getCategory()->authorise('moderate') ) {
  531. $this->_db->setQuery ( "SELECT MAX(time) FROM #__kunena_messages WHERE ip={$this->_db->quote($this->ip)}" );
  532. $lastPostTime = $this->_db->loadResult ();
  533. if ($this->_db->getErrorNum()) {
  534. $this->setError ( $this->_db->getErrorMsg() );
  535. return false;
  536. }
  537. if ($lastPostTime + $config->floodprotection > JFactory::getDate()->toUnix()) {
  538. $this->setError ( JText::sprintf ( 'COM_KUNENA_LIB_MESSAGE_ERROR_FLOOD', (int)$config->floodprotection ) );
  539. return false;
  540. }
  541. }
  542. if (!$this->exists()) {
  543. // Ignore identical messages (posted within 5 minutes)
  544. $duplicatetimewindow = JFactory::getDate ()->toUnix() - 5 * 60;
  545. $this->_db->setQuery ( "SELECT m.id FROM #__kunena_messages AS m INNER JOIN #__kunena_messages_text AS t ON m.id=t.mesid
  546. WHERE m.userid={$this->_db->quote($this->userid)}
  547. AND m.ip={$this->_db->quote($this->ip)}
  548. AND t.message={$this->_db->quote($this->message)}
  549. AND m.time>={$this->_db->quote($duplicatetimewindow)}" );
  550. $id = $this->_db->loadResult ();
  551. if ($this->_db->getErrorNum()) {
  552. $this->setError ( $this->_db->getErrorMsg() );
  553. return false;
  554. }
  555. if ($id) {
  556. $this->setError ( JText::_ ( 'COM_KUNENA_POST_DUPLICATE_IGNORED' ) );
  557. return false;
  558. }
  559. }
  560. return true;
  561. }
  562. // Internal functions
  563. protected function update() {
  564. // If post was published and then moved, we need to update old topic
  565. if (!$this->_hold && $this->_thread && $this->_thread != $this->thread) {
  566. $topic = KunenaForumTopicHelper::get($this->_thread);
  567. if (! $topic->update($this, -1)) {
  568. $this->setError ( $topic->getError () );
  569. }
  570. }
  571. $postDelta = $this->delta(true);
  572. $topic = $this->getTopic();
  573. // Create / update topic
  574. if (!$this->hold && $topic->hold && $topic->exists()) {
  575. // We published message -> publish and recount topic
  576. $topic->hold = 0;
  577. $topic->recount();
  578. } elseif (! $topic->update($this, $postDelta)) {
  579. $this->setError ( $topic->getError () );
  580. }
  581. // Activity integration
  582. $dispatcher = JDispatcher::getInstance();
  583. JPluginHelper::importPlugin('finder');
  584. $activity = KunenaFactory::getActivityIntegration();
  585. if ($postDelta < 0) {
  586. $dispatcher->trigger('onDeleteKunenaPost', array(array($this->id)));
  587. $activity->onAfterDelete($this);
  588. } elseif ($postDelta > 0) {
  589. $topic->markRead();
  590. if ($this->parent == 0) {
  591. $activity->onAfterPost($this);
  592. } else {
  593. $activity->onAfterReply($this);
  594. }
  595. }
  596. }
  597. protected function authoriseRead($user) {
  598. // Check that user has the right to see the post (user can see his own unapproved posts)
  599. if ($this->hold > 1 || ($this->hold == 1 && $this->userid != $user->userid)) {
  600. $access = KunenaAccess::getInstance();
  601. $hold = $access->getAllowedHold($user->userid, $this->catid, false);
  602. if (!in_array($this->hold, $hold)) {
  603. $this->setError ( JText::_ ( 'COM_KUNENA_NO_ACCESS' ) );
  604. return false;
  605. }
  606. }
  607. return true;
  608. }
  609. protected function authoriseNotHold($user) {
  610. if ($this->hold) {
  611. // Nobody can reply to unapproved or deleted post
  612. $this->setError ( JText::_ ( 'COM_KUNENA_NO_ACCESS' ) );
  613. return false;
  614. }
  615. return true;
  616. }
  617. protected function authoriseOwn($user) {
  618. // Check that topic owned by the user or user is a moderator
  619. // TODO: check #__kunena_user_topics
  620. if ((!$this->userid || $this->userid != $user->userid) && !$user->isModerator($this->getCategory())) {
  621. $this->setError ( JText::_ ( 'COM_KUNENA_POST_EDIT_NOT_ALLOWED' ) );
  622. return false;
  623. }
  624. return true;
  625. }
  626. protected function authoriseThankyou($user) {
  627. // Check that message is not your own
  628. if(!KunenaFactory::getConfig()->showthankyou) {
  629. $this->setError ( JText::_ ( 'COM_KUNENA_THANKYOU_DISABLED' ) );
  630. return false;
  631. }
  632. if (!$user->userid || !$this->userid || $this->userid == $user->userid) {
  633. // TODO: better error message
  634. $this->setError ( JText::_ ( 'COM_KUNENA_THANKYOU_DISABLED' ) );
  635. return false;
  636. }
  637. return true;
  638. }
  639. /**
  640. * This function check the edit time for the author of the author
  641. * of the post and return if the user is allwoed or not to edit
  642. * her post
  643. *
  644. * @param timestamp $messagemodifiedtime Time when the message has been edited
  645. * @param timestamp $messagetime Actual message time
  646. */
  647. protected function authoriseEditTime($user) {
  648. // Do not perform rest of the checks to moderators and admins
  649. if ($user->isModerator($this->getCategory())) {
  650. return true;
  651. }
  652. // User is only allowed to edit post within time specified in the configuration
  653. $config = KunenaFactory::getConfig ();
  654. if (intval($config->useredit) != 1) {
  655. $this->setError ( JText::_ ( 'COM_KUNENA_POST_EDIT_NOT_ALLOWED' ) );
  656. return false;
  657. }
  658. if (intval($config->useredittime) == 0) {
  659. return true;
  660. } else {
  661. //Check whether edit is in time
  662. $modtime = $this->modified_time;
  663. if (! $modtime) {
  664. $modtime = $this->time;
  665. }
  666. if ($modtime + intval($config->useredittime)< JFactory::getDate ()->toUnix()) {
  667. $this->setError ( JText::_ ( 'COM_KUNENA_POST_EDIT_NOT_ALLOWED' ) );
  668. return false;
  669. }
  670. }
  671. return true;
  672. }
  673. protected function authoriseDelete($user) {
  674. $config = KunenaFactory::getConfig();
  675. if (!$user->isModerator($this->getCategory())
  676. && $config->userdeletetmessage != '2' && ($config->userdeletetmessage == '0' || $this->getTopic()->last_post_id != $this->id)) {
  677. $this->setError (JText::_ ( 'COM_KUNENA_POST_ERROR_DELETE_REPLY_AFTER' ) );
  678. return false;
  679. }
  680. return true;
  681. }
  682. protected function delta() {
  683. if (!$this->hold && ($this->_hold || $this->thread != $this->_thread)) {
  684. // Publish message or move it into new topic
  685. return 1;
  686. } elseif (!$this->_hold && $this->hold) {
  687. // Unpublish message
  688. return -1;
  689. }
  690. return 0;
  691. }
  692. protected function sendEmail($mail, $receivers) {
  693. $config = KunenaFactory::getConfig();
  694. $email_recipient_count = !empty($config->email_recipient_count) ? $config->email_recipient_count : 1;
  695. $email_recipient_privacy = !empty($config->email_recipient_privacy) ? $config->email_recipient_privacy : 'bcc';
  696. // If we hide email addresses from other users, we need to add TO address to prevent email from becoming spam
  697. if ($email_recipient_count > 1 && $email_recipient_privacy == 'bcc'
  698. && !empty($config->email_visible_address) && JMailHelper::isEmailAddress ( $config->email_visible_address )) {
  699. $mail->AddAddress($config->email_visible_address, JMailHelper::cleanAddress ( $config->board_title ));
  700. // Also make sure that email receiver limits are not violated (TO + CC + BCC = limit)
  701. if ($email_recipient_count > 9) $email_recipient_count--;
  702. }
  703. $chunks = array_chunk($receivers, $email_recipient_count);
  704. foreach ($chunks as $emails) {
  705. if ($email_recipient_count == 1 || $email_recipient_privacy == 'to') {
  706. $mail->ClearAddresses();
  707. $mail->addRecipient($emails);
  708. } elseif ($email_recipient_privacy == 'cc') {
  709. $mail->ClearCCs();
  710. $mail->addCC($emails);
  711. } else {
  712. $mail->ClearBCCs();
  713. $mail->addBCC($emails);
  714. }
  715. $mail->Send();
  716. }
  717. }
  718. protected function createEmailBody($subscription, $subject, $url, $message, $once) {
  719. $config = KunenaFactory::getConfig();
  720. if ($subscription) {
  721. $msg1 = $this->get ( 'parent' ) ? JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION1' ) : JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION1_CAT' );
  722. $msg2 = $this->get ( 'parent' ) ? JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION2' ) : JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION2_CAT' );
  723. } else {
  724. $msg1 = JText::_ ( 'COM_KUNENA_POST_EMAIL_MOD1' );
  725. $msg2 = JText::_ ( 'COM_KUNENA_POST_EMAIL_MOD2' );
  726. }
  727. $msg = $msg1 . " " . $config->board_title . "\n\n";
  728. // DO NOT REMOVE EXTRA SPACE, JMailHelper::cleanBody() removes "Subject:" from the message body
  729. $msg .= JText::_ ( 'COM_KUNENA_MESSAGE_SUBJECT' ) . " : " . $subject . "\n";
  730. $msg .= JText::_ ( 'COM_KUNENA_CATEGORY' ) . " : " . $this->getCategory()->name . "\n";
  731. $msg .= JText::_ ( 'COM_KUNENA_VIEW_POSTED' ) . " : " . $this->getAuthor()->getName('???', false) . "\n\n";
  732. $msg .= "URL : $url\n\n";
  733. if ($config->mailfull == 1) {
  734. $msg .= JText::_ ( 'COM_KUNENA_MESSAGE' ) . " :\n-----\n";
  735. $msg .= $message;
  736. $msg .= "\n-----\n\n";
  737. }
  738. $msg .= $msg2 . "\n";
  739. if ($subscription && $once) {
  740. if ($this->parent) {
  741. $msg .= JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION_MORE_READ' ) . "\n";
  742. } else {
  743. $msg .= JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION_MORE_SUBSCRIBE' ) . "\n";
  744. }
  745. }
  746. $msg .= "\n";
  747. $msg .= JText::_ ( 'COM_KUNENA_POST_EMAIL_NOTIFICATION3' ) . "\n";
  748. return JMailHelper::cleanBody ( $msg );
  749. }
  750. }