PageRenderTime 67ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/campsite/src/classes/ArticleComment.php

https://github.com/joechrysler/Campsite
PHP | 457 lines | 292 code | 49 blank | 116 comment | 57 complexity | 291fd90bac17644896740f13355063e5 MD5 | raw file
Possible License(s): BSD-3-Clause, AGPL-1.0, LGPL-2.1, Apache-2.0
  1. <?php
  2. /**
  3. * @package Campsite
  4. */
  5. /**
  6. * Includes
  7. */
  8. require_once($GLOBALS['g_campsiteDir'].'/include/phorum_load.php');
  9. require_once($GLOBALS['g_campsiteDir'].'/classes/DbObjectArray.php');
  10. require_once($GLOBALS['g_campsiteDir'].'/classes/SQLSelectClause.php');
  11. require_once($GLOBALS['g_campsiteDir'].'/classes/Phorum_message.php');
  12. require_once($GLOBALS['g_campsiteDir'].'/classes/Article.php');
  13. require_once($GLOBALS['g_campsiteDir'].'/classes/CampCacheList.php');
  14. class ArticleComment
  15. {
  16. const DEFAULT_TTL = 30;
  17. /**
  18. * Returns an Article object to which the comment identified
  19. * by the given id belongs to. Returns null if invalid message id.
  20. * @param $p_messageId
  21. * @return Article
  22. */
  23. public static function GetArticleOf($p_messageId)
  24. {
  25. global $g_ado_db;
  26. $p_messageId = (int)$p_messageId;
  27. $sql = "SELECT * FROM ArticleComments WHERE fk_comment_id = $p_messageId";
  28. $res = $g_ado_db->GetAll($sql);
  29. if (is_array($res) && count($res) > 0) {
  30. $articleNo = $res[0]['fk_article_number'];
  31. $languageId = $res[0]['fk_language_id'];
  32. $article = new Article($languageId, $articleNo);
  33. return $article;
  34. }
  35. return null;
  36. }
  37. /**
  38. * Get the comment ID for the given article.
  39. *
  40. * @param int $p_articleNumber
  41. * @param int $p_languageId
  42. * @return int
  43. */
  44. public function GetCommentThreadId($p_articleNumber, $p_languageId)
  45. {
  46. global $g_ado_db;
  47. $queryStr = "SELECT fk_comment_id FROM ArticleComments"
  48. ." WHERE fk_article_number=$p_articleNumber"
  49. ." AND fk_language_id=$p_languageId"
  50. ." AND is_first=1";
  51. $threadId = $g_ado_db->GetOne($queryStr);
  52. return $threadId;
  53. } // fn GetCommentThreadId
  54. /**
  55. * Link the given article to the given comment.
  56. *
  57. * @param int $p_articleNumber
  58. * @param int $p_languageId
  59. * @param int $p_commentId
  60. * @return void
  61. */
  62. public static function Link($p_articleNumber, $p_languageId,
  63. $p_commentId, $p_isFirstMessage = false)
  64. {
  65. global $g_ado_db;
  66. $p_isFirstMessage = $p_isFirstMessage ? '1' : '0';
  67. $queryStr = "INSERT INTO ArticleComments "
  68. ." SET fk_article_number=$p_articleNumber,"
  69. ." fk_language_id=$p_languageId,"
  70. ." fk_comment_id=$p_commentId,"
  71. ." is_first=$p_isFirstMessage";
  72. $g_ado_db->Execute($queryStr);
  73. } // fn Link
  74. /**
  75. * Remove all the entries from the table that match the given parameters.
  76. *
  77. * @param int $p_articleNumber
  78. * @param int $p_languageId
  79. * @param int $p_commentId
  80. */
  81. public static function Unlink($p_articleNumber = null, $p_languageId = null,
  82. $p_commentId = null)
  83. {
  84. global $g_ado_db;
  85. $constraints = array();
  86. if (!is_null($p_articleNumber)) {
  87. $constraints[] = "fk_article_number=$p_articleNumber";
  88. }
  89. if (!is_null($p_languageId)) {
  90. $constraints[] = "fk_language_id=$p_languageId";
  91. }
  92. if (!is_null($p_commentId)) {
  93. $constraints[] = "fk_comment_id=$p_commentId";
  94. }
  95. $queryStr = "DELETE FROM ArticleComments WHERE "
  96. .implode(" AND ", $constraints);
  97. $g_ado_db->Execute($queryStr);
  98. } // fn Unlink
  99. /**
  100. * This function should be called whenever an article is deleted.
  101. *
  102. * @param int $p_articleNumber
  103. * @param int $p_languageId
  104. * @return void
  105. */
  106. public static function OnArticleDelete($p_articleNumber, $p_languageId)
  107. {
  108. if (!is_numeric($p_articleNumber) || !is_numeric($p_languageId)) {
  109. return;
  110. }
  111. $threadId = ArticleComment::GetCommentThreadId($p_articleNumber, $p_languageId);
  112. // Delete all comments for this article
  113. $threadHead = new Phorum_message($threadId);
  114. $threadHead->delete(PHORUM_DELETE_TREE);
  115. // Delete all links to this article.
  116. ArticleComment::Unlink($p_articleNumber, $p_languageId);
  117. } // fn OnArticleDelete
  118. /**
  119. * Get all comments associated with the given article.
  120. *
  121. * @param int $p_articleNumber
  122. * @param int $p_languageId
  123. * @param string $p_status
  124. * This can be NULL if you dont care about the status,
  125. * "approved" or "unapproved".
  126. * @param boolean $p_countOnly
  127. * @return array
  128. */
  129. public static function GetArticleComments($p_articleNumber, $p_languageId,
  130. $p_status = null, $p_countOnly = false,
  131. $p_skipCache = true)
  132. {
  133. global $PHORUM, $g_ado_db;
  134. if (CampCache::IsEnabled() && !$p_skipCache) {
  135. $cacheKey = __METHOD__ . '_' . (int)$p_articleNumber . '_'
  136. . (int)$p_languageId . '_' . $p_status . '_' . (int)$p_count_only;
  137. $result = CampCache::singleton()->fetch($cacheKey);
  138. if ($result !== false) {
  139. return $result;
  140. }
  141. }
  142. $threadId = ArticleComment::GetCommentThreadId($p_articleNumber, $p_languageId);
  143. if (!$threadId) {
  144. $result = $p_countOnly ? 0 : null;
  145. if (CampCache::IsEnabled()) {
  146. CampCache::singleton()->store($cacheKey, $result);
  147. }
  148. return $result;
  149. }
  150. // Are we counting or getting the comments?
  151. $selectClause = "*";
  152. if ($p_countOnly) {
  153. $selectClause = "COUNT(*)";
  154. }
  155. // Only getting comments with a specific status?
  156. $whereClause = "";
  157. if (!is_null($p_status)) {
  158. if ($p_status == "approved") {
  159. $whereClause = " AND status=".PHORUM_STATUS_APPROVED;
  160. } elseif ($p_status == "unapproved") {
  161. $whereClause = " AND status=".PHORUM_STATUS_HIDDEN;
  162. }
  163. }
  164. $queryStr = "SELECT $selectClause "
  165. ." FROM ".$PHORUM['message_table']
  166. ." WHERE thread=$threadId"
  167. ." AND message_id != thread"
  168. . $whereClause
  169. ." ORDER BY message_id";
  170. if ($p_countOnly) {
  171. $result = $g_ado_db->GetOne($queryStr);
  172. } else {
  173. $result = DbObjectArray::Create("Phorum_message", $queryStr);
  174. }
  175. if (CampCache::IsEnabled() && !$p_skipCache) {
  176. CampCache::singleton()->store($cacheKey, $result, self::DEFAULT_TTL);
  177. }
  178. return $result;
  179. } // fn GetArticleComments
  180. /**
  181. * Get the comments and their associated articles.
  182. *
  183. * @param string $p_status
  184. * Can be 'approved' or 'unapproved'.
  185. * @param boolean $p_getTotal
  186. * If TRUE, return the number of comments that match the search
  187. * criteria and not the actual records.
  188. * @param string $p_searchString
  189. * A string to search for.
  190. * @param array $p_sqlOptions
  191. * See DatabaseObject::ProcessOptions().
  192. * @return array
  193. */
  194. public static function GetComments($p_status = 'approved', $p_getTotal = false,
  195. $p_searchString = '', $p_sqlOptions = null)
  196. {
  197. global $PHORUM;
  198. global $g_ado_db;
  199. $messageTable = $PHORUM['message_table'];
  200. $selectClause = "*";
  201. if ($p_getTotal) {
  202. $selectClause = "COUNT(*)";
  203. }
  204. $baseQuery = "SELECT $selectClause FROM ($messageTable"
  205. ." LEFT JOIN ArticleComments "
  206. ." ON $messageTable". ".thread=ArticleComments.fk_comment_id)"
  207. ." LEFT JOIN Articles ON ArticleComments.fk_article_number=Articles.Number"
  208. ." AND ArticleComments.fk_language_id=Articles.IdLanguage";
  209. $whereQuery = "$messageTable.message_id != $messageTable.thread";
  210. if ($p_status == 'approved') {
  211. $whereQuery .= " AND status > 0";
  212. } elseif ($p_status == 'unapproved') {
  213. $whereQuery .= " AND status < 0";
  214. }
  215. if (!empty($p_searchString)) {
  216. $p_searchString = mysql_real_escape_string($p_searchString);
  217. if (!empty($whereQuery)) {
  218. $whereQuery .= " AND ";
  219. }
  220. $whereQuery .="($messageTable.subject LIKE '%$p_searchString%'"
  221. ." OR $messageTable.body LIKE '%$p_searchString%'"
  222. ." OR $messageTable.email LIKE '%$p_searchString%'"
  223. ." OR $messageTable.author LIKE '%$p_searchString%'"
  224. ." OR $messageTable.ip LIKE '%$p_searchString%')";
  225. }
  226. if (!empty($whereQuery)) {
  227. $baseQuery .= " WHERE ".$whereQuery;
  228. }
  229. // Default ORDER BY clause
  230. if (is_null($p_sqlOptions) || !isset($p_sqlOptions['ORDER BY'])) {
  231. $baseQuery .= " ORDER BY ".$PHORUM['message_table'].".message_id";
  232. }
  233. //echo $baseQuery."<br><br>";
  234. if ($p_getTotal) {
  235. $numComments = $g_ado_db->GetOne($baseQuery);
  236. return $numComments;
  237. } else {
  238. $queryStr = DatabaseObject::ProcessOptions($baseQuery, $p_sqlOptions);
  239. //echo $queryStr;
  240. $rows = $g_ado_db->GetAll($queryStr);
  241. $returnArray = array();
  242. if (is_array($rows)) {
  243. foreach ($rows as $row) {
  244. $comment = new Phorum_message();
  245. $comment->fetch($row);
  246. $article = new Article();
  247. $article->fetch($row);
  248. $returnArray[] = array("comment" => $comment, "article" => $article);
  249. }
  250. }
  251. return $returnArray;
  252. }
  253. } // fn GetComments
  254. /**
  255. * Returns an article comments list based on the given parameters.
  256. *
  257. * @param array $p_parameters
  258. * An array of ComparisonOperation objects
  259. * @param string $p_order
  260. * An array of columns and directions to order by
  261. * @param integer $p_start
  262. * The record number to start the list
  263. * @param integer $p_limit
  264. * The offset. How many records from $p_start will be retrieved.
  265. * @param integer $p_count
  266. * The total count of the elements; this count is computed without
  267. * applying the start ($p_start) and limit parameters ($p_limit)
  268. *
  269. * @return array $articleCommentsList
  270. * An array of Comment objects
  271. */
  272. public static function GetList(array $p_parameters, $p_order = null,
  273. $p_start = 0, $p_limit = 0, &$p_count, $p_skipCache = false)
  274. {
  275. global $g_ado_db, $PHORUM;
  276. if (!$p_skipCache && CampCache::IsEnabled()) {
  277. $paramsArray['parameters'] = serialize($p_parameters);
  278. $paramsArray['order'] = (is_null($p_order)) ? 'null' : $p_order;
  279. $paramsArray['start'] = $p_start;
  280. $paramsArray['limit'] = $p_limit;
  281. $cacheListObj = new CampCacheList($paramsArray, __METHOD__, self::DEFAULT_TTL);
  282. $articleCommentsList = $cacheListObj->fetchFromCache();
  283. if ($articleCommentsList !== false && is_array($articleCommentsList)) {
  284. return $articleCommentsList;
  285. }
  286. }
  287. $selectClauseObj = new SQLSelectClause();
  288. $countClauseObj = new SQLSelectClause();
  289. $messageTable = $PHORUM['message_table'];
  290. $selectClauseObj->setTable($messageTable);
  291. $countClauseObj->setTable($messageTable);
  292. $articleNumber = null;
  293. $languageId = null;
  294. // sets the where conditions
  295. foreach ($p_parameters as $param) {
  296. $comparisonOperation = self::ProcessListParameters($param);
  297. if (strtolower($comparisonOperation->getLeftOperand()) == 'fk_article_number') {
  298. $articleNumber = $comparisonOperation->getRightOperand();
  299. }
  300. if (strtolower($comparisonOperation->getLeftOperand()) == 'fk_language_id') {
  301. $languageId = $comparisonOperation->getRightOperand();
  302. }
  303. $parameters[] = $comparisonOperation;
  304. }
  305. if (!is_null($articleNumber) && !is_null($languageId)) {
  306. // gets the thread id for the article
  307. $threadId = ArticleComment::GetCommentThreadId($articleNumber, $languageId);
  308. $selectClauseObj->addWhere('thread = '.$threadId);
  309. $countClauseObj->addWhere('thread = '.$threadId);
  310. }
  311. $selectClauseObj->addWhere('message_id != thread');
  312. $selectClauseObj->addWhere('status = '.PHORUM_STATUS_APPROVED);
  313. $countClauseObj->addWhere('message_id != thread');
  314. $countClauseObj->addWhere('status = '.PHORUM_STATUS_APPROVED);
  315. if (!is_array($p_order) || count($p_order) == 0) {
  316. $p_order = array('default'=>'asc');
  317. }
  318. // sets the order condition if any
  319. if (is_array($p_order)) {
  320. $order = ArticleComment::ProcessListOrder($p_order);
  321. // sets the order condition if any
  322. foreach ($order as $orderDesc) {
  323. $orderField = $orderDesc['field'];
  324. $orderDirection = $orderDesc['dir'];
  325. $selectClauseObj->addOrderBy($orderField . ' ' . $orderDirection);
  326. }
  327. }
  328. // sets the limit
  329. $selectClauseObj->setLimit($p_start, $p_limit);
  330. // builds the query and executes it
  331. $selectQuery = $selectClauseObj->buildQuery();
  332. $comments = $g_ado_db->GetAll($selectQuery);
  333. if (is_array($comments)) {
  334. $countClauseObj->addColumn('COUNT(*)');
  335. $countQuery = $countClauseObj->buildQuery();
  336. $p_count = $g_ado_db->GetOne($countQuery);
  337. // builds the array of comment objects
  338. $articleCommentsList = array();
  339. foreach ($comments as $comment) {
  340. $pmObj = new Phorum_message($comment['message_id']);
  341. if ($pmObj->exists()) {
  342. $articleCommentsList[] = $pmObj;
  343. }
  344. }
  345. } else {
  346. $articleCommentsList = array();
  347. $p_count = 0;
  348. }
  349. if (!$p_skipCache && CampCache::IsEnabled()) {
  350. $cacheListObj->storeInCache($articleCommentsList);
  351. }
  352. return $articleCommentsList;
  353. } // fn GetList
  354. /**
  355. * Processes a paremeter (condition) coming from template tags.
  356. *
  357. * @param array $p_param
  358. * The array of parameters
  359. *
  360. * @return array $parameter
  361. * The array containing processed values of the condition
  362. */
  363. private static function ProcessListParameters($p_param)
  364. {
  365. switch (strtolower($p_param->getLeftOperand())) {
  366. case 'article_number':
  367. return new ComparisonOperation('fk_article_number',
  368. new Operator('is', 'integer'),
  369. (int) $p_param->getRightOperand());
  370. case 'language_id':
  371. return new ComparisonOperation('fk_language_id',
  372. new Operator('is', 'integer'),
  373. (int) $p_param->getRightOperand());
  374. }
  375. } // fn ProcessListParameters
  376. /**
  377. * Processes an order directive coming from template tags.
  378. *
  379. * @param array $p_order
  380. * The array of order directives
  381. *
  382. * @return array
  383. * The array containing processed values of the condition
  384. */
  385. private static function ProcessListOrder(array $p_order)
  386. {
  387. $order = array();
  388. foreach ($p_order as $orderDesc) {
  389. $dbField = null;
  390. $field = $orderDesc['field'];
  391. $direction = $orderDesc['dir'];
  392. switch (strtolower($field)) {
  393. case 'default':
  394. $dbField = 'thread_order';
  395. break;
  396. case 'bydate':
  397. $dbField = 'datestamp';
  398. break;
  399. }
  400. if (!is_null($dbField)) {
  401. $direction = !empty($direction) ? $direction : 'asc';
  402. $order[] = array('field'=>$dbField, 'dir'=>$direction);
  403. }
  404. }
  405. return $order;
  406. }
  407. } // class ArticleComment
  408. ?>