PageRenderTime 59ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/system/expressionengine/modules/comment/mcp.comment.php

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