<?php
/**
 * This file implements newsletter functions.
 *
 * This file is part of the b2evolution/evocms project - {@link http://b2evolution.net/}.
 * See also {@link https://github.com/b2evolution/b2evolution}.
 *
 * @license GNU GPL v2 - {@link http://b2evolution.net/about/gnu-gpl-license}
 *
 * @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}.
 * Parts of this file are copyright (c)2004-2005 by Daniel HAHLER - {@link http://thequod.de/contact}.
 *
 * @package evocore
 */
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );


/**
 * Get user IDs from current filterset of users list
 *
 * @param string Filterset name
 * return array User IDs
 */
function get_filterset_user_IDs( $filterset_name = 'admin' )
{
	load_class( 'users/model/_userlist.class.php', 'UserList' );
	// Initialize users list from session cache in order to get users IDs for newsletter
	$UserList = new UserList( $filterset_name );
	$UserList->memorize = false;
	$UserList->load_from_Request();

	return $UserList->filters['users'];
}

/**
 * Get campaign edit modes
 *
 * @param integer Campaign ID
 * @return array with modes
 */
function get_campaign_edit_modes( $campaign_ID, $glue = '&amp;' )
{
	global $admin_url;

	$EmailCampaignCache = & get_EmailCampaignCache();
	$EmailCampaign = & $EmailCampaignCache->get_by_ID( $campaign_ID );

	$modes = array();

	$edit_url = $admin_url.'?ctrl=campaigns'.$glue.'action=edit'.$glue.'ecmp_ID='.$campaign_ID;

	$url = $edit_url.$glue.'tab=info';
	$modes['info'] = array(
		'text' => T_('Campaign info'),
		'href' => $url
	);
	if( check_user_perm( 'emails', 'edit' ) )
	{ // User must has a permission to edit emails
		$modes['info']['onclick'] = "return b2edit_reload( '#campaign_form', '$url', 'undefined', {tab:'info'} );";
	}

	$url = $edit_url.$glue.'tab=compose';
	$modes['compose'] = array(
		'text' => T_('Compose'),
		'href' => $url
	);
	if( check_user_perm( 'emails', 'edit' ) )
	{ // User must has a permission to edit emails
		$modes['compose']['onclick'] = "return b2edit_reload( '#campaign_form', '$url', 'undefined', {tab:'compose'} );";
	}

	$url = $edit_url.$glue.'tab=plaintext';
	$modes['plaintext'] = array(
		'text'  => T_('Plain-text version'),
		'href'  => $url,
		'class' => 'ecmp_plaintext_tab'.( $EmailCampaign->get( 'sync_plaintext' ) ? ' hidden' : '' ),
	);
	if( check_user_perm( 'emails', 'edit' ) )
	{ // User must has a permission to edit emails
		$modes['plaintext']['onclick'] = "return b2edit_reload( '#campaign_form', '$url', 'undefined', {tab:'plaintext'} );";
	}

	$url = $edit_url.$glue.'tab=send';
	$modes['send'] = array(
		'text' => T_('Review and send'),
		'href' => $url
	);
	if( check_user_perm( 'emails', 'edit' ) )
	{ // User must has a permission to edit emails
		$modes['send']['onclick'] = "return b2edit_reload( '#campaign_form', '$url', 'undefined', {tab:'send'} );";
	}

	$url = $edit_url.$glue.'tab=recipient'.$glue.'filter=new';
	$modes['recipient'] = array(
		'text' => T_('Recipient list'),
		'href' => $url
	);
	if( check_user_perm( 'emails', 'edit' ) )
	{ // User must has a permission to edit emails
		$modes['recipient']['onclick'] = "return b2edit_reload( '#campaign_form', '$url', 'undefined', {tab:'recipient'} );";
	}

	$url = $edit_url.$glue.'tab=plugins';
	$modes['plugins'] = array(
		'text' => T_('Plugins'),
		'href' => $url
	);
	if( check_user_perm( 'emails', 'edit' ) )
	{ // User must has a permission to edit emails
		$modes['plugins']['onclick'] = "return b2edit_reload( '#campaign_form', '$url', 'undefined', {tab:'plugins'} );";
	}

	return $modes;
}


/**
 * Get URL for current/next tab of edit campaign view
 *
 * @param string Current tab: 'info', 'compose', 'send'
 * @param integer Campaign ID
 * @param string Type of tab: 'current', 'next'
 * @param string Glue
 * @return string URL
 */
function get_campaign_tab_url( $current_tab, $campaign_ID, $type = 'current', $glue = '&' )
{
	$modes = get_campaign_edit_modes( $campaign_ID, $glue );

	$EmailCampaignCache = & get_EmailCampaignCache();
	$EmailCampaign = & $EmailCampaignCache->get_by_ID( $campaign_ID );

	switch( $type )
	{
		case 'current':
			// Get URL of current tab
			if( !empty( $modes[ $current_tab ] ) )
			{
				if( $current_tab == 'plaintext' && $EmailCampaign->get( 'sync_plaintext' ) )
				{	// Don't allow tab plaintext when it is not enabled:
					return $modes['compose']['href'];
				}
				else
				{
					return $modes[ $current_tab ]['href'];
				}
			}
			break;

		case 'next':
		default:
			// Get URL of next tab:
			$this_tab = false;
			foreach( $modes as $tab_name => $tab_info )
			{
				if( $this_tab )
				{ // We find URL for next tab
					return ( $tab_name == 'plaintext' && $EmailCampaign->get( 'sync_plaintext' ) ) ? $modes['send']['href'] : $tab_info['href'];
				}
				if( $tab_name == $current_tab )
				{ // The next tab will be what we find
					$this_tab = true;
				}
			}
		break;
	}

	return '';
}


/**
 * Queue user to receive to email campaign
 *
 * @param integer Campaign ID
 * @param integer User ID to queue
 */
function queue_campaign_user( $campaign_ID, $user_ID )
{
	global $DB;

	if( empty( $campaign_ID ) || empty( $user_ID ) )
	{
		return;
	}

	$DB->query( 'UPDATE T_email__campaign_send
			SET csnd_status = IF( csnd_emlog_ID IS NULL, "ready_to_send", "ready_to_resend" )
			WHERE csnd_camp_ID = '.$DB->quote( $campaign_ID ).'
			AND csnd_user_ID = '.$DB->quote( $user_ID ) );
}


/**
 * Skip user from receiving email campaign
 *
 * @param integer Campaign ID
 * @param integer User ID to skip
 */
function skip_campaign_user( $campaign_ID, $user_ID )
{
	global $DB;

	if( empty( $campaign_ID ) || empty( $user_ID ) )
	{
		return;
	}

	$DB->query( 'UPDATE T_email__campaign_send
			SET csnd_status = "skipped"
			WHERE csnd_camp_ID = '.$DB->quote( $campaign_ID ).'
			AND csnd_user_ID = '.$DB->quote( $user_ID ) );
}


/**
 * Check if campaign email is opened
 *
 * @param integer Email log ID
 * @param array Associative array of campaign email send data
 * @return mixed NULL if the email log record does not exist, true if email is considered open, false otherwise
 */
function is_unopened_campaign_mail( $email_log_ID, & $send_data = NULL )
{
	global $DB;

	$send_data = $DB->get_row( 'SELECT * FROM T_email__campaign_send WHERE csnd_emlog_ID = '.$DB->quote( $email_log_ID ).' LIMIT 1', ARRAY_A );

	if( $send_data )
	{
		// Unsubscribe clicks do not "open" emails
		return empty( $send_data['csnd_last_open_ts'] ) && // image load
				empty( $send_data['csnd_last_click_ts'] ) &&
				empty( $send_data['csnd_like'] ) &&
				empty( $send_data['csnd_cta1'] ) &&
				empty( $send_data['csnd_cta2'] ) &&
				empty( $send_data['csnd_cta3'] );
	}
	else
	{
		return NULL;
	}
}


/**
 * Get EmailCampaign object from object which is used to select recipients
 *
 * @return object EmailCampaign
 */
function & get_session_EmailCampaign()
{
	global $Session;

	$EmailCampaignCache = & get_EmailCampaignCache();
	$edited_EmailCampaign = & $EmailCampaignCache->get_by_ID( $Session->get( 'edited_campaign_ID' ), false, false );

	return $edited_EmailCampaign;
}


/**
 * Display link to filtered userlist
 *
 * @param Object EmailCampaign object
 * @param String Recipient action on email campaign
 * @return String <a> tag
 */
function campaign_td_recipient_action( $row, $recipient_action )
{
	global $admin_url;

	if( empty( $row->ecmp_send_count ) )
	{
		return NULL;
	}

	$url = $admin_url.'?ctrl=campaigns&amp;action=edit&amp;ecmp_ID='.$row->ecmp_ID.'&amp;tab=recipient&amp;filter=new';

	switch( $recipient_action )
	{
		case 'img_loaded':
			$text = $row->ecmp_img_loads;
			break;

		case 'link_clicked':
			$text = $row->ecmp_link_clicks;
			break;

		case 'cta1':
			$text = $row->ecmp_cta1_clicks;
			break;

		case 'cta2':
			$text = $row->ecmp_cta2_clicks;
			break;

		case 'cta3':
			$text = $row->ecmp_cta3_clicks;
			break;

		case 'liked':
			$text = $row->ecmp_like_count;
			$class = 'text-success';
			break;

		case 'disliked':
			$text = $row->ecmp_dislike_count;
			$class = 'text-danger';
			break;

		case 'clicked_unsubscribe':
			$text = $row->ecmp_unsub_clicks;
			$class = 'text-danger';
			break;
	}

	return '<a href="'.$url.( empty( $recipient_action ) ? '' : '&amp;recipient_action='.$recipient_action ).'"'.
			( empty( $class ) ? '': ' class="'.$class.'"' ).'>'.$text.'</a>';
}


/**
 * Callback to add filters on top of the result set
 *
 * @param Form
 */
function filter_campaign_results_block( & $Form )
{
	$Form->text_input( 'username', get_param( 'username' ), 40, T_('Username or email address') );
}


/**
 * Display the campaigns results table
 *
 * @param array Params
 */
function campaign_results_block( $params = array() )
{
	global $admin_url, $UserSettings, $DB;

	$params = array_merge( array(
		'enlt_ID'               => NULL,
		'results_title'         => T_('Email campaigns').get_manual_link( 'email-campaign-list' ),
		'display_create_button' => true
	), $params );

	// Create result set:
	$SQL = new SQL();
	$SQL->SELECT( 'DISTINCT ecmp_ID, T_email__campaign.*, enlt_ID, enlt_name, IF( ecmp_send_count = 0, 0, ecmp_open_count / ecmp_send_count ) AS open_rate' );
	$SQL->FROM( 'T_email__campaign' );
	$SQL->FROM_add( 'INNER JOIN T_email__newsletter ON ecmp_enlt_ID = enlt_ID' );
	$SQL->WHERE( 1 );

	$count_SQL = new SQL();
	$count_SQL->SELECT( 'COUNT( DISTINCT ecmp_ID )' );
	$count_SQL->FROM( 'T_email__campaign' );
	$count_SQL->FROM_add( 'INNER JOIN T_email__newsletter ON ecmp_enlt_ID = enlt_ID' );

	if( isset( $params['enlt_ID'] ) )
	{	// Filter by Newsletter:
		$SQL->WHERE_and( 'ecmp_enlt_ID = '.$DB->quote( $params['enlt_ID'] ) );
		$count_SQL->WHERE_and( 'ecmp_enlt_ID = '.$DB->quote( $params['enlt_ID'] ) );
	}

	$username = param( 'username', 'string', NULL );
	if( ! empty( $username ) )
	{	// Filter by user login, first name, last name, nickname:
		$sql_where = array();
		$kw_array = explode( ' ', $username );
		foreach( $kw_array as $kw )
		{	// Note: we use CONCAT_WS (Concat With Separator) because CONCAT returns NULL if any arg is NULL
			$sql_where[] = 'CONCAT_WS( " ", user_login, user_firstname, user_lastname, user_nickname, user_email ) LIKE '.$DB->quote( '%'.$kw.'%' );
		}
		$sql_where = implode( ' OR ', $sql_where );
		$SQL->WHERE_and( $sql_where );
		$count_SQL->WHERE_and( $sql_where );
		// Join additional tables for the user columns:
		$SQL->FROM_add( 'LEFT JOIN T_email__campaign_send ON csnd_camp_ID = ecmp_ID AND csnd_emlog_ID IS NOT NULL' );
		$SQL->FROM_add( 'LEFT JOIN T_users ON csnd_user_ID = user_ID' );
		$count_SQL->FROM_add( 'LEFT JOIN T_email__campaign_send ON csnd_camp_ID = ecmp_ID AND csnd_emlog_ID IS NOT NULL' );
		$count_SQL->FROM_add( 'LEFT JOIN T_users ON csnd_user_ID = user_ID' );
	}

	$Results = new Results( $SQL->get(), isset( $params['enlt_ID'] ) ? 'lemcmp_' : 'emcmp_', 'D', $UserSettings->get( 'results_per_page' ), $count_SQL->get() );
	$Results->Cache = & get_EmailCampaignCache();
	$Results->title = $params['results_title'];

	if( check_user_perm( 'emails', 'edit' ) && $params['display_create_button'] )
	{ // User must has a permission to edit emails
		$Results->global_icon( T_('Create new campaign').'...', 'new', $admin_url.'?ctrl=campaigns&amp;action=new'.( isset( $params['enlt_ID'] ) ? '&amp;enlt_ID='.$params['enlt_ID'] : '' ), T_('Create new campaign').' &raquo;', 3, 4, array( 'class' => 'action_icon btn-primary' ) );
	}

	$Results->filter_area = array( 
			'callback' => 'filter_campaign_results_block' 
		);

	$Results->register_filter_preset( 'all', T_('All'),
		isset( $params['enlt_ID'] )
		// URL to display campaigns of the edited List:
		? $admin_url.'?ctrl=newsletters&amp;action=edit&amp;tab=campaigns&amp;enlt_ID='.$params['enlt_ID']
		// URL to display all campaigns:
		: $admin_url.'?ctrl=campaigns' );

	$Results->cols[] = array(
			'th' => T_('ID'),
			'order' => 'ecmp_ID',
			'th_class' => 'shrinkwrap',
			'td_class' => 'right',
			'td' => '$ecmp_ID$',
		);

	$Results->cols[] = array(
			'th' => T_('Date'),
			'order' => 'ecmp_date_ts',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'timestamp',
			'td' => '%mysql2localedatetime_spans( #ecmp_date_ts# )%',
		);

	$Results->cols[] = array(
			'th' => T_('List'),
			'order' => 'enlt_name',
			'td' => '<a href="'.$admin_url.'?ctrl=newsletters&amp;action=edit&amp;enlt_ID=$enlt_ID$"><b>$enlt_name$</b></a>',
			'th_class' => 'shrinkwrap',
			'td_class' => 'nowrap',
		);

	$Results->cols[] = array(
			'th' => T_('Campaign name'),
			'order' => 'ecmp_name',
			'td' => '<a href="'.$admin_url.'?ctrl=campaigns&amp;action=edit&amp;ecmp_ID=$ecmp_ID$"><b>$ecmp_name$</b></a>',
		);

	$Results->cols[] = array(
			'th' => T_('Email title'),
			'order' => 'ecmp_email_title',
			'td' => '<a href="'.$admin_url.'?ctrl=campaigns&amp;action=edit&amp;ecmp_ID=$ecmp_ID$&amp;tab=compose"><b>$ecmp_email_title$</b></a>',
		);

	$Results->cols[] = array(
			'th' => T_('Welcome'),
			'order' => 'ecmp_welcome',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' => '%campaign_td_welcome( #ecmp_ID#, #ecmp_welcome#, #ecmp_activate# )%',
		);

	$Results->cols[] = array(
			'th' => T_('Sent manually'),
			'order' => 'ecmp_sent_ts',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'timestamp',
			'td' => '%mysql2localedatetime_spans( #ecmp_sent_ts# )%',
		);

	$Results->cols[] = array(
			'th' => T_('Sent automatically'),
			'order' => 'ecmp_auto_sent_ts',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'timestamp',
			'td' => '%mysql2localedatetime_spans( #ecmp_auto_sent_ts# )%',
		);

	$Results->cols[] = array(
			'th' => T_('Send count'),
			'order' => 'ecmp_send_count',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'$ecmp_send_count$'
		);

	$Results->cols[] = array(
			'th' => T_('Open rate'),
			'order' => 'open_rate',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'%empty( #ecmp_send_count# ) ? "" : number_format( #open_rate# * 100, 1 )%%'
		);

	$Results->cols[] = array(
			'th' => /* TRANS: Image load count */ T_('Img loads'),
			'order' => 'ecmp_img_loads',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'%campaign_td_recipient_action( {row}, "img_loaded" )%',
		);

	$Results->cols[] = array(
			'th' => T_('Link clicks'),
			'order' => 'ecmp_link_clicks',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'%campaign_td_recipient_action( {row}, "link_clicked" )%',
		);

	$Results->cols[] = array(
			'th' => /* TRANS: Call To Action 1*/ T_('CTA1'),
			'order' => 'ecmp_cta1_clicks',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'%campaign_td_recipient_action( {row}, "cta1" )%',
		);

	$Results->cols[] = array(
			'th' => /* TRANS: Call To Action 2*/ T_('CTA2'),
			'order' => 'ecmp_cta2_clicks',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'%campaign_td_recipient_action( {row}, "cta2" )%',
		);

	$Results->cols[] = array(
			'th' => /* TRANS: Call To Action 3*/ T_('CTA3'),
			'order' => 'ecmp_cta3_clicks',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center',
			'td' =>'%campaign_td_recipient_action( {row}, "cta3" )%',
		);

	$Results->cols[] = array(
			'th' => T_('Likes'),
			'order' => 'ecmp_like_count',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center text-success',
			'td' =>'%campaign_td_recipient_action( {row}, "liked" )%',
		);

	$Results->cols[] = array(
			'th' => T_('Dislikes'),
			'order' => 'ecmp_dislike_count',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center text-danger',
			//'td' =>'%empty( #send_count# ) ? "" : #dislike_count#%'
			'td' =>'%campaign_td_recipient_action( {row}, "disliked" )%',
		);

	$Results->cols[] = array(
			'th' => T_('Unsub clicks'),
			'order' => 'ecmp_unsub_clicks',
			'default_dir' => 'D',
			'th_class' => 'shrinkwrap',
			'td_class' => 'center text-danger',
			//'td' =>'%empty( #send_count# ) ? "" : #unsubscribe_click_count#%'
			'td' => '%campaign_td_recipient_action( {row}, "clicked_unsubscribe" )%'
		);

	$Results->cols[] = array(
			'th' => T_('Actions'),
			'th_class' => 'shrinkwrap',
			'td_class' => 'shrinkwrap',
			'td' => action_icon( T_('Edit this email campaign...'), 'properties', $admin_url.'?ctrl=campaigns&amp;action=edit&amp;ecmp_ID=$ecmp_ID$' )
				.( check_user_perm( 'emails', 'edit' ) ?
				// Display an action icon to delete newsletter if current User has a perm:
				action_icon( T_('Duplicate this email campaign...'), 'copy', $admin_url.'?ctrl=campaigns&amp;action=copy&amp;ecmp_ID=$ecmp_ID$' )
				.action_icon( T_('Delete this email campaign!'), 'delete', $admin_url.'?ctrl=campaigns&amp;action=delete&amp;ecmp_ID=$ecmp_ID$&amp;'.url_crumb( 'campaign' ) ) : '' )
		);

	// Display results:
	$Results->display( NULL, 'session' );
}


/**
 * Helper function to display a welcome status of email campaign in list
 *
 * @param integer Email Campaign ID
 * @param integer TRUE/1 if this is a welcome Email Campaign
 * @param integer TRUE/1 if this is an activate Email Campaign
 * @return string
 */
function campaign_td_welcome( $ecmp_ID, $ecmp_welcome, $ecmp_activate )
{
	if( $ecmp_welcome )
	{	// If email campaign is used as welcome message:
		$welcome_icon = get_icon( 'bullet_green', 'imgtag', array( 'title' => T_('The email campaign is used as "Welcome" for its list.') ) );
		if( $ecmp_activate )
		{	// If email campaign is used as activate message:
			$activate_icon = get_icon( 'bullet_dark_blue', 'imgtag', array( 'title' => T_('This welcome email doubles as an activation message. No separate activation email will be sent.') ) );
		}
		else
		{	// If email campaign is NOT used as activate message:
			$activate_icon = get_icon( 'bullet_empty_grey', 'imgtag', array( 'title' => T_('This welcome email does not act as an activation message.') ) );
		}
	}
	else
	{	// If email campaign is NOT used as welcome message:
		$welcome_icon = get_icon( 'bullet_empty_grey', 'imgtag', array( 'title' => T_('The email campaign is not used as "Welcome" for its list.') ) );
		// Don't use email campaign as activate message when it is not used as welcome message:
		$activate_icon = '';
	}

	if( check_user_perm( 'emails', 'edit' ) )
	{	// Make icon(s) toggle welcome/activate statuses if current User has a perm to edit this:
		global $admin_url, $ctrl;
		$icon_url = $admin_url.'?ctrl=campaigns'
			.'&amp;ecmp_ID='.$ecmp_ID
			.( $ctrl == 'newsletters' ? '&amp;from='.$ctrl : '' )
			.'&amp;'.url_crumb( 'campaign' );
		$welcome_icon = '<a href="'.$icon_url.'&amp;action='.( $ecmp_welcome ? 'disable_welcome' : 'enable_welcome' ).'">'.$welcome_icon.'</a>';
		if( ! empty( $activate_icon ) )
		{	// Make activate icon clickable:
			$activate_icon = '<a href="'.$icon_url.'&amp;action='.( $ecmp_activate ? 'disable_activate' : 'enable_activate' ).'">'.$activate_icon.'</a>';
		}
	}

	return $welcome_icon.( empty( $activate_icon ) ? '' : ' '.$activate_icon );
}
?>