PageRenderTime 74ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 1ms

/cp/expressionengine/modules/comment/mcp.comment.php

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