PageRenderTime 55ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/_backkup/HB_BACKUP_APRIL5_2012/public_html/system/expressionengine/modules/comment/mcp.comment.php

https://bitbucket.org/sims/heartbeets
PHP | 1691 lines | 1054 code | 350 blank | 287 comment | 156 complexity | 090b96d0b41590a8301a012145f6230e MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * ExpressionEngine - by EllisLab
  4. *
  5. * @package ExpressionEngine
  6. * @author ExpressionEngine Dev Team
  7. * @copyright Copyright (c) 2003 - 2011, EllisLab, Inc.
  8. * @license http://expressionengine.com/user_guide/license.html
  9. * @link http://expressionengine.com
  10. * @since Version 2.0
  11. * @filesource
  12. */
  13. // ------------------------------------------------------------------------
  14. /**
  15. * ExpressionEngine Comment Module
  16. *
  17. * @package ExpressionEngine
  18. * @subpackage Modules
  19. * @category Modules
  20. * @author ExpressionEngine Dev Team
  21. * @link http://expressionengine.com
  22. */
  23. class Comment_mcp {
  24. protected $pipe_length = '2';
  25. protected $comment_chars = "20";
  26. protected $comment_leave_breaks = 'n';
  27. protected $perpage = 50;
  28. protected $base_url = '';
  29. protected $search_url;
  30. protected $_dir;
  31. protected $_limit;
  32. protected $_offset;
  33. protected $_order_by;
  34. protected $_entry_id;
  35. /**
  36. * Constructor
  37. */
  38. public function __construct()
  39. {
  40. // Make a local reference to the ExpressionEngine super object
  41. $this->EE =& get_instance();
  42. if (REQ == 'CP')
  43. {
  44. $this->base_url = BASE.AMP.'C=addons_modules'.AMP.'M=show_module_cp'.AMP.'module=comment';
  45. if ($this->EE->cp->allowed_group('can_moderate_comments') &&
  46. $this->EE->cp->allowed_group('can_edit_all_comments') &&
  47. $this->EE->cp->allowed_group('can_delete_all_comments'))
  48. {
  49. $this->EE->cp->set_right_nav(
  50. array(
  51. 'settings' => $this->base_url.AMP.'method=settings',
  52. 'comments' => $this->base_url)
  53. );
  54. }
  55. }
  56. }
  57. // --------------------------------------------------------------------
  58. /**
  59. * Comments Home Page
  60. *
  61. * For the time being, this bad-boy is being simplified. With some existing
  62. * inefficiencies + datatables, the memory requirements to load the page
  63. * with a large dataset (> 100k comments) was unacceptable.
  64. *
  65. * In an attempt to mitigate high memory usage, I'm purposely avoiding
  66. * using a model and doing the queries right in this controller. But Greg,
  67. * that's "poor design!" When performance is a concern, I'm more than happy
  68. * to drop using a model, since we aren't on an ORM.
  69. */
  70. public function index()
  71. {
  72. $this->_permissions_check();
  73. $this->EE->load->helper(array('text', 'form'));
  74. $this->EE->load->library('javascript');
  75. $this->EE->javascript->set_global('lang.selection_required', lang('selection_required'));
  76. $this->EE->cp->set_variable('cp_page_title', lang('comments'));
  77. $this->_setup_query_filters();
  78. list($total_count, $qry) = $this->_setup_index_query();
  79. if ( ! $qry->num_rows())
  80. {
  81. $comments = FALSE;
  82. }
  83. else
  84. {
  85. $comment = $this->_get_comments($qry->result());
  86. $channel = $this->_get_channel_info($comment->result());
  87. $author = $this->_get_author_info($comment->result());
  88. $comments = $this->_merge_comment_data($comment->result(), $channel, $author);
  89. $comment->free_result();
  90. $channel->free_result();
  91. $author->free_result();
  92. }
  93. $data = array(
  94. 'comments' => $comments,
  95. 'pagination' => $this->_setup_pagination($total_count),
  96. 'channel_select_opts' => $this->_channel_select_opts(),
  97. 'channel_selected' => $this->_channel,
  98. 'status_select_opts' => $this->_status_select_opts(),
  99. 'status_selected' => $this->_status,
  100. 'date_select_opts' => $this->_date_select_opts(),
  101. 'date_selected' => $this->_date_range,
  102. 'form_options' => array(
  103. 'close' => lang('close_selected'),
  104. 'open' => lang('open_selected'),
  105. 'pending' => lang('pending_selected'),
  106. 'null' => '------',
  107. 'delete' => lang('delete_selected')
  108. )
  109. );
  110. return $this->EE->load->view('index', $data, TRUE);
  111. }
  112. // --------------------------------------------------------------------
  113. /**
  114. * Date Select Options
  115. *
  116. * @return array
  117. */
  118. protected function _date_select_opts()
  119. {
  120. return array(
  121. '' => lang('date_range'),
  122. 1 => lang('past_day'),
  123. 7 => lang('past_week'),
  124. 31 => lang('past_month'),
  125. 182 => lang('past_six_months'),
  126. 365 => lang('past_year')
  127. );
  128. }
  129. // --------------------------------------------------------------------
  130. /**
  131. * Status Select Options
  132. *
  133. * @return array
  134. */
  135. protected function _status_select_opts()
  136. {
  137. return array(
  138. '' => lang('filter_by_status'),
  139. 'all' => lang('all'),
  140. 'p' => lang('pending'),
  141. 'o' => lang('open'),
  142. 'c' => lang('closed')
  143. );
  144. }
  145. // --------------------------------------------------------------------
  146. /**
  147. * Channel filter select options
  148. *
  149. * @return array
  150. */
  151. protected function _channel_select_opts()
  152. {
  153. // We only limit to channels they are assigned to if they can't
  154. // moderate and can't edit all
  155. if ( ! $this->EE->cp->allowed_group('can_moderate_comments') &&
  156. ! $this->EE->cp->allowed_group('can_edit_all_comments'))
  157. {
  158. $query = $this->EE->channel_model->get_channels(
  159. (int) $this->EE->config->item('site_id'),
  160. array('channel_title', 'channel_id', 'cat_group'));
  161. }
  162. else
  163. {
  164. $this->EE->db->select('channel_title, channel_id, cat_group');
  165. $this->EE->db->where('site_id', (int) $this->EE->config->item('site_id'));
  166. $this->EE->db->order_by('channel_title');
  167. $query = $this->EE->db->get('channels');
  168. }
  169. $opts = array(
  170. '' => lang('filter_by_channel')
  171. );
  172. if ( ! $query)
  173. {
  174. return array();
  175. }
  176. if ($query->num_rows() > 1)
  177. {
  178. $opts['all'] = lang('all');
  179. }
  180. foreach ($query->result() as $row)
  181. {
  182. $opts[$row->channel_id] = $row->channel_title;
  183. }
  184. return $opts;
  185. }
  186. // --------------------------------------------------------------------
  187. /**
  188. * Merge Comment Data
  189. *
  190. * This is a...productive method.
  191. *
  192. * This method loops through the array of 50 comment db objects and
  193. * adds in a few more vars that will be used in the view. Additionally,
  194. * we alter some values such as status to make it human readable to get
  195. * that logic out of the views where it has no bidness.
  196. *
  197. * @param array array of comment objects
  198. * @param object db result from channel query
  199. * @param object db result from authors query
  200. * @return array array of altered comment objects
  201. */
  202. protected function _merge_comment_data($comments, $channels, $authors)
  203. {
  204. $this->EE->load->library('typography');
  205. $config = array(
  206. 'parse_images' => FALSE,
  207. 'allow_headings'=> FALSE,
  208. 'word_censor' => ($this->EE->config->item('comment_word_censoring') == 'y') ? TRUE : FALSE
  209. );
  210. $this->EE->typography->initialize($config);
  211. // There a result for authors here, or are they all anon?
  212. $authors = ( ! $authors->num_rows()) ? array() : $authors->result();
  213. foreach ($comments as $k => $v)
  214. {
  215. // Drop the entry title into the comment object
  216. foreach ($channels->result() as $row)
  217. {
  218. if ($v->entry_id == $row->entry_id)
  219. {
  220. $comments[$k]->entry_title = $row->title;
  221. break;
  222. }
  223. }
  224. // Get member info as well.
  225. foreach ($authors as $row)
  226. {
  227. if ($v->author_id == $row->member_id)
  228. {
  229. $comments[$k]->author_screen_name = $row->screen_name;
  230. break;
  231. }
  232. }
  233. if ( ! isset($comments[$k]->author_screen_name))
  234. {
  235. $comments[$k]->author_screen_name = '';
  236. }
  237. // Convert stati to human readable form
  238. switch ($comments[$k]->status)
  239. {
  240. case 'o':
  241. $comments[$k]->status = lang('open');
  242. break;
  243. case 'c':
  244. $comments[$k]->status = lang('closed');
  245. break;
  246. default:
  247. $comments[$k]->status = lang("pending");
  248. }
  249. // Alter the email var
  250. $comments[$k]->email = mailto($comments[$k]->email);
  251. // Create comment_edit_link
  252. $comments[$k]->comment_edit_link = sprintf(
  253. "<a class=\"less_important_link\" href=\"%s\" title=\"%s\">%s</a>",
  254. $this->base_url.AMP.'method=edit_comment_form'.AMP.'comment_id='.$comments[$k]->comment_id,
  255. 'edit',
  256. ellipsize($comments[$k]->comment, 50)
  257. );
  258. $comments[$k]->comment = $this->EE->typography->parse_type($comments[$k]->comment);
  259. }
  260. // flip the array
  261. $comments = array_reverse($comments);
  262. return $comments;
  263. }
  264. // --------------------------------------------------------------------
  265. /**
  266. * Get comment author information
  267. *
  268. * @param array array of comment db objects
  269. * @return object members db result object
  270. */
  271. protected function _get_author_info($comments)
  272. {
  273. $ids = array();
  274. foreach ($comments as $comment)
  275. {
  276. if ($comment->author_id != 0) // db results are always string
  277. {
  278. $ids[] = (int) $comment->author_id;
  279. }
  280. }
  281. $ids = array_unique($ids);
  282. if (empty($ids))
  283. {
  284. $ids = array(0);
  285. }
  286. return $this->EE->db->select('member_id, screen_name, username')
  287. ->where_in('member_id', $ids)
  288. ->get('members');
  289. }
  290. // --------------------------------------------------------------------
  291. /**
  292. * Get channel info.
  293. *
  294. * With large datasets/databases, a JOIN can be stupidly expensive,
  295. * especially in a situation where the db server isn't properly tuned
  296. * to make usage of system cache/buffers. While I do appreciate the
  297. * various distributions not making assumptions on what you want, sane
  298. * defaults would be really nice.
  299. *
  300. * @param array array of comment db objects
  301. * @return object channel_titles db result object
  302. */
  303. protected function _get_channel_info($comments)
  304. {
  305. $ids = array();
  306. foreach ($comments as $comment)
  307. {
  308. $ids[] = (int) $comment->entry_id;
  309. }
  310. // Remove duplicate keys.
  311. $ids = array_unique($ids);
  312. if (empty($ids))
  313. {
  314. $ids = array(0);
  315. }
  316. return $this->EE->db->select('title, entry_id')
  317. ->where_in('entry_id', $ids)
  318. ->get('channel_titles');
  319. }
  320. // --------------------------------------------------------------------
  321. /**
  322. * Setup pagination for the module index page.
  323. *
  324. * @param int total number of items
  325. * @return string rendered pagination links to display in the view
  326. */
  327. protected function _setup_pagination($total)
  328. {
  329. $this->EE->load->library('pagination');
  330. $url = $this->base_url.AMP.'method=index';
  331. if ($this->_channel)
  332. {
  333. $url .= AMP.'channel_id='.$this->_channel;
  334. }
  335. if ($this->_status && $this->_status != 'all')
  336. {
  337. $url .= AMP.'status='.$this->_status;
  338. }
  339. if ($this->_date_range)
  340. {
  341. $url .= AMP.'status='.$this->_date_range;
  342. }
  343. if ($this->_entry_id)
  344. {
  345. $url .= AMP.'entry_id='.$this->_entry_id;
  346. }
  347. $p_button = "<img src=\"{$this->EE->cp->cp_theme_url}images/pagination_%s_button.gif\" width=\"13\" height=\"13\" alt=\"%s\" />";
  348. $config = array(
  349. 'base_url' => $url,
  350. 'total_rows' => $total,
  351. 'per_page' => $this->_limit,
  352. 'page_query_string' => TRUE,
  353. 'query_string_segment' => 'offset',
  354. 'full_tag_open' => '<p id="paginationLinks">',
  355. 'full_tag_close' => '</p>',
  356. 'prev_link' => sprintf($p_button, 'prev', '&lt;'),
  357. 'next_link' => sprintf($p_button, 'next', '&gt;'),
  358. 'first_link' => sprintf($p_button, 'first', '&lt; &lt;'),
  359. 'last_link' => sprintf($p_button, 'last', '&gt; &gt;')
  360. );
  361. $this->EE->pagination->initialize($config);
  362. return $this->EE->pagination->create_links();
  363. }
  364. // --------------------------------------------------------------------
  365. /**
  366. * Setup query
  367. *
  368. * This method checks permissions on the logged in user to ensure they
  369. * have been granted access to moderate/edit comments. If they are,
  370. * we give them everything, if not, we only give them the comments they
  371. * authored.
  372. *
  373. * @return array $array($number_of_results, $comment_id_query);
  374. */
  375. protected function _setup_index_query()
  376. {
  377. // get filters
  378. $this->_query_filters();
  379. // get total number of comments
  380. $count = (int) $this->EE->db->select('COUNT(*) as count')
  381. ->get_where('comments', array(
  382. 'site_id' => (int) $this->EE->config->item('site_id')
  383. ))->row('count');
  384. // get filters
  385. $this->_query_filters();
  386. $qry = $this->EE->db->select('comment_id')
  387. ->where('site_id', (int) $this->EE->config->item('site_id'))
  388. ->order_by('comment_date', $this->_dir)
  389. ->get('comments', $this->_limit, $this->_offset);
  390. return array($count, $qry);
  391. }
  392. // --------------------------------------------------------------------
  393. protected function _query_filters()
  394. {
  395. // If the can ONLY edit their own comments- need to
  396. // bring in title table to limit on author
  397. if (( ! $this->EE->cp->allowed_group('can_moderate_comments') &&
  398. ! $this->EE->cp->allowed_group('can_edit_all_comments')) &&
  399. $this->EE->cp->allowed_group('can_edit_own_comments'))
  400. {
  401. $this->EE->db->where('author_id', (int) $this->EE->session->userdata('member_id'));
  402. }
  403. if ($this->_channel)
  404. {
  405. $this->EE->db->where('channel_id', (int) $this->_channel);
  406. }
  407. if ($this->_status && $this->_status != 'all')
  408. {
  409. $this->EE->db->where('status', $this->_status);
  410. }
  411. if ($this->_date_range)
  412. {
  413. $date_range = time() - ($this->_date_range * 60 * 60 * 24);
  414. $this->EE->db->where('comment_date >', (int) $date_range);
  415. }
  416. if ($this->_entry_id)
  417. {
  418. $this->EE->db->where('entry_id', (int) $this->_entry_id);
  419. }
  420. }
  421. // --------------------------------------------------------------------
  422. /**
  423. * Get Comments
  424. *
  425. * This method takes an array of comment ids and performs the query
  426. * based on the filtering that previously happened.
  427. *
  428. * @param array ids of comments to retrieve
  429. * @return object db object
  430. */
  431. protected function _get_comments($ids)
  432. {
  433. $comment_ids = array();
  434. foreach ($ids as $id)
  435. {
  436. $comment_ids[] = (int) $id->comment_id;
  437. }
  438. return $this->EE->db->where_in('comment_id', $comment_ids)
  439. ->get('comments');
  440. }
  441. // --------------------------------------------------------------------
  442. /**
  443. * Setup Query Filters
  444. *
  445. * This method Sets up a few class properties based on query strings to
  446. * filter the comments query on the index page.
  447. *
  448. * @return void
  449. */
  450. protected function _setup_query_filters()
  451. {
  452. $this->_channel = $this->EE->input->get_post('channel_id');
  453. $this->_status = $this->EE->input->get_post('status');
  454. $this->_date_range = $this->EE->input->get_post('date_range');
  455. $this->_limit = ($per_page = $this->EE->input->get('per_page')) ? $per_page : 50;
  456. $this->_offset = ($offset = $this->EE->input->get('offset')) ? $offset : 0;
  457. $this->_dir = ($dir = $this->EE->input->get('dir')) ? $dir : 'desc';
  458. $this->_order_by = ($ob = $this->EE->input->get('order_by')) ? $ob : 'comment_date';
  459. $this->_entry_id = $this->EE->input->get('entry_id');
  460. }
  461. // --------------------------------------------------------------------
  462. /**
  463. * Delete Comment Notification
  464. *
  465. * @return string
  466. */
  467. public function delete_comment_notification()
  468. {
  469. if ( ! $id = $this->EE->input->get_post('id') OR
  470. ! $hash = $this->EE->input->get_post('hash'))
  471. {
  472. return FALSE;
  473. }
  474. if ( ! is_numeric($id))
  475. {
  476. return FALSE;
  477. }
  478. $this->EE->lang->loadfile('comment');
  479. $this->EE->load->library('subscription');
  480. $this->EE->subscription->init('comment', array('subscription_id' => $id), TRUE);
  481. $this->EE->subscription->unsubscribe('', $hash);
  482. $data = array(
  483. 'title' => lang('cmt_notification_removal'),
  484. 'heading' => lang('thank_you'),
  485. 'content' => lang('cmt_you_have_been_removed'),
  486. 'redirect' => '',
  487. 'link' => array($this->EE->config->item('site_url'), stripslashes($this->EE->config->item('site_name')))
  488. );
  489. $this->EE->output->show_message($data);
  490. }
  491. // --------------------------------------------------------------------
  492. /**
  493. * Edit Comment Form
  494. *
  495. * @return void
  496. */
  497. public function edit_comment_form($comment_id = FALSE)
  498. {
  499. $this->_permissions_check();
  500. $can_edit = FALSE;
  501. $this->EE->load->library('table');
  502. $this->EE->load->library('javascript');
  503. $this->EE->javascript->output('
  504. // If validation fails- want to be sure to show the move field if populated
  505. if ($("#move_to").val() != "")
  506. {
  507. $("#move_link").hide();
  508. $("#move_field").show();
  509. }
  510. $("#move_link").click(function() {
  511. $("#move_link").hide();
  512. $("#move_field").show();
  513. return false;
  514. });
  515. $("#cancel_link").click(function() {
  516. $("input#move_to").val("");
  517. $("#move_link").show();
  518. $("#move_field").hide();
  519. return false;
  520. });
  521. ');
  522. $this->EE->javascript->compile();
  523. $comment_id = ( ! $comment_id) ? $this->EE->input->get_post('comment_id') : $comment_id;
  524. if ($comment_id == FALSE OR ! is_numeric($comment_id))
  525. {
  526. show_error(lang('unauthorized_access'));
  527. }
  528. $this->EE->load->helper(array('form', 'snippets'));
  529. $this->EE->db->select('channel_titles.author_id as entry_author, title, channel_title, comment_require_email, comment, comment_id, comments.author_id, comments.status, name, email, url, location, comments.ip_address, comment_date, channels.comment_text_formatting, channels.comment_html_formatting, channels.comment_allow_img_urls, channels.comment_auto_link_urls');
  530. $this->EE->db->from(array('channel_titles', 'comments'));
  531. $this->EE->db->join('channels', 'exp_comments.channel_id = exp_channels.channel_id ', 'left');
  532. $this->EE->db->where('channel_titles.entry_id = '.$this->EE->db->dbprefix('comments.entry_id'));
  533. $this->EE->db->where('comments.comment_id', $comment_id);
  534. $query = $this->EE->db->get();
  535. if ($query->num_rows() === 0)
  536. {
  537. return FALSE;
  538. }
  539. if ($this->EE->cp->allowed_group('can_edit_all_comments'))
  540. {
  541. $can_edit = TRUE;
  542. }
  543. else
  544. {
  545. if ($query->row('entry_author') == $this->EE->session->userdata('member_id'))
  546. {
  547. $can_edit = TRUE;
  548. }
  549. else
  550. {
  551. if ( ! $this->EE->cp->allowed_group('can_moderate_comments'))
  552. {
  553. show_error(lang('unauthorized_access'));
  554. }
  555. }
  556. }
  557. $vars = $query->row_array();
  558. $vars['move_link'] = '';
  559. $vars['move_to'] = '';
  560. $vars['can_edit'] = $can_edit;
  561. $vars['status_select_options']['p'] = lang('pending');
  562. $vars['status_select_options']['o'] = lang('open');
  563. $vars['status_select_options']['c'] = lang('closed');
  564. $vars['status'] = ($this->EE->input->post('status')) ? $this->EE->input->post('status') : $vars['status'];
  565. // Instantiate Typography class
  566. $config = ($this->EE->config->item('comment_word_censoring') == 'y') ? array('word_censor' => TRUE) : array();
  567. $this->EE->load->library('typography');
  568. $this->EE->typography->initialize(array(
  569. 'parse_images' => FALSE)
  570. );
  571. $vars['display_comment'] = $this->EE->typography->parse_type($vars['comment'],
  572. array(
  573. 'text_format' => $vars['comment_text_formatting'],
  574. 'html_format' => $vars['comment_html_formatting'],
  575. 'auto_links' => $vars['comment_auto_link_urls'],
  576. 'allow_img_url' => $vars['comment_allow_img_urls']
  577. )
  578. );
  579. $hidden = array(
  580. 'comment_id' => $comment_id,
  581. 'email' => $query->row('email')
  582. );
  583. $this->EE->cp->set_variable('cp_page_title', lang('edit_comment'));
  584. // a bit of a breadcrumb override is needed
  585. $this->EE->cp->set_variable('cp_breadcrumbs', array(
  586. $this->base_url => lang('comments')));
  587. $vars['hidden'] = $hidden;
  588. $this->EE->javascript->compile();
  589. return $this->EE->load->view('edit', $vars, TRUE);
  590. }
  591. // --------------------------------------------------------------------
  592. /**
  593. * This permissions check is used in several places.
  594. */
  595. private function _permissions_check()
  596. {
  597. if ( ! $this->EE->cp->allowed_group('can_moderate_comments')
  598. && ! $this->EE->cp->allowed_group('can_edit_all_comments')
  599. && ! $this->EE->cp->allowed_group('can_edit_own_comments'))
  600. {
  601. show_error(lang('unauthorized_access'));
  602. }
  603. }
  604. // --------------------------------------------------------------------
  605. /**
  606. * Update Comment
  607. *
  608. * @return void
  609. */
  610. public function update_comment()
  611. {
  612. $this->_permissions_check();
  613. $comment_id = $this->EE->input->get_post('comment_id');
  614. if ($comment_id == FALSE OR ! is_numeric($comment_id))
  615. {
  616. show_error(lang('unauthorized_access'));
  617. }
  618. $this->EE->load->library('form_validation');
  619. $can_edit = FALSE;
  620. if ($this->EE->cp->allowed_group('can_edit_all_comments'))
  621. {
  622. $query = $this->EE->db->get_where('comments', array('comment_id' => $comment_id));
  623. $can_edit = TRUE;
  624. }
  625. else
  626. {
  627. $this->EE->db->select('channel_titles.author_id, comments.channel_id, comments.entry_id');
  628. $this->EE->db->from(array('channel_titles', 'comments'));
  629. $this->EE->db->where('channel_titles.entry_id = '.$this->EE->db->dbprefix('comments.entry_id'));
  630. $this->EE->db->where('comments.comment_id', $comment_id);
  631. $query = $this->EE->db->get();
  632. if ($query->row('author_id') != $this->EE->session->userdata('member_id'))
  633. {
  634. if ( ! $this->EE->cp->allowed_group('can_moderate_comments'))
  635. {
  636. show_error(lang('unauthorized_access'));
  637. }
  638. $can_edit = TRUE;
  639. }
  640. }
  641. if ($query->num_rows() == 0)
  642. {
  643. return false;
  644. }
  645. $row = $query->row_array();
  646. $author_id = $row['author_id'];
  647. $channel_id = $row['channel_id'];
  648. $entry_id = $row['entry_id'];
  649. $current_status = $row['status'];
  650. $new_channel_id = $row['channel_id'];
  651. $new_entry_id = $row['entry_id'];
  652. // Are emails required?
  653. $this->EE->db->select('channels.comment_require_email');
  654. $this->EE->db->from(array('channels', 'comments'));
  655. $this->EE->db->where('comments.channel_id = '.$this->EE->db->dbprefix('channels.channel_id'));
  656. $this->EE->db->where('comments.comment_id', $comment_id);
  657. $query = $this->EE->db->get();
  658. if ($query->num_rows() == 0)
  659. {
  660. return show_error(lang('no_channel_exists'));
  661. }
  662. foreach ($query->row_array() as $key => $val)
  663. {
  664. $$key = $val;
  665. }
  666. $status = $this->EE->input->post('status');
  667. // If they can not edit- only the status may change
  668. if ( ! $can_edit)
  669. {
  670. if ( ! in_array($status, array('o', 'c', 'p')))
  671. {
  672. show_error(lang('unauthorized_access'));
  673. }
  674. $data = array('status' => $status);
  675. $this->EE->db->query($this->EE->db->update_string('exp_comments', $data, "comment_id = '$comment_id'"));
  676. $this->update_stats(array($entry_id), array($channel_id), array($author_id));
  677. // Did status change to open? Notify
  678. if ($status == 'o' && $current_status != 'o')
  679. {
  680. $this->send_notification_emails(array($comment_id));
  681. }
  682. $this->EE->functions->clear_caching('all');
  683. $url = $this->base_url.AMP.'comment_id='.$comment_id;
  684. $this->EE->session->set_flashdata('message_success',
  685. lang('comment_updated'));
  686. $this->EE->functions->redirect($url);
  687. }
  688. // Error checks
  689. if ($author_id == 0)
  690. {
  691. // Fetch language file
  692. $this->EE->lang->loadfile('myaccount');
  693. if ($comment_require_email == 'y')
  694. {
  695. $this->EE->form_validation->set_rules('email', 'lang:email', 'callback__email_check');
  696. }
  697. else
  698. {
  699. $this->EE->form_validation->set_rules('email', 'lang:email', '');
  700. }
  701. $this->EE->form_validation->set_rules('name', 'lang:name', 'required');
  702. $this->EE->form_validation->set_rules('url', '', '');
  703. $this->EE->form_validation->set_rules('location', '', '');
  704. }
  705. // Are thy moving the comment? Check for valid entry_id
  706. $move_to = $this->EE->input->get_post('move_to');
  707. $recount_ids = array();
  708. $recount_channels = array();
  709. if ($move_to != '')
  710. {
  711. $tcount = 0;
  712. if (ctype_digit($move_to))
  713. {
  714. $this->EE->db->select('title, entry_id, channel_id');
  715. $this->EE->db->where('entry_id', $move_to);
  716. $query = $this->EE->db->get('channel_titles');
  717. $tcount = $query->num_rows();
  718. }
  719. if ($tcount == 0)
  720. {
  721. $this->EE->form_validation->set_rules('move_to', 'lang:move_to', 'callback__move_check');
  722. }
  723. else
  724. {
  725. $row = $query->row();
  726. $new_entry_id = $row->entry_id;
  727. $new_channel_id = $row->channel_id;
  728. $recount_ids[] = $entry_id;
  729. $recount_channels[] = $channel_id;
  730. $recount_ids[] = $row->entry_id;
  731. $recount_channels[] = $row->channel_id;
  732. }
  733. }
  734. $this->EE->form_validation->set_rules('comment', 'lang:comment', 'required');
  735. $this->EE->form_validation->set_error_delimiters('<br /><span class="notice">', '<br />');
  736. if ($this->EE->form_validation->run() === FALSE)
  737. {
  738. return $this->edit_comment_form($comment_id);
  739. }
  740. // Build query
  741. if ($author_id == 0)
  742. {
  743. $data = array(
  744. 'entry_id' => $new_entry_id,
  745. 'channel_id' => $new_channel_id,
  746. 'name' => $this->EE->input->post('name'),
  747. 'email' => $this->EE->input->post('email'),
  748. 'url' => $this->EE->input->post('url'),
  749. 'location' => $this->EE->input->post('location'),
  750. 'comment' => $this->EE->input->post('comment'),
  751. 'status' => $status
  752. );
  753. }
  754. else
  755. {
  756. $data = array(
  757. 'entry_id' => $new_entry_id,
  758. 'channel_id' => $new_channel_id,
  759. 'comment' => $this->EE->input->post('comment'),
  760. 'status' => $status
  761. );
  762. }
  763. $this->EE->db->query($this->EE->db->update_string('exp_comments', $data, "comment_id = '$comment_id'"));
  764. if ($status != $current_status)
  765. {
  766. $this->update_stats(array($entry_id), array($channel_id), array($author_id));
  767. // Did status change to open? Notify
  768. if ($status == 'o' && $current_status != 'o')
  769. {
  770. $this->send_notification_emails(array($comment_id));
  771. }
  772. }
  773. if (count($recount_ids) > 0)
  774. {
  775. $this->EE->load->model('comment_model');
  776. $this->EE->comment_model->recount_entry_comments($recount_ids);
  777. // Quicker and updates just the channels
  778. foreach(array_unique($recount_channels) as $channel_id)
  779. {
  780. $this->EE->stats->update_comment_stats($channel_id, '', FALSE);
  781. }
  782. // Updates the total stats
  783. $this->EE->stats->update_comment_stats();
  784. }
  785. /* -------------------------------------------
  786. /* 'update_comment_additional' hook.
  787. /* - Add additional processing on comment update.
  788. */
  789. $edata = $this->EE->extensions->call('update_comment_additional', $comment_id, $data);
  790. if ($this->EE->extensions->end_script === TRUE) return;
  791. /*
  792. /* -------------------------------------------*/
  793. $this->EE->functions->clear_caching('all');
  794. $url = $this->base_url.AMP.'comment_id='.$comment_id;
  795. $this->EE->session->set_flashdata('message_success', lang('comment_updated'));
  796. $this->EE->functions->redirect($url);
  797. }
  798. // --------------------------------------------------------------------
  799. /**
  800. * Email Check
  801. *
  802. * callback function for form_validation, so it needs to be publicly
  803. * accessible.
  804. */
  805. public function _email_check($str)
  806. {
  807. // Is email missing?
  808. if ($str == '')
  809. {
  810. $this->EE->form_validation->set_message('_email_check',
  811. lang('missing_email'));
  812. return FALSE;
  813. }
  814. // Is email valid?
  815. $this->EE->load->helper('email');
  816. if ( ! valid_email($str))
  817. {
  818. $this->EE->form_validation->set_message('_email_check',
  819. lang('invalid_email_address'));
  820. return FALSE;
  821. }
  822. // Is email banned?
  823. if ($this->EE->session->ban_check('email', $str))
  824. {
  825. $this->EE->form_validation->set_message('_email_check',
  826. lang('banned_email'));
  827. return FALSE;
  828. }
  829. return TRUE;
  830. }
  831. // --------------------------------------------------------------------
  832. /**
  833. * Move check -- form_validation callback
  834. *
  835. */
  836. public function _move_check($str)
  837. {
  838. // failed by definition
  839. $this->EE->form_validation->set_message('_move_check',
  840. lang('invalid_entry_id'));
  841. return FALSE;
  842. }
  843. // --------------------------------------------------------------------
  844. /**
  845. * Modify Comments
  846. *
  847. * @return void
  848. */
  849. public function modify_comments()
  850. {
  851. // This only happens if they submit with no comments checked, so we send
  852. // them home.
  853. if ( ! $this->EE->input->post('toggle') &&
  854. ! $this->EE->input->get_post('comment_id'))
  855. {
  856. $this->EE->session->set_flashdata('message_failure',
  857. lang('no_valid_selections'));
  858. $this->EE->functions->redirect($this->base_url);
  859. }
  860. switch($this->EE->input->post('action'))
  861. {
  862. case 'open':
  863. $this->change_comment_status('o');
  864. break;
  865. case 'close':
  866. $this->change_comment_status('c');
  867. break;
  868. case 'pending':
  869. $this->change_comment_status('p');
  870. break;
  871. default:
  872. return $this->delete_comment_confirm();
  873. break;
  874. }
  875. }
  876. // --------------------------------------------------------------------
  877. /**
  878. * Delete Comments Confirmation
  879. *
  880. * @return void
  881. */
  882. public function delete_comment_confirm()
  883. {
  884. if ( ! $this->EE->cp->allowed_group('can_delete_all_comments')
  885. && ! $this->EE->cp->allowed_group('can_delete_own_comments'))
  886. {
  887. show_error(lang('unauthorized_access'));
  888. }
  889. $this->EE->cp->get_installed_modules();
  890. $blacklist_installed = (isset($this->EE->cp->installed_modules['blacklist'])) ? TRUE : FALSE;
  891. if ( ! $this->EE->input->post('toggle') && ! $this->EE->input->get_post('comment_id'))
  892. {
  893. $this->EE->session->set_flashdata('message_failure', lang('no_valid_selections'));
  894. $this->EE->functions->redirect($this->base_url);
  895. }
  896. $this->EE->load->library('table');
  897. $comments = array();
  898. if ($this->EE->input->post('toggle'))
  899. {
  900. foreach ($_POST['toggle'] as $key => $val)
  901. {
  902. $comments[] = $val;
  903. }
  904. }
  905. if ($this->EE->input->get_post('comment_id') !== FALSE && is_numeric($this->EE->input->get_post('comment_id')))
  906. {
  907. $comments[] = $this->EE->input->get_post('comment_id');
  908. }
  909. if (count($comments) == 0)
  910. {
  911. show_error(lang('unauthorized_access'));
  912. }
  913. $this->EE->db->select('channel_titles.author_id, title, comments.comment_id, comment, comments.ip_address');
  914. $this->EE->db->from(array('channel_titles', 'comments'));
  915. $this->EE->db->where('channel_titles.entry_id = '.$this->EE->db->dbprefix('comments.entry_id'));
  916. $this->EE->db->where_in('comments.comment_id', $comments);
  917. $comments = array();
  918. $query = $this->EE->db->get();
  919. if ($query->num_rows() > 0)
  920. {
  921. foreach($query->result_array() as $row)
  922. {
  923. if ( ! $this->EE->cp->allowed_group('can_delete_all_comments') && ($row['author_id'] != $this->EE->session->userdata('member_id')))
  924. {
  925. continue;
  926. }
  927. $row['comment'] = strip_tags(str_replace(array("\t","\n","\r"), ' ', $row['comment']));
  928. $row['comment'] = $this->EE->functions->char_limiter(trim($row['comment']), 100);
  929. $comments[$row['comment_id']]['entry_title'] = $row['title'];
  930. $comments[$row['comment_id']]['comment'] = $row['comment'];
  931. $comments[$row['comment_id']]['ip_address'] = $row['ip_address'];
  932. }
  933. }
  934. if (count($comments) == 0)
  935. {
  936. $this->EE->session->set_flashdata('message_failure',
  937. lang('no_valid_selections'));
  938. $this->EE->functions->redirect($this->base_url);
  939. }
  940. $this->EE->load->helper('form');
  941. $this->EE->cp->set_variable('cp_page_title', lang('delete_confirm'));
  942. $this->EE->cp->set_variable('cp_breadcrumbs', array(
  943. $this->base_url => lang('comments'),
  944. ));
  945. $vars = array();
  946. $vars['hidden'] = array(
  947. 'comment_ids' => implode('|', array_keys($comments)));
  948. $vars['blacklist_installed'] = (isset($this->EE->cp->installed_modules['blacklist'])) ? TRUE : FALSE;
  949. $message = (count($comments) > 1) ? 'delete_comments_confirm' : 'delete_comment_confirm';
  950. $vars['comments'] = $comments;
  951. $vars['message'] = $message;
  952. return $this->EE->load->view('delete_comments', $vars, TRUE);
  953. }
  954. // --------------------------------------------------------------------
  955. /**
  956. * Change Comment Status
  957. *
  958. * @param string new status
  959. * @return void
  960. */
  961. public function change_comment_status($status = '')
  962. {
  963. $this->_permissions_check();
  964. $comments = array();
  965. if (isset($_POST['toggle']) && is_array($_POST['toggle']))
  966. {
  967. foreach ($_POST['toggle'] as $key => $val)
  968. {
  969. $comments[$val] = $val;
  970. }
  971. }
  972. if($this->EE->input->get_post('comment_id') !== FALSE && is_numeric($this->EE->input->get_post('comment_id')))
  973. {
  974. $comments[$this->EE->input->get_post('comment_id')] = $this->EE->input->get_post('comment_id');
  975. }
  976. if (count($comments) == 0)
  977. {
  978. show_error(lang('unauthorized_access'));
  979. }
  980. $status = ($status == '') ? $this->EE->input->get('status') : $status;
  981. if ( ! in_array($status, array('o', 'c', 'p')))
  982. {
  983. show_error(lang('unauthorized_access'));
  984. }
  985. $this->EE->db->select('exp_comments.entry_id, exp_comments.channel_id, exp_comments.author_id, comment_id, exp_channel_titles.author_id AS entry_author');
  986. $this->EE->db->join('channel_titles', 'exp_comments.entry_id = exp_channel_titles.entry_id', 'left');
  987. $this->EE->db->where_in('comment_id', $comments);
  988. $query = $this->EE->db->get('comments');
  989. // Retrieve Our Results
  990. if ($query->num_rows() == 0)
  991. {
  992. show_error(lang('unauthorized_access'));
  993. }
  994. $entry_ids = array();
  995. $author_ids = array();
  996. $channel_ids = array();
  997. foreach($query->result_array() as $row)
  998. {
  999. if (( ! $this->EE->cp->allowed_group('can_moderate_comments')
  1000. && ! $this->EE->cp->allowed_group('can_edit_all_comments'))
  1001. && ($row['entry_author'] != $this->EE->session->userdata('member_id')))
  1002. {
  1003. unset($comments[$row['comment_id']]);
  1004. continue;
  1005. }
  1006. $entry_ids[] = $row['entry_id'];
  1007. $author_ids[] = $row['author_id'];
  1008. $channel_ids[] = $row['channel_id'];
  1009. }
  1010. if (count($comments) == 0)
  1011. {
  1012. show_error(lang('unauthorized_access'));
  1013. }
  1014. $entry_ids = array_unique($entry_ids);
  1015. $author_ids = array_unique($author_ids);
  1016. $channel_ids = array_unique($channel_ids);
  1017. /** -------------------------------
  1018. /** Change Status
  1019. /** -------------------------------*/
  1020. $this->EE->db->set('status', $status);
  1021. $this->EE->db->where_in('comment_id', $comments);
  1022. $this->EE->db->update('comments');
  1023. $this->update_stats($entry_ids, $channel_ids, $author_ids);
  1024. // Send email notification or remove notifications
  1025. if ($status == 'o')
  1026. {
  1027. $this->send_notification_emails($comments);
  1028. }
  1029. if ($this->EE->extensions->active_hook('update_comment_additional'))
  1030. {
  1031. $qry = $this->EE->db->where_in('comment_id', $comments)
  1032. ->get('comments');
  1033. foreach ($qry->result_array() as $row)
  1034. {
  1035. /* -------------------------------------------
  1036. /* 'update_comment_additional' hook.
  1037. /* - Add additional processing on comment update.
  1038. */
  1039. $edata = $this->EE->extensions->call(
  1040. 'update_comment_additional',
  1041. $row['comment_id'], $row
  1042. );
  1043. if ($this->EE->extensions->end_script === TRUE) return;
  1044. /*
  1045. /* -------------------------------------------*/
  1046. }
  1047. }
  1048. $this->EE->functions->clear_caching('all');
  1049. $url = $this->base_url;
  1050. $this->EE->session->set_flashdata('message_success', lang('status_changed'));
  1051. $this->EE->functions->redirect($url);
  1052. }
  1053. // --------------------------------------------------------------------
  1054. /**
  1055. * Delete Comment
  1056. *
  1057. * @return void
  1058. */
  1059. public function delete_comment()
  1060. {
  1061. if ( ! $this->EE->cp->allowed_group('can_delete_all_comments') &&
  1062. ! $this->EE->cp->allowed_group('can_delete_own_comments'))
  1063. {
  1064. show_error(lang('unauthorized_access'));
  1065. }
  1066. $comment_id = $this->EE->input->post('comment_ids');
  1067. if ($comment_id == FALSE)
  1068. {
  1069. show_error(lang('unauthorized_access'));
  1070. }
  1071. if ( ! preg_match("/^[0-9]+$/", str_replace('|', '', $comment_id)))
  1072. {
  1073. show_error(lang('unauthorized_access'));
  1074. }
  1075. $this->EE->db->where_in('comment_id', explode('|', $comment_id));
  1076. $count = $this->EE->db->count_all_results('comments');
  1077. if ($count == 0)
  1078. {
  1079. show_error(lang('unauthorized_access'));
  1080. }
  1081. $this->EE->cp->get_installed_modules();
  1082. $blacklist_installed = (isset($this->EE->cp->installed_modules['blacklist'])) ? TRUE : FALSE;
  1083. $this->EE->db->select('channel_titles.author_id, channel_titles.entry_id, channel_titles.channel_id, channel_titles.comment_total, comments.ip_address');
  1084. $this->EE->db->from(array('channel_titles', 'comments'));
  1085. $this->EE->db->where('channel_titles.entry_id = '.$this->EE->db->dbprefix('comments.entry_id'));
  1086. $this->EE->db->where_in('comments.comment_id', explode('|', $comment_id));
  1087. $query = $this->EE->db->get();
  1088. if ($query->num_rows() == 0)
  1089. {
  1090. show_error(lang('unauthorized_access'));
  1091. }
  1092. $entry_ids = array();
  1093. $author_ids = array();
  1094. $channel_ids = array();
  1095. $bad_ips = array();
  1096. foreach($query->result_array() as $row)
  1097. {
  1098. $entry_ids[] = $row['entry_id'];
  1099. $author_ids[] = $row['author_id'];
  1100. $channel_ids[] = $row['channel_id'];
  1101. $bad_ips[] = $row['ip_address'];
  1102. }
  1103. $entry_ids = array_unique($entry_ids);
  1104. $author_ids = array_unique($author_ids);
  1105. $channel_ids = array_unique($channel_ids);
  1106. $ips['ip'] = array_unique($bad_ips);
  1107. unset($bad_ips);
  1108. if ( ! $this->EE->cp->allowed_group('can_delete_all_comments'))
  1109. {
  1110. foreach($query->result_array() as $row)
  1111. {
  1112. if ($row['author_id'] != $this->EE->session->userdata('member_id'))
  1113. {
  1114. show_error(lang('unauthorized_access'));
  1115. }
  1116. }
  1117. }
  1118. // If blacklist was checked- blacklist!
  1119. if ($blacklist_installed && $this->EE->input->post('add_to_blacklist') == 'y')
  1120. {
  1121. include_once PATH_MOD.'blacklist/mcp.blacklist.php';
  1122. $bl = new Blacklist_mcp();
  1123. // Write to htaccess?
  1124. $write_htacces = ($this->EE->session->userdata('group_id') == '1' && $this->EE->config->item('htaccess_path') != '') ? TRUE : FALSE;
  1125. $blacklisted = $bl->update_blacklist($ips, $write_htacces, 'bool');
  1126. }
  1127. $comment_ids = explode('|', $comment_id);
  1128. /* -------------------------------------------
  1129. /* 'delete_comment_additional' hook.
  1130. /* - Add additional processing on comment delete
  1131. */
  1132. $edata = $this->EE->extensions->call('delete_comment_additional', $comment_ids);
  1133. if ($this->EE->extensions->end_script === TRUE) return;
  1134. /*
  1135. /* -------------------------------------------*/
  1136. $this->EE->db->where_in('comment_id', $comment_ids);
  1137. $this->EE->db->delete('comments');
  1138. $this->update_stats($entry_ids, $channel_ids, $author_ids);
  1139. $this->EE->functions->clear_caching('all');
  1140. $this->EE->session->set_flashdata('message_success',
  1141. lang('comment_deleted'));
  1142. $this->EE->functions->redirect($this->base_url);
  1143. }
  1144. // --------------------------------------------------------------------
  1145. /**
  1146. * Send Notification Emails
  1147. *
  1148. * @return void
  1149. */
  1150. public function send_notification_emails($comments)
  1151. {
  1152. // Load subscription class
  1153. $this->EE->load->library('subscription');
  1154. // Instantiate Typography class
  1155. $this->EE->load->library('typography');
  1156. $this->EE->typography->initialize(array(
  1157. 'parse_images' => FALSE,
  1158. 'word_censor' => ($this->EE->config->item('comment_word_censoring') == 'y') ? TRUE : FALSE)
  1159. );
  1160. // Grab the required comments
  1161. $this->EE->db->select('comment, comment_id, author_id, name, email, comment_date, entry_id');
  1162. $this->EE->db->where_in('comment_id', $comments);
  1163. $query = $this->EE->db->get('comments');
  1164. // Sort based on entry
  1165. $entries = array();
  1166. foreach ($query->result() as $row)
  1167. {
  1168. if ( ! isset($entries[$row->entry_id]))
  1169. {
  1170. $entries[$row->entry_id] = array();
  1171. }
  1172. $entries[$row->entry_id][] = $row;
  1173. }
  1174. // Go through the entries and send subscriptions
  1175. foreach ($entries as $entry_id => $comments)
  1176. {
  1177. $this->EE->subscription->init('comment', array('entry_id' => $entry_id), TRUE);
  1178. // Grab them all
  1179. $subscriptions = $this->EE->subscription->get_subscriptions();
  1180. $this->EE->load->model('comment_model');
  1181. $recipients = $this->EE->comment_model->fetch_email_recipients($entry_id, $subscriptions);
  1182. if (count($recipients))
  1183. {
  1184. // Grab generic entry info
  1185. $action_id = $this->EE->functions->fetch_action_id('Comment_mcp', 'delete_comment_notification');
  1186. $this->EE->db->select('channel_titles.title, channel_titles.entry_id, channel_titles.url_title, channels.channel_title, channels.comment_url, channels.channel_url, channels.channel_id');
  1187. $this->EE->db->join('channels', 'exp_channel_titles.channel_id = exp_channels.channel_id', 'left');
  1188. $this->EE->db->where('channel_titles.entry_id', $entry_id);
  1189. $results = $this->EE->db->get('channel_titles');
  1190. $com_url = ($results->row('comment_url') == '') ? $results->row('channel_url') : $results->row('comment_url');
  1191. // Create an array of comments to add to the email
  1192. $comments_swap = array();
  1193. foreach ($comments as $c)
  1194. {
  1195. $comment_text = $this->EE->typography->parse_type(
  1196. $c->comment,
  1197. array(
  1198. 'text_format' => 'none',
  1199. 'html_format' => 'none',
  1200. 'auto_links' => 'n',
  1201. 'allow_img_url' => 'n'
  1202. )
  1203. );
  1204. $comments_swap[] = array(
  1205. 'name_of_commenter' => $c->name,
  1206. 'name' => $c->name,
  1207. 'comment' => $comment_text,
  1208. 'comment_id' => $c->comment_id,
  1209. );
  1210. }
  1211. $swap = array(
  1212. 'channel_name' => $results->row('channel_title'),
  1213. 'entry_title' => $results->row('title'),
  1214. 'site_name' => stripslashes($this->EE->config->item('site_name')),
  1215. 'site_url' => $this->EE->config->item('site_url'),
  1216. 'comment_url' => $this->EE->functions->remove_double_slashes($com_url.'/'.$results->row('url_title') .'/'),
  1217. 'channel_id' => $results->row('channel_id'),
  1218. 'entry_id' => $results->row('entry_id'),
  1219. 'url_title' => $results->row('url_title'),
  1220. 'comment_url_title_auto_path' => reduce_double_slashes($com_url.'/'.$results->row('url_title')),
  1221. 'comments' => $comments_swap
  1222. );
  1223. $template = $this->EE->functions->fetch_email_template('comments_opened_notification');
  1224. $this->EE->load->library('template');
  1225. $email_tit = $this->EE->template->parse_variables_row($template['title'], $swap);
  1226. $email_msg = $this->EE->template->parse_variables_row($template['data'], $swap);
  1227. // Send email
  1228. $this->EE->load->library('email');
  1229. $this->EE->email->wordwrap = true;
  1230. // Load the text helper
  1231. $this->EE->load->helper('text');
  1232. $sent = array();
  1233. foreach ($recipients as $val)
  1234. {
  1235. if ( ! in_array($val['0'], $sent))
  1236. {
  1237. $title = $email_tit;
  1238. $message = $email_msg;
  1239. $sub = $subscriptions[$val['1']];
  1240. $sub_qs = 'id='.$sub['subscription_id'].'&hash='.$sub['hash'];
  1241. // Deprecate the {name} variable at some point
  1242. $title = str_replace('{name}', $val['2'], $title);
  1243. $message = str_replace('{name}', $val['2'], $message);
  1244. $title = str_replace('{name_of_recipient}', $val['2'], $title);
  1245. $message = str_replace('{name_of_recipient}', $val['2'], $message);
  1246. $title = str_replace('{notification_removal_url}', $this->EE->functions->fetch_site_index(0, 0).QUERY_MARKER.'ACT='.$action_id.'&'.$sub_qs, $title);
  1247. $message = str_replace('{notification_removal_url}', $this->EE->functions->fetch_site_index(0, 0).QUERY_MARKER.'ACT='.$action_id.'&'.$sub_qs, $message);
  1248. $this->EE->email->EE_initialize();
  1249. $this->EE->email->from($this->EE->config->item('webmaster_email'), $this->EE->config->item('webmaster_name'));
  1250. $this->EE->email->to($val['0']);
  1251. $this->EE->email->subject($title);
  1252. $this->EE->email->message(entities_to_ascii($message));
  1253. $this->EE->email->send();
  1254. $sent[] = $val['0'];
  1255. }
  1256. }
  1257. }
  1258. }
  1259. return;
  1260. }
  1261. // --------------------------------------------------------------------
  1262. /**
  1263. * Update Entry and Channel Stats
  1264. *
  1265. * @return void
  1266. */
  1267. public function update_stats($entry_ids, $channel_ids, $author_ids)
  1268. {
  1269. foreach($entry_ids as $entry_id)
  1270. {
  1271. $query = $this->EE->db->query("SELECT MAX(comment_date) AS max_date FROM exp_comments WHERE status = 'o' AND entry_id = '".$this->EE->db->escape_str($entry_id)."'");
  1272. $comment_date = ($query->num_rows() == 0 OR ! is_numeric($query->row('max_date') )) ? 0 : $query->row('max_date') ;
  1273. $query = $this->EE->db->query("SELECT COUNT(*) AS count FROM exp_comments WHERE entry_id = '".$this->EE->db->escape_str($entry_id)."' AND status = 'o'");
  1274. $this->EE->db->set('comment_total', $query->row('count'));
  1275. $this->EE->db->set('recent_comment_date', $comment_date);
  1276. $this->EE->db->where('entry_id', $entry_id);
  1277. $this->EE->db->update('channel_titles');
  1278. }
  1279. // Quicker and updates just the channels
  1280. foreach($channel_ids as $channel_id)
  1281. {
  1282. $this->EE->stats->update_comment_stats($channel_id, '', FALSE);
  1283. }
  1284. // Updates the total stats
  1285. $this->EE->stats->update_comment_stats();
  1286. foreach($author_ids as $author_id)
  1287. {
  1288. $res = $this->EE->db->query("SELECT COUNT(comment_id) AS comment_total, MAX(comment_date) AS comment_date FROM exp_comments WHERE author_id = '$author_id'");
  1289. $resrow = $res->row_array();
  1290. $comment_total = $resrow['comment_total'] ;
  1291. $comment_date = ( ! empty($resrow['comment_date'])) ? $resrow['comment_date'] : 0;
  1292. $this->EE->db->query($this->EE->db->update_string('exp_members', array('total_comments' => $comment_total, 'last_comment_date' => $comment_date), "member_id = '$author_id'"));
  1293. }
  1294. return;
  1295. }
  1296. // --------------------------------------------------------------------
  1297. /**
  1298. * Settings page
  1299. *
  1300. * @return void
  1301. */
  1302. public function settings()
  1303. {
  1304. $this->_permissions_check();
  1305. $this->EE->load->library('table');
  1306. $this->EE->load->library('javascript');
  1307. $this->EE->load->helper('form');
  1308. $vars = array('action_url' => 'C=addons_modules'.AMP.'M=show_module_cp'.AMP.'module=comment'.AMP.'method=save_settings'
  1309. );
  1310. $this->EE->cp->set_variable('cp_page_title', lang('comment_settings'));
  1311. $this->EE->cp->set_variable('cp_breadcrumbs', array(
  1312. $this->base_url => lang('comments')));
  1313. $vars['comment_word_censoring'] = ($this->EE->config->item('comment_word_censoring') == 'y') ? TRUE : FALSE;
  1314. $vars['comment_moderation_override'] = ($this->EE->config->item('comment_moderation_override') == 'y') ? TRUE : FALSE;
  1315. $vars['comment_edit_time_limit'] = ($this->EE->config->item('comment_edit_time_limit') && ctype_digit($this->EE->config->item('comment_edit_time_limit'))) ? $this->EE->config->item('comment_edit_time_limit') : 0;
  1316. return $this->EE->load->view('settings', $vars, TRUE);
  1317. }
  1318. // --------------------------------------------------------------------
  1319. /**
  1320. * Update Comment Settings
  1321. *
  1322. * @return void
  1323. */
  1324. public function save_settings()
  1325. {
  1326. $this->_permissions_check();
  1327. $timelimit = $this->EE->input->post('comment_edit_time_limit');
  1328. $insert['comment_word_censoring'] = ($this->EE->input->post('comment_word_censoring')) ? 'y' : 'n';
  1329. $insert['comment_moderation_override'] = ($this->EE->input->post('comment_moderation_override')) ? 'y' : 'n';
  1330. $insert['comment_edit_time_limit'] = ($timelimit && ctype_digit($timelimit)) ? $timelimit : '';
  1331. $this->EE->config->_update_config($insert);
  1332. $this->EE->session->set_flashdata('message_success', lang('settings_updated'));
  1333. $this->EE->functions->redirect($this->base_url.AMP.'method=settings');
  1334. }
  1335. }
  1336. // END CLASS
  1337. /* End of file mcp.comment.php */
  1338. /* Location: ./system/expressionengine/modules/comment/mcp.comment.php */