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