1<?php
2/*
3 * e107 website system
4 *
5 * Copyright (C) 2008-2017 e107 Inc (e107.org)
6 * Released under the terms and conditions of the
7 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
8 *
9 * Mailout - admin-related functions
10 *
11 */
12
13/**
14 *	Various admin-related mailout functions, mostly to do with creating and
15 * handling forms.
16 *
17 *	@package     e107
18 *	@subpackage	e107_handlers
19 */
20
21/*
22 TODO:
23 1. Use API to downloads plugin to get available files (when available)
24 2. Fuller checking prior to send
25 3. May want more control over date display format
26 4. Use new date picker
27 */
28
29if(!defined('e107_INIT'))
30{
31	exit ;
32}
33
34define('MAIL_ADMIN_DEBUG', TRUE);
35
36require_once (e_HANDLER . 'mail_manager_class.php');
37
38class mailoutAdminClass extends e107MailManager
39{
40	public $_cal = array();
41	protected $mode;
42	// So we know what the current task is
43	protected $mailHandlers = array();
44	protected $showFrom = 0;
45	protected $showCount = 10;
46	protected $sortField = 'mail_source_id';
47	protected $sortOrder = 'asc';
48	protected $fieldPref = array();
49	protected $userCache = array();
50
51	// Definitions associated with each column which might be displayed. (Compatible
52	// with forms-based display)
53	// Fields are displayed in the order listed.
54	// Can also have:	width
55	//					type
56	//					thclass
57	protected $fields = array(
58		'mail_recipients' => array(
59			'mail_target_id' => array(
60				'title' => LAN_MAILOUT_143,
61				'thclass' => 'center',
62				'forced' => TRUE
63			),
64			'mail_recipient_id' => array(
65				'title' => LAN_MAILOUT_142,
66				'thclass' => 'center'
67			),
68			'mail_recipient_name' => array(
69				'title' => LAN_MAILOUT_141,
70				'forced' => TRUE
71			),
72			'mail_recipient_email' => array(
73				'title' => LAN_MAILOUT_140,
74				'thclass' => 'left',
75				'forced' => TRUE
76			),
77			'mail_status' => array(
78				'title' => LAN_MAILOUT_138,
79				'thclass' => 'center',
80				'proc' => 'contentstatus'
81			),
82			'mail_detail_id' => array('title' => LAN_MAILOUT_137),
83			'mail_send_date' => array(
84				'title' => LAN_MAILOUT_139,
85				'proc' => 'sdatetime'
86			),
87			'mail_target_info' => array(
88				'title' => LAN_MAILOUT_148,
89				'proc' => 'array'
90			),
91			'options' => array(
92				'title' => LAN_OPTIONS,
93				'forced' => TRUE
94			)
95		),
96		'mail_content' => array(
97			'mail_source_id' => array(
98				'title' => LAN_MAILOUT_137,
99				'thclass' => 'center',
100				'forced' => TRUE
101			),
102			'mail_title' => array(
103				'title' => LAN_TITLE,
104				'forced' => TRUE
105			),
106			'mail_subject' => array(
107				'title' => LAN_MAILOUT_06,
108				'forced' => TRUE
109			),
110			'mail_content_status' => array(
111				'title' => LAN_MAILOUT_136,
112				'thclass' => 'center',
113				'proc' => 'contentstatus'
114			),
115			'mail_togo_count' => array('title' => LAN_MAILOUT_83),
116			'mail_sent_count' => array('title' => LAN_MAILOUT_82),
117			'mail_fail_count' => array('title' => LAN_MAILOUT_128),
118			'mail_bounce_count' => array('title' => LAN_MAILOUT_144),
119			'mail_start_send' => array(
120				'title' => LAN_MAILOUT_131,
121				'proc' => 'sdatetime'
122			),
123			'mail_end_send' => array(
124				'title' => LAN_MAILOUT_132,
125				'proc' => 'sdatetime'
126			),
127			'mail_create_date' => array(
128				'title' => LAN_MAILOUT_130,
129				'proc' => 'sdatetime'
130			),
131			'mail_creator' => array(
132				'title' => LAN_MAILOUT_85,
133				'proc' => 'username'
134			),
135			'mail_create_app' => array('title' => LAN_SOURCE),
136			'mail_e107_priority' => array('title' => LAN_MAILOUT_134),
137			'mail_notify_complete' => array(
138				'title' => LAN_MAILOUT_243,
139				'nolist' => 'TRUE'
140			),
141			'mail_last_date' => array(
142				'title' => LAN_MAILOUT_129,
143				'proc' => 'sdatetime'
144			),
145			'mail_body' => array(
146				'title' => LAN_MAILOUT_100,
147				'proc' => 'trunc200'
148			),
149			'mail_body_templated' => array(
150				'title' => LAN_MAILOUT_257,
151				'proc' => 'chars'
152			),
153			//	'mail_other' = array('title' => LAN_MAILOUT_84),
154			'mail_sender_email' => array('title' => LAN_MAILOUT_149),
155			'mail_sender_name' => array('title' => LAN_MAILOUT_150),
156			'mail_copy_to' => array('title' => LAN_MAILOUT_151),
157			'mail_bcopy_to' => array('title' => LAN_MAILOUT_152),
158			'mail_attach' => array('title' => LAN_MAILOUT_153),
159			'mail_send_style' => array('title' => LAN_MAILOUT_154),
160			'mail_selectors' => array(
161				'title' => LAN_MAILOUT_155,
162				'proc' => 'selectors',
163				'nolist' => 'TRUE'
164			),
165			'mail_include_images' => array(
166				'title' => LAN_MAILOUT_224,
167				'proc' => 'yesno'
168			),
169			'options' => array(
170				'title' => LAN_OPTIONS,
171				'forced' => TRUE
172			)
173		)
174	);
175
176	// List of fields to be hidden for each action ('nolist' attribute true)
177	protected $hideFields = array(
178		'orphans' => array(),
179		'saved' => 'mail_content_status,mail_togo_count,mail_sent_count,mail_fail_count,mail_bounce_count,mail_start_send,mail_end_send,mail_e107_priority,mail_notify_complete,mail_last_date,mail_selectors',
180		'sent' => 'mail_togo_count,mail_last_date,mail_selectors,mail_notify_complete',
181		//		'pending'  =>
182		// 'mail_togo_count,mail_sent_count,mail_fail_count,mail_bounce_count,mail_start_send,mail_end_send,mail_e107_priority,mail_last_date,mail_selectors',
183		'pending' => 'mail_start_send,mail_end_send,mail_e107_priority,mail_notify_complete,mail_last_date,mail_selectors',
184		'held' => 'mail_sent_count,mail_fail_count,mail_bounce_count,mail_start_send,mail_end_send,mail_e107_priority,mail_notify_complete,mail_last_date,mail_selectors',
185		'resend' => 'mail_Selectors,mail_notify_complete',
186		'recipients' => 'mail_detail_id'
187	);
188
189	// Array of info associated with each task we might do
190	protected $tasks = array(
191		'makemail' => array(
192			'title' => LAN_MAILOUT_190,
193			'defaultSort' => '',
194			'defaultTable' => ''
195		),
196		'saved' => array(
197			'title' => LAN_MAILOUT_191,
198			'defaultSort' => 'mail_source_id',
199			'defaultTable' => 'mail_content'
200		),
201		'marksend' => array(
202			'title' => 'Internal: marksend',
203			'defaultSort' => 'mail_source_id',
204			'defaultTable' => 'mail_content'
205		),
206		'sent' => array(
207			'title' => LAN_MAILOUT_192,
208			'defaultSort' => 'mail_source_id',
209			'defaultTable' => 'mail_content'
210		),
211		'pending' => array(
212			'title' => LAN_MAILOUT_193,
213			'defaultSort' => 'mail_source_id',
214			'defaultTable' => 'mail_content'
215		),
216		'held' => array(
217			'title' => LAN_MAILOUT_194,
218			'defaultSort' => 'mail_source_id',
219			'defaultTable' => 'mail_content'
220		),
221		'recipients' => array(
222			'title' => LAN_MAILOUT_173,
223			'defaultSort' => 'mail_recipient_email',
224			'defaultTable' => 'mail_recipients'
225		),
226		'mailtargets' => array(
227			'title' => LAN_MAILOUT_173,
228			'defaultSort' => 'mail_recipient_email',
229			'defaultTable' => 'mail_recipients'
230		),
231		'prefs' => array(
232			'title' => ADLAN_40,
233			'defaultSort' => '',
234			'defaultTable' => ''
235		),
236		'maint' => array(
237			'title' => ADLAN_40,
238			'defaultSort' => '',
239			'defaultTable' => ''
240		)
241	);
242
243	// Options for mail listing dropdown - actions apertaining to a stored email
244	protected $modeOptions = array(
245		'saved' => array(
246			'mailedit' => LAN_MAILOUT_163,
247			'maildelete' => LAN_DELETE,
248			'mailshowtemplate' => LAN_MAILOUT_254
249		),
250		'pending' => array(
251			'mailsendimmediately' => "Send Immediately",
252			'mailhold' => LAN_MAILOUT_159,
253			'mailcancel' => LAN_MAILOUT_160,
254			'mailtargets' => LAN_MAILOUT_181
255		),
256		'held' => array(
257			'mailsendnow' => LAN_MAILOUT_158,
258			'mailcancel' => LAN_MAILOUT_160,
259			'mailtargets' => LAN_MAILOUT_181
260		),
261		'sent' => array(
262			'mailcopy' => LAN_MAILOUT_251,
263			'maildelete' => LAN_DELETE,
264			'mailtargets' => LAN_MAILOUT_181
265		),
266		'recipients' => array('mailonedelete' => LAN_DELETE)
267	);
268
269	// List of fields to be included in email display for various options
270	protected $mailDetailDisplay = array(
271		'basic' => array(
272			'mail_source_id' => 1,
273			'mail_title' => 1,
274			'mail_subject' => 1,
275			'mail_body' => 200
276		),
277		'send' => array(
278			'mail_source_id' => 1,
279			'mail_title' => 1,
280			'mail_subject' => 1,
281			'mail_body' => 500,
282			'mail_send_style' => 1
283		),
284		'template' => array(
285			'mail_source_id' => 1,
286			'mail_title' => 1,
287			'mail_subject' => 1,
288			'mail_body' => 200,
289			'mail_body_templated' => 'chars'
290		),
291	);
292
293	/**
294	 * Constructor
295	 *
296	 *
297	 * @return void
298	 */
299	public function __construct($mode = '')
300	{
301		parent::__construct();
302
303		$dbTable = '';
304		if(isset($this->tasks[$mode]))
305		{
306			$dbTable = $this->tasks[$mode]['defaultTable'];
307		}
308		if(isset($_GET['frm']))
309		{
310			$temp = intval($_GET['frm']);
311			if($temp < 0)
312				$temp = 0;
313			$this->showFrom = $temp;
314		}
315		if(isset($_GET['count']))
316		{
317			$temp = min(intval($_GET['count']), 50);
318			// Limit to 50 per page
319			$temp = max($temp, 5);
320			// ...and minimum 5 per page
321			$this->showCount = $temp;
322		}
323		if(isset($_GET['fld']))
324		{
325			$temp = e107::getParser()->toDB($_GET['fld']);
326			if(is_array($this->fields[$dbTable][$temp]))
327			{
328				$this->sortField = $temp;
329			}
330		}
331		if(isset($_GET['asc']))
332		{
333			$temp = strtolower(e107::getParser()->toDB($_GET['asc']));
334			if(($temp == 'asc') || ($temp == 'desc'))
335			{
336				$this->sortOrder = $temp;
337			}
338		}
339		$this->newMode($mode);
340	}
341
342	/**
343	 * Set up new mode
344	 *
345	 * @param $mode - display mode
346	 * @return none
347	 */
348	public function newMode($mode = '')
349	{
350		global $user_pref;
351		$this->mode = $mode;
352		$curTable = $this->tasks[$this->mode]['defaultTable'];
353		if($curTable)
354		{
355			if(isset($user_pref['admin_mailout_columns'][$mode]) && is_array($user_pref['admin_mailout_columns'][$mode]))
356			{
357				// Use saved list of fields to view if it exists
358				$this->fieldPref = $user_pref['admin_mailout_columns'][$mode];
359			}
360			else
361			{
362				// Default list is minimal fields only
363				$this->fieldPref = array();
364				foreach($this->fields[$curTable] as $f => $v)
365				{
366					if(vartrue($v['forced']))
367					{
368						$this->fieldPref[] = $f;
369					}
370				}
371			}
372		}
373
374		// Possibly the sort field needs changing
375		if(!isset($this->fields[$curTable][$this->sortField]))
376		{
377			$this->sortField = $this->tasks[$mode]['defaultSort'];
378		}
379
380		// Now hide any fields that need to be for this mode
381		if(isset($this->hideFields[$mode]))
382		{
383			$hideList = array_flip(explode(',', $this->hideFields[$mode]));
384			foreach($this->fields[$curTable] as $f => $v)
385			{
386				$this->fields[$curTable][$f]['nolist'] = isset($hideList[$f]);
387			}
388			foreach($this->fieldPref as $k => $v)// Remove from list of active fields
389			// (shouldn't often do anything)
390			{
391				if(isset($hideList[$v]))
392				{
393					unset($this->fieldPref[$k]);
394				}
395			}
396		}
397	}
398
399	/**
400	 * Calculate the list of fields (columns) to be displayed for a given mode
401	 *
402	 * @param string $mode - display mode
403	 * @param boolean $noOptions - set TRUE to suppress inclusion of any 'options'
404	 * column. FALSE to include 'options' (default)
405	 * @return array of field definitions
406	 */
407	protected function calcFieldSpec($mode, $noOptions = FALSE)
408	{
409		if(!isset($this->tasks[$mode]))
410		{
411			echo "CalcfieldSpec({$mode}) - programming bungle<br />";
412			return FALSE;
413		}
414		$ret = array();
415		$curTable = $this->tasks[$this->mode]['defaultTable'];
416		foreach($this->fields[$curTable] as $f => $v)
417		{
418			if((vartrue($v['forced']) && !vartrue($v['nolist'])) || in_array($f, $this->fieldPref))
419			{
420				if(($f != 'options') || ($noOptions === FALSE))
421				{
422					$ret[] = $f;
423				}
424			}
425		}
426		return $ret;
427	}
428
429	/**
430	 * Save the column visibility prefs for this mode
431	 *
432	 * @param $target - display mode
433	 * @return none
434	 */
435	/*
436	 public function mailbodySaveColumnPref($target)
437	 {
438	 global $user_pref;
439	 if (!$target) return;
440	 if (!isset($this->tasks[$target]))
441	 {
442	 echo "Invalid prefs target: {$target}<br />";
443	 return;
444	 }
445	 if (isset ($_POST['etrigger_ecolumns']))
446	 {
447	 $user_pref['admin_mailout_columns'][$target] = $_POST['e-columns'];
448	 save_prefs('user');
449	 $this->fieldPref = $user_pref['admin_mailout_columns'][$target];
450	 }
451	 }
452	 */
453	/**
454	 *	Get the user name associated with a user ID.
455	 *	The result is cached in case required again
456	 *
457	 *	@param int $uid - User ID
458	 *
459	 *	@return string with user name and user login name (UID if user not found)
460	 */
461	protected function getUserName($uid)
462	{
463		if(!isset($this->userCache[$uid]))
464		{
465			// Look up user
466			$this->checkDB(2);
467			// Make sure DB object created
468			if($this->db2->select('user', 'user_name, user_loginname', 'user_id=' . intval($uid)))
469			{
470				$row = $this->db2->fetch();
471				$this->userCache[$uid] = $row['user_name'] . ' (' . $row['user_loginname'] . ')';
472			}
473			else
474			{
475				$this->userCache[$uid] = 'UID: ' . $uid;
476			}
477		}
478		return $this->userCache[$uid];
479	}
480
481	/**
482	 * Generate the HTML for displaying actions box for emails
483	 *
484	 * Options given depend on $mode (saved|sent|pending|held), and also values in
485	 * the email data.
486	 *
487	 * @param array $mailData - array of email-related info
488	 * @return string HTML for display
489	 */
490	public function makeMailOptions($mode, $mailData)
491	{
492		if(!is_numeric($mailData['mail_source_id']) || ($mailData['mail_source_id'] == 0))
493		{
494			echo "makeMailOptions ({$mode}): Programming bungle!";
495			print_a($mailData);
496			return 'Error';
497		}
498		$text = "<select name='mailaction[{$mailData['mail_source_id']}]' onchange='this.form.submit()' class='tbox' style='width:90%'>\n
499				<option selected='selected' value=''>&nbsp;</option>\n";
500		foreach($this->modeOptions[$mode] as $key => $val)
501		{
502			$text .= "<option value='{$key}'>{$val}</option>\n";
503		}
504		$text .= "</select>\n";
505		return $text;
506	}
507
508	/**
509	 * Generate the HTML for displaying actions box for emails
510	 *
511	 * Options given depend on $mode, and also values in the email data.
512	 *
513	 * @param $mailData - array of email-related info
514	 * @return HTML for display
515	 */
516	public function makeTargetOptions($mode, $targetData)
517	{
518		if(!is_numeric($targetData['mail_target_id']) || ($targetData['mail_target_id'] == 0))
519		{
520			echo "makeTargetOptions ({$mode}): Programming bungle!";
521			print_a($targetData);
522			return 'Error';
523		}
524		$text = "<select name='targetaction[{$targetData['mail_target_id']}]' onchange='this.form.submit()' class='tbox' style='width:90%'>\n
525				<option selected='selected' value=''>&nbsp;</option>\n";
526		foreach($this->modeOptions[$mode] as $key => $val)
527		{
528			$text .= "<option value='{$key}'>{$val}</option>\n";
529		}
530		$text .= "</select>\n";
531		return $text;
532	}
533
534	/**
535	 * Generate the HTML for displaying email selection fields
536	 *
537	 * @param $options - comma-separate string of handlers to load
538	 *	'core' - core handler
539	 *	plugin name - obvious!
540	 *	'all' - obvious!
541	 * @return Number of handlers loaded
542	 */
543	public function loadMailHandlers($options = 'all')
544	{
545		$pref = e107::getPref();
546
547		$pref['mailout_enabled'] = str_replace('core','user',$pref['mailout_enabled']); // BC fix.
548
549		$ret = 0;
550		$toLoad = explode(',', $options);
551
552		$active_mailers = explode(',', varset($pref['mailout_enabled'], 'user'));
553
554		if((in_array('core', $toLoad) || ($options == 'all')) && in_array('core', $active_mailers))
555		{
556		//	require_once (e_HANDLER . 'mailout_class.php');
557		//	$this->mailHandlers['core'] = new core_mailout; // Start by loading the core mailout class
558		//	$ret++;
559		}
560
561		if(empty($pref['e_mailout_list']))
562		{
563			return $ret;
564		}
565
566
567		// Load additional configured handlers e_mailout.php from plugins.
568		foreach($pref['e_mailout_list'] as $mailer => $v)
569		{
570
571			if(isset($pref['plug_installed'][$mailer]) && in_array($mailer, $active_mailers) && (($options == 'all') || in_array($mailer, $toLoad)))
572			{
573				// Could potentially use this handler - its installed and enabled
574				if(!is_readable(e_PLUGIN . $mailer . '/e_mailout.php'))
575				{
576					echo 'Invalid mailer selected: ' . $mailer . '<br />';
577					exit ;
578				}
579				require_once (e_PLUGIN . $mailer . '/e_mailout.php');
580				if(varset($mailerIncludeWithDefault, TRUE))
581				{
582					// Definitely need this plugin
583					$mailClass = $mailer . '_mailout';
584					$temp = new $mailClass;
585				//	$temp = e107::getSingleton($mailClass);
586					if($temp->mailerEnabled)
587					{
588						$this->mailHandlers[$mailer] = $temp;
589						$ret++;
590						if(varset($mailerExcludeDefault, FALSE) && isset($this->mailHandlers['core']))
591						{
592							$this->mailHandlers['core']->mailerEnabled = FALSE;
593							// Don't need default (core) handler
594							$ret--;
595						}
596					}
597					else
598					{
599						unset($temp);
600					}
601				}
602			}
603		}
604
605		return $ret;
606	}
607
608	/**
609	 * Generate the HTML for displaying email selection fields
610	 *
611	 * @param $options - comma-separated string of areas to display:
612	 *		plugins - selectors from any available plugins
613	 *		cc - field for 'cc' options
614	 *		bcc -  field for 'bcc' options
615	 *		src=plugname - selector from the specified plugin
616	 *		'all' - all available fields
617	 * @return text for display
618	 */
619	public function emailSelector($options = 'all', $selectorInfo = FALSE)
620	{
621		$tabs = array();
622
623		// Check for selected email address sources
624		if(!$this->mailHandlers)
625		{
626			$text = "<span class='label label-warning'>".LAN_MAILOUT_259."</span>";
627		}
628
629		foreach($this->mailHandlers as $key => $m)
630		{
631
632			if($m->mailerEnabled)
633			{
634
635				$content = $m->showSelect(TRUE, varset($selectorInfo[$key], FALSE));
636
637				if(is_array($content))
638				{
639					$text = "<table class='table table-bordered table-striped ' style='margin-bottom:0;margin-left:0; margin-top:10px'>
640					<colgroup span='2'>
641						<col class='col-label' />
642						<col class='col-control' />
643					</colgroup>
644					";
645
646					foreach($content as $var)
647					{
648						$text .= "
649						<tr>
650							<td>" . $var['caption'] . "</td>
651							<td class='form-inline'>" . $var['html'] . "</td>
652						</tr>";
653					}
654
655					$text .= "</table>";
656
657				}
658				else
659				{
660					$text = $content;  //BC (0.8 only) but should be deprecated
661				}
662
663				$tabs[$key] = array('caption'=>$m->mailerName, 'text'=>$text);
664
665			}
666		}
667
668		if(count($tabs) < 2) // no tabs if there's only 1 category.
669		{
670			return $text;
671		}
672
673
674		return e107::getForm()->tabs($tabs);
675	}
676
677
678
679	/**
680	 * Get the selector details from each mail plugin (to add to mail data)
681	 *
682	 * @return array of selectors - key is the plugin name, value is the selector
683	 * data (often itself an array)
684	 */
685	public function getAllSelectors()
686	{
687		$ret = array();
688		foreach($this->mailHandlers as $key => $m)
689		{
690			if($m->mailerEnabled)
691			{
692				$ret[$key] = $m->returnSelectors();
693			}
694		}
695		return $ret;
696	}
697
698	/**
699	 * Creates a 'select' dropdown of userclasses, including the number of members in
700	 * each class.
701	 *
702	 * @param string $name - name for <select>
703	 * @param string $curSel - current select value
704	 * @return text for display
705	 *
706	 *	@TODO: Doesn't give correct count for core classes where no data initialised
707	 */
708	public function userClassesTotals($name, $curSel)
709	{
710		$fixedClasses = array(
711			'self' => LAN_MAILOUT_54,
712			'all' => LAN_MAILOUT_12,
713			'unverified' => LAN_MAILOUT_13,
714			'admin' => LAN_MAILOUT_53
715		);
716
717		$ret = '';
718		$this->checkDB(2);
719		// Make sure DB object created
720		$ret .= "<select class='tbox' name='{$name}' >
721		<option value=''>&nbsp;</option>\n";
722
723		foreach($fixedClasses as $k => $v)
724		{
725			$sel = ($k == $curSel)? " selected='selected'": '';
726			$ret .= "<option value='{$k}'{$sel}>{$v}</option>\n";
727		}
728		$query = "SELECT uc.*, count(u.user_id) AS members
729				FROM #userclass_classes AS uc
730				LEFT JOIN #user AS u ON u.user_class REGEXP concat('(^|,)',uc.userclass_id,'(,|$)')
731				WHERE NOT uc.userclass_id IN (" . e_UC_PUBLIC . ',' . e_UC_NOBODY . ',' . e_UC_READONLY . ',' . e_UC_BOTS . ")
732				GROUP BY uc.userclass_id
733						";
734
735		$this->db2->gen($query);
736		while($row = $this->db2->fetch())
737		{
738			$public = ($row['userclass_editclass'] == e_UC_PUBLIC)? "(" . LAN_MAILOUT_10 . ")": "";
739			$selected = ($row['userclass_id'] == $curSel)? " selected='selected'": '';
740			$ret .= "<option value='{$row['userclass_id']}'{$selected} >" . LAN_MAILOUT_55 . " - {$row['userclass_name']}  {$public} [{$row['members']}]</option>\n";
741		}
742		$ret .= " </select>\n";
743
744		return $ret;
745	}
746
747	/**
748	 * Creates a 'select' dropdown of non-system user fields
749	 *
750	 * @param string $list_name - name for <select>
751	 * @param string $curval - current select value
752	 * @param boolean $add_blank - add a blank line before the options if TRUE
753	 * @return text for display if any extended fields defined; FALSE if none
754	 * available
755	 */
756	public function ret_extended_field_list($list_name, $curval = '', $add_blank = FALSE)
757	{
758		$ue = e107::getUserExt();
759		// Get the extended field handler
760		if(count($ue->fieldDefinitions) == 0)
761			return FALSE;
762		$ret = "<select name='{$list_name}' class='tbox'>\n";
763		if($add_blank)
764			$ret .= "<option value=''>&nbsp;</option>\n";
765
766		foreach($ue->fieldDefinitions as $fd)
767		{
768			if($fd['user_extended_struct_text'] != '_system_')
769			{
770				$value = 'ue.user_' . $fd['user_extended_struct_name'];
771				$selected = ($value == $curval)? " selected='selected'": '';
772				$ret .= "<option value='" . $value . "' {$selected}>" . ucfirst($fd['user_extended_struct_name']) . "</option>\n";
773			}
774		}
775		$ret .= "</select>\n";
776		return $ret;
777	}
778
779	/**
780	 * Creates an array of data from standard $_POST fields
781	 *
782	 * @param $newMail - set TRUE for initial creation, FALSE when updating
783	 * @return array of data
784	 */
785	public function parseEmailPost($newMail = TRUE)
786	{
787		$tp = e107::getParser();
788
789		$ret = array(
790			'mail_title' => $_POST['email_title'],
791			'mail_subject' => $_POST['email_subject'],
792			'mail_body' => $_POST['email_body'],
793			'mail_sender_email' => $_POST['email_from_email'],
794			'mail_sender_name' => $_POST['email_from_name'],
795			'mail_copy_to' => $_POST['email_cc'],
796			'mail_bcopy_to' => $_POST['email_bcc'],
797			'mail_attach' => trim($_POST['email_attachment']),
798			'mail_send_style' => varset($_POST['email_send_style'], 'textonly'),
799			'mail_include_images' => (isset($_POST['email_include_images'])? 1: 0)
800		);
801
802		$ret = $tp->toDB($ret);
803		// recursive
804
805		if(isset($_POST['mail_source_id']))
806		{
807			$ret['mail_source_id'] = intval($_POST['mail_source_id']);
808		}
809		if($newMail)
810		{
811			$ret['mail_creator'] = USERID;
812			$ret['mail_create_date'] = time();
813		}
814		return $ret;
815	}
816
817	/**
818	 * Does some basic checking on email data.
819	 *
820	 * @param $email - array of data in parseEmailPost() format
821	 * @param $fullCheck - TRUE to check all fields that are required (immediately
822	 * prior to sending); FALSE to just check a few basics (prior to save)
823	 * @return TRUE if OK. Array of error messages if any errors found
824	 */
825	public function checkEmailPost(&$email, $fullCheck = FALSE)
826	{
827		$errList = array();
828		if(count($email) < 3)
829		{
830			$errList[] = LAN_MAILOUT_201;
831			return $errList;
832		}
833		if(!trim($email['mail_subject']))
834			$errList[] = LAN_MAILOUT_200;
835		if(!trim($email['mail_body']))
836			$errList[] = LAN_MAILOUT_202;
837		if(!trim($email['mail_sender_name']))
838			$errList[] = LAN_MAILOUT_203;
839		if(!trim($email['mail_sender_email']))
840			$errList[] = LAN_MAILOUT_204;
841		if(strlen($email['mail_send_style']) == 0)
842		{
843			// Can be a template name now
844			$errList[] = LAN_MAILOUT_205;
845		//	break;
846		}
847		else
848		{
849			// Get template data, override email settings as appropriate
850			require_once (e_HANDLER . 'mail_template_class.php');
851			$ourTemplate = new e107MailTemplate();
852			$templateName = $email['mail_send_style'];
853			if(!$ourTemplate->setNewTemplate($templateName))
854			{
855				$errList[] = LAN_MAILOUT_207 . ':' . $templateName;
856				print_a($ourTemplate);
857				// Probably template not found if error
858			}
859			if(!$ourTemplate->makeEmailBody($email['mail_body'], $email['mail_include_images']))
860			{
861				$errList[] = LAN_MAILOUT_205 . ':' . $templateName;
862				print_a($ourTemplate);
863			}
864			else
865			{
866				$email['mail_body_templated'] = $ourTemplate->mainBodyText;
867				$email['mail_body_alt'] = $ourTemplate->altBodyText;
868				if(count($ourTemplate->lastTemplateData['email_overrides']))
869				{
870					$email['mail_overrides'] = $ourTemplate->lastTemplateData['email_overrides'];
871				}
872			}
873		}
874
875		if(count($errList) == 0)
876		{
877			return TRUE;
878		}
879		return $errList;
880	}
881
882	/**
883	 * Generate a table which shows some information about an email.
884	 * Intended to be part of a 2-column table - includes the row detail, but not the
885	 * surrounding table definitions
886	 *
887	 * @param $mailSource - array of mail information
888	 * @param $options - controls how much information is displayed
889	 * @return text for display
890	 */
891	public function showMailDetail(&$mailSource, $options = 'basic')
892	{
893		$tp = e107::getParser();
894
895		if(!isset($this->mailDetailDisplay[$options]))
896		{
897			return "<tr><td colspan='2'>Programming bungle - invalid option value: {$options}</td></tr>";
898		}
899
900		$text = '';
901		foreach($this->mailDetailDisplay[$options] as $k => $v)
902		{
903			$text .= '<tr><td>' . $this->fields['mail_content'][$k]['title'] . '</td><td>';
904			$val = $mailSource[$k];
905
906			if($k == 'mail_body')
907			{
908			//	$text .= print_a($mailSource,true);
909			//	$text .= $tp->toHTML($val,true);
910				$text .= "<iframe src='".e_ADMIN."mailout.php?mode=main&action=preview&id=".$mailSource['mail_source_id']."' width='100%' height='350'>Loading...</iframe>";
911				continue;
912			}
913
914			if(is_numeric($v))
915			{
916				$text .= ($v > 1)? $tp->text_truncate($val, $v, '...'): $val;
917			}
918			else
919			{
920				switch ($v)
921				{
922					case 'username':
923						$text .= $this->getUserName($val);
924					break;
925					case 'sdatetime':
926						$text .= $tp->toDate($val, 'short');
927					break;
928					case 'trunc200':
929
930						$text .= e107::getParser()->text_truncate($val, 200, '...');
931					break;
932					case 'chars':
933						// Show generated html as is
934						$text .= htmlspecialchars($val, ENT_COMPAT, 'UTF-8');
935					break;
936					case 'contentstatus':
937						$text .= $this->statusToText($val);
938					break;
939					case 'selectors':
940						$text .= 'cannot display';
941					break;
942					case 'yesno':
943						$text .= $val? LAN_YES: LAN_NO;
944					break;
945					case 'default':
946					default:
947						$text .= $val;
948				}
949			}
950			$text .= '</td></tr>' . "\n";
951		}
952		return $text;
953	}
954
955	/**
956	 * Generate the HTML for dropdown to select mail sending style (text/HTML/styled
957	 *
958	 * @param $curval - current value
959	 * @param $name name of item
960	 * @return text for display
961	 */
962	public function sendStyleSelect($curval = '', $name = 'email_send_style', $incTemplates = TRUE)
963	{
964
965		$emFormat = array(
966			'textonly' => LAN_MAILOUT_125,
967			'texthtml' => LAN_MAILOUT_126,
968			'texttheme' => LAN_MAILOUT_127
969		);
970
971		if($incTemplates)
972		{
973			$tList = self::getEmailTemplateNames('user');
974			foreach($tList as $key => $val)
975			{
976				$emFormat[$key] = LAN_TEMPLATE .": ". $val;
977			}
978		}
979
980		if(empty($curval))
981		{
982			$curval = e107::getConfig()->get('mail_sendstyle');
983
984		}
985
986
987		return e107::getForm()->select($name,$emFormat, $curval, 'required=1&size=xxlarge');
988
989	}
990
991	/**
992	 * Generate the HTML to show the mailout form. Used for both sending and editing
993	 *
994	 * @param $mailSource - array of mail information
995	 * @return text for display
996	 */
997	/*
998	 function show_mailform(&$mailSource)
999	 {
1000	 global $HANDLERS_DIRECTORY;
1001	 global $mailAdmin;
1002
1003	 $sql 	= e107::getDb();
1004	 $ns 	= e107::getRender();
1005	 $tp 	= e107::getParser();
1006	 $frm 	= e107::getForm();
1007	 $mes 	= e107::getMessage();
1008	 $pref 	= e107::getPref();
1009
1010	 if (!is_array($mailSource))
1011	 {
1012	 $mes->addError('Coding error - mail not array (521)');
1013	 //$ns->tablerender('ERROR!!', );
1014	 //exit;
1015	 }
1016
1017	 $email_subject = varset($mailSource['mail_subject'], '');
1018	 $email_body = $tp->toForm(varset($mailSource['mail_body'],''));
1019	 $email_id = varset($mailSource['mail_source_id'],'');
1020
1021	 $text = '';
1022
1023	 if(strpos($_SERVER['SERVER_SOFTWARE'],'mod_gzip') &&
1024	!is_readable(e_HANDLER.'phpmailer/.htaccess'))
1025	 {
1026	 $warning = LAN_MAILOUT_40.' '.$HANDLERS_DIRECTORY.'phpmailer/ '.LAN_MAILOUT_41;
1027	 $ns->tablerender(LAN_MAILOUT_42, $mes->render().$warning);
1028	 }
1029
1030	 $debug = (e_MENU == "debug") ? "?[debug]" : "";
1031
1032	 $text .= "<div>
1033	 <form method='post' action='".e_SELF."?mode=makemail' id='mailout_form'>";
1034
1035	 $text .= $this->emailSelector('all', varset($mailSource['mail_selectors'],
1036	FALSE));
1037
1038	 $text .= "<table class='table'>
1039	 <colgroup>
1040	 <col class='col-label' />
1041	 <col class='col-control' />
1042	 </colgroup>
1043	 <tr>
1044	 <td>".LAN_MAILOUT_111.": </td>
1045	 <td>".$frm->text('email_title',varset($mailSource['mail_title'],''))."</td>
1046	 </tr>
1047
1048	 <tr>
1049	 <td>".LAN_MAILOUT_01.": </td>
1050	 <td>".$frm->text('email_from_name',varset($mailSource['mail_from_name'],USERNAME))."</td>
1051	 </tr>
1052
1053	 <tr>
1054	 <td>".LAN_MAILOUT_02.": </td>
1055	 <td
1056	>".$frm->text('email_from_email',varset($mailSource['mail_from_email'],USEREMAIL))."</td>
1057	 </tr>";
1058
1059	 // Add in the core and any plugin selectors here
1060	 */
1061	/*$text .= "
1062
1063	 <tr>
1064	 <td>".LAN_MAILOUT_03.": </td>
1065	 <td>".$this->emailSelector('all', varset($mailSource['mail_selectors'],
1066	FALSE))."</td>
1067	 </tr>";*/
1068	/*
1069	 $text .= "
1070	 <tr>
1071	 <td>".LAN_MAILOUT_04.": </td>
1072	 <td>".$frm->text('email_cc',varset($mailSource['mail_cc'],''))."</td>
1073	 </tr>
1074
1075	 <tr>
1076	 <td>".LAN_MAILOUT_05.": </td>
1077	 <td>".$frm->text('email_bcc',varset($mailSource['mail_bcc'],''))."</td>
1078	 </tr>
1079
1080	 <tr>
1081	 <td>".LAN_MAILOUT_51.": </td>
1082	 <td>".$frm->text('email_subject',varset($email_subject,''),255,'required=1&size=xxlarge')."</td>
1083	 </tr>";
1084
1085	 // Attachment.
1086	 if (e107::isInstalled('download'))
1087	 {
1088	 // TODO - use download plugin API
1089
1090	 if($sql->select("download", "download_url,download_name", "download_id !=''
1091	ORDER BY download_name"))
1092	 {
1093	 $text .= "<tr>
1094	 <td>".LAN_MAILOUT_07.": </td>
1095	 <td >";
1096	 $text .= "<select class='tbox' name='email_attachment' >
1097	 <option value=''>&nbsp;</option>\n";
1098
1099	 while ($row = $sql->fetch())
1100	 {
1101	 $selected = ($mailSource['mail_attach'] == $row['download_url']) ?
1102	"selected='selected'" : '';
1103	 //				$text .= "<option value='".urlencode($row['download_url'])."'
1104	// {$selected}>".htmlspecialchars($row['download_name'])."</option>\n";
1105	 $text .= "<option value='".$row['download_url']."'
1106	{$selected}>".htmlspecialchars($row['download_name'])."</option>\n";
1107	 }
1108	 $text .= " </select>";
1109
1110	 $text .= "</td>
1111	 </tr>";
1112	 }
1113
1114	 }
1115	 // TODO File-Picker from Media-Manager.
1116
1117	 $text .= "
1118	 <tr>
1119	 <td>".LAN_MAILOUT_09.": </td>
1120	 <td >\n";
1121
1122	 global $eplug_bb;
1123
1124	 $eplug_bb[] = array(
1125	 'name'		=> 'shortcode',
1126	 'onclick'	=> 'expandit',
1127	 'onclick_var' => 'sc_selector',
1128	 'icon'		=> e_IMAGE.'generic/bbcode/shortcode.png',
1129	 'helptext'	=> LAN_MAILOUT_11,
1130	 'function'	=> array($this,'sc_Select'),
1131	 'function_var'	=> 'sc_selector'
1132	 );
1133
1134	 $text .= $this->sendStyleSelect(varset($mailSource['mail_send_style'], ''));
1135	 $checked = (isset($mailSource['mail_include_images']) &&
1136	$mailSource['mail_include_images']) ? " checked='checked'" : '';
1137	 $text .= "&nbsp;&nbsp;<input type='checkbox' name='email_include_images'
1138	value='1' {$checked} />".LAN_MAILOUT_225;
1139	 $text .="
1140	 </td></tr>\n
1141	 <tr>
1142
1143	 <td
1144	colspan='2'>".$frm->bbarea('email_body',$email_body,'mailout','helpb')."</td>
1145	 </tr>";
1146
1147	 $text .="
1148	 <tr>
1149	 <td colspan='2'>
1150	 <div>";
1151
1152	 //	$text .= display_help('helpb','mailout');
1153
1154	 $text .="
1155	 </div></td>
1156	 </tr>
1157	 </table> ";
1158
1159	 $text .= "<div class='buttons-bar center'>";
1160
1161	 if($email_id)
1162	 {
1163	 $text .= $frm->hidden('mail_source_id',$email_id);
1164	 $text .= $frm->admin_button('update_email',LAN_UPDATE);
1165	 //$text .= "<input type='hidden' name='mail_source_id' value='".$email_id."'
1166	// />";
1167	 //$text .= "<input  type='submit' name='update_email' value=\"".LAN_UPDATE."\"
1168	// />";
1169	 }
1170	 else
1171	 {
1172	 $text .= $frm->admin_button('save_email',LAN_SAVE,'other');
1173	 }
1174
1175	 $text .= $frm->admin_button('send_email',LAN_MAILOUT_08); //
1176
1177	 $text .= "</div>
1178
1179	 </form>
1180	 </div>";
1181
1182	 return $text;
1183
1184	 // $ns->tablerender(ADLAN_136.SEP.LAN_MAILOUT_15, $mes->render(). $text);		//
1185	// Render the complete form
1186	 }
1187	 */
1188
1189	/**
1190	 *		Helper function manages the shortcodes which can be inserted
1191	 */
1192	function sc_Select($container = 'sc_selector')
1193	{
1194		$text = "
1195		<!-- Start of Shortcode selector -->\n
1196			<div style='margin-left:0px;margin-right:0px; position:relative;z-index:1000;float:right;display:none' id='{$container}'>
1197			<div style='position:absolute; bottom:30px; right:125px'>
1198			<table class='fborder' style='background-color: #fff'>
1199			<tr><td>
1200			<select class='tbox' name='sc_sel' onchange=\"addtext(this.value); this.selectedIndex= 0; expandit('{$container}')\">
1201			<option value=''> -- </option>\n";
1202
1203		$sc = array(
1204			'|DISPLAYNAME|' => LAN_MAILOUT_14,
1205			'|USERNAME|' => LAN_MAILOUT_16,
1206			'|SIGNUP_LINK|' => LAN_MAILOUT_17,
1207			'|USERID|' => LAN_MAILOUT_18,
1208			'|USERLASTVISIT|' => LAN_MAILOUT_178
1209		);
1210
1211		foreach($sc as $key => $val)
1212		{
1213			$text .= "<option value='" . $key . "'>" . $val . "</option>\n";
1214		}
1215		$text .= "
1216			</select></td></tr>	\n </table></div>
1217			</div>
1218		\n<!-- End of SC selector -->
1219		";
1220
1221		return $text;
1222	}
1223
1224	/**
1225	 * Return dropdown for arithmetic comparisons
1226	 *
1227	 * @param $name  string name of select structure
1228	 * @param $curval string current value
1229	 * @return text for display
1230	 */
1231	public function comparisonSelect($name, $curval = '')
1232	{
1233		$compVals = array(
1234			' ' => ' ',
1235			'<' => LAN_MAILOUT_175,
1236			'=' => LAN_MAILOUT_176,
1237			'>' => LAN_MAILOUT_177
1238		);
1239		$ret = "<select name='{$name}' class='tbox'>\n";
1240		foreach($compVals as $k => $v)
1241		{
1242			$selected = ($k == $curval)? " selected='selected'": '';
1243			$ret .= "<option value='" . $k . "' {$selected}>" . $v . "</option>\n";
1244		}
1245		$ret .= "</select>\n";
1246		return $ret;
1247	}
1248
1249	/**
1250	 *	Show the generated template of a saved email
1251	 */
1252	public function showEmailTemplate($mailId)
1253	{
1254		$mes = e107::getMessage();
1255		$ns = e107::getRender();
1256		$frm = e107::getForm();
1257
1258
1259		$mailData = $this->retrieveEmail($mailId);
1260
1261		if($mailData === FALSE)
1262		{
1263			$mes->addInfo(LAN_MAILOUT_79);
1264			$ns->tablerender(ADLAN_136 . SEP . LAN_MAILOUT_171, $mes->render() . $text);
1265			exit ;
1266		}
1267
1268		$text = "
1269			<form action='" . e_SELF . "?mode=saved' id='email_show_template' method='post'>
1270			<fieldset id='email-show-template'>
1271			<table class='table adminlist'>
1272			<colgroup>
1273				<col class='col-label' />
1274				<col class='col-control' />
1275			</colgroup>
1276			<tbody>";
1277
1278		$text .= $this->showMailDetail($mailData, 'template');
1279		$text .= '<tr><td>' . LAN_MAILOUT_172 . '</td><td>' . $this->statusToText($mailData['mail_content_status']) . "<input type='hidden' name='mailIDConf' value='{$mailID}' /></td></tr>";
1280
1281		$text .= "</tbody></table>\n</fieldset>";
1282
1283		$text .= "<div class='buttons-bar center'>
1284					" . $frm->admin_button('email_delete', LAN_MAILOUT_256, 'other') . "
1285				</div>";
1286
1287		$text .= "</form>";
1288		$ns->tablerender(ADLAN_136 . SEP . LAN_MAILOUT_255 . $mailId, $text);
1289	}
1290
1291	/**
1292	 * Show a screen to confirm deletion of an email
1293	 *
1294	 * @param $mailid - number of email
1295	 * @param $nextPage - 'mode' specification for page to return to following delete
1296	 * @return text for display
1297	 */
1298	/*
1299	 public function showDeleteConfirm($mailID, $nextPage = 'saved')
1300	 {
1301	 $mailData = $this->retrieveEmail($mailID);
1302	 $frm = e107::getForm();
1303	 $ns = e107::getRender();
1304	 $mes = e107::getMessage();
1305
1306	 if ($mailData === FALSE)
1307	 {
1308	 $mes->addInfo(LAN_MAILOUT_79);
1309	 $ns-> tablerender(ADLAN_136.SEP.LAN_MAILOUT_171, $mes->render().$text);
1310	 exit;
1311	 }
1312
1313	 $text .= "
1314	 <form
1315	action='".e_SELF.'?mode=maildeleteconfirm&amp;m='.$mailID.'&amp;savepage='.$nextPage."'
1316	id='email_delete' method='post'>
1317	 <fieldset id='email-delete'>
1318	 <table class='table adminlist'>
1319	 <colgroup>
1320	 <col class='col-label' />
1321	 <col class='col-control' />
1322	 </colgroup>
1323
1324	 <tbody>";
1325
1326	 $text .= $this->showMailDetail($mailData, 'basic');
1327	 $text .=
1328	'<tr><td>'.LAN_MAILOUT_172.'</td><td>'.$this->statusToText($mailData['mail_content_status'])."<input
1329	type='hidden' name='mailIDConf' value='{$mailID}' /></td></tr>";
1330	 if ($mailData['mail_content_status'] != MAIL_STATUS_SAVED)
1331	 {
1332	 $text .= '<tr><td>'.LAN_MAILOUT_173.'</td><td>'.($mailData['mail_togo_count'] +
1333	$mailData['mail_sent_count'] + $mailData['mail_fail_count']).'</td></tr>';
1334	 }
1335
1336	 $text .= "</tbody></table>\n</fieldset>";
1337
1338	 $text .= "<div class='buttons-bar center'>
1339	 ".$frm->admin_button('email_delete', LAN_DELETE, 'delete')."
1340	 ".$frm->admin_button('email_cancel', LAN_CANCEL, 'cancel')."
1341	 </div>
1342	 </form>";
1343
1344	 $ns->tablerender(ADLAN_136.SEP.LAN_MAILOUT_171, $text);
1345	 }
1346	 */
1347
1348	/**
1349	 * Generate the HTML to show a list of emails of a particular type, in tabular
1350	 * form
1351	 *
1352	 * @param $type - type of email to display (saved|sent|pending|held)
1353	 * @param $from - offset into table of candidates
1354	 * @param $amount - number to return
1355	 * @return text for display
1356	 */
1357	/*
1358	 public function showEmailList($type, $from = 0, $amount = 10)
1359	 {
1360	 // Need to select main email entries; count number of addresses attached to each
1361	 $gen = new convert;
1362	 $frm = e107::getForm();
1363	 $ns = e107::getRender();
1364	 $mes = e107::getMessage();
1365	 $tp = e107::getParser();
1366
1367	 switch ($type)
1368	 {
1369	 case 'sent' :
1370	 $searchType = 'allcomplete';
1371	 break;
1372	 default :
1373	 $searchType = $type;
1374	 }
1375
1376	 if ($from < 0) { $from = $this->showFrom; }
1377	 if ($amount < 0) { $amount = $this->showCount; }
1378	 // in $_GET, so = sort order, sf = sort field
1379	 $count = $this->selectEmailStatus($from, $amount, '*', $searchType,
1380	$this->sortField, $this->sortOrder);
1381	 $totalCount = $this->getEmailCount();
1382
1383	 $emails_found = array();			// Log ID and count for later
1384
1385	 if (!$count)
1386	 {
1387	 $mes->addInfo(LAN_MAILOUT_79);
1388	 $ns->tablerender($this->tasks[$type]['title'], $mes->render() . $text);
1389	 return;
1390	 }
1391
1392	 $text = "
1393	 <form action='".e_SELF.'?'.e_QUERY."' id='email_list' method='post'>
1394	 <fieldset id='emails-list'>
1395	 <table class='table adminlist'>";
1396
1397	 $fieldPrefs = $this->calcFieldSpec($type, TRUE);			// Get columns to display
1398
1399	 // Must use '&' rather than '&amp;' in query pattern
1400	 $text .=
1401	$frm->colGroup($this->fields['mail_content'],$this->fieldPref).$frm->thead($this->fields['mail_content'],$this->fieldPref,'mode='.$type."&fld=[FIELD]&asc=[ASC]&frm=[FROM]")."<tbody>";
1402
1403	 while ($row = $this->getNextEmailStatus(FALSE))
1404	 {
1405	 //print_a($row);
1406	 $text .= '<tr>';
1407	 foreach ($fieldPrefs as $fieldName)
1408	 {	// Output column data value
1409	 $text .= '<td>';
1410	 if (isset($row[$fieldName]))
1411	 {
1412	 $proctype = varset($this->fields['mail_content'][$fieldName]['proc'],
1413	'default');
1414	 switch ($proctype)
1415	 {
1416	 case 'username' :
1417	 $text .= $this->getUserName($row[$fieldName]);
1418	 break;
1419	 case 'sdatetime' :
1420	 $text .= $gen->convert_date($row[$fieldName], 'short');
1421	 break;
1422	 case 'trunc200' :
1423	 $text .= $tp->text_truncate($row[$fieldName], 200, '...');
1424	 break;
1425	 case 'chars' :			// Show generated html as is
1426	 $text .= htmlspecialchars($row[$fieldName], ENT_COMPAT, 'UTF-8');
1427	 break;
1428	 case 'contentstatus' :
1429	 $text .= $this->statusToText($row[$fieldName]);
1430	 break;
1431	 case 'selectors' :
1432	 $text .= 'cannot display';
1433	 break;
1434	 case 'yesno' :
1435	 $text .= $row[$fieldName] ? LAN_YES : LAN_NO;
1436	 break;
1437	 case 'default' :
1438	 default :
1439	 $text .= $row[$fieldName];
1440	 }
1441	 }
1442	 else
1443	 {	// Special stuff
1444	 }
1445	 $text .= '</td>';
1446	 }
1447	 // Add in options here
1448	 $text .= '<td>'.$this->makeMailOptions($type,$row).'</td>';
1449	 $text .= '</tr>';
1450	 }
1451	 $text .= "</tbody></table><br /><br />\n";
1452
1453	 if ($totalCount > $count)
1454	 {
1455	 $parms =
1456	"{$totalCount},{$amount},{$from},".e_SELF."?mode={$type}&amp;count={$amount}&amp;frm=[FROM]&amp;fld={$this->sortField}&amp;asc={$this->sortOrder}";
1457	 $text .= $tp->parseTemplate("{NEXTPREV={$parms}}");
1458	 }
1459
1460	 $text .= '</fieldset></form>';
1461	 $ns->tablerender(ADLAN_136.SEP.$this->tasks[$type]['title'], $text);
1462	 }
1463	 */
1464
1465	/**
1466	 * Generate a list of emails to send
1467	 * Returns various information to display in a confirmation screen
1468	 *
1469	 * The email and its recipients are stored in the DB with a tag of
1470	 * 'MAIL_STATUS_TEMP' if its a new email (no change if already on hold)
1471	 *
1472	 * @param array $mailData - Details of the email, selection criteria etc
1473	 * @param boolean $fromHold - FALSE if this is a 'new' email to send, TRUE if its
1474	 * already been put on hold (selects processing path)
1475	 * @return text for display
1476	 */
1477	public function sendEmailCircular($mailData, $fromHold = FALSE)
1478	{
1479		$sql = e107::getDb();
1480		$mes = e107::getMessage();
1481		$frm = e107::getForm();
1482
1483		if($fromHold)
1484		{
1485			// Email data already generated
1486			$mailMainID = $mailData['mail_source_id'];
1487			if($mailMainID == 0)
1488				return FALSE;
1489			if(FALSE === ($mailData = $this->retrieveEmail($mailMainID)))// Get the new data
1490			{
1491				return FALSE;
1492			}
1493			$counters['add'] = $mailData['mail_togo_count'];
1494			// Set up the counters
1495			$counters['dups'] = 0;
1496		}
1497		else
1498		{
1499			// Start by saving the email
1500			/*
1501			$mailData['mail_content_status'] = MAIL_STATUS_TEMP;
1502			$mailData['mail_create_app'] = 'core';
1503			$result = $this->saveEmail($mailData, TRUE);
1504		//	$result = $this->saveEmail($mailData, false); // false = update, not insert.
1505			if(is_numeric($result))
1506			{
1507				$mailMainID = $mailData['mail_source_id'] = $result;
1508			}
1509			else
1510			{
1511				e107::getMessage()->addDebug("Couldn't save email. (".__FILE__." Line: ".__LINE__.")");
1512			}
1513			*/
1514
1515			$mailMainID = $mailData['mail_source_id'];
1516
1517			$this->mailInitCounters($mailMainID); // Initialise counters for emails added
1518
1519			foreach($this->mailHandlers as $key => $m)
1520			{
1521				// Get email addresses from each handler in turn. Do them one at a time, so that
1522				// all can use the $sql data object
1523				if($m->mailerEnabled && isset($mailData['mail_selectors'][$key]))
1524				{
1525
1526					$mailerCount = $m->selectInit($mailData['mail_selectors'][$key]); // Initialise
1527
1528					if(!empty($mailerCount))
1529					{
1530
1531						while($row = $m->selectAdd()) // Get email addresses - add to list, strip duplicates
1532						{
1533							$result = $this->mailAddNoDup($mailMainID, $row, MAIL_STATUS_TEMP); // Add email addresses to the database ready for sending (the body is never saved // in the DB - it gets passed as a $_POST value)
1534
1535							if($result === FALSE)
1536							{
1537								// Error
1538								e107::getMessage()->addDebug("Couldn't add receipients (".__FILE__."  Line: ".__LINE__.")");
1539							}
1540						}
1541					}
1542					else
1543					{
1544						e107::getMessage()->addWarning($key.": no matching recipients");
1545					}
1546
1547
1548
1549					$m->select_close();
1550					// Close
1551					// Update the stats after each handler
1552					$this->mailUpdateCounters($mailMainID);
1553				}
1554			}
1555
1556			$counters = $this->mailRetrieveCounters($mailMainID);
1557			//	$this->e107->admin_log->log_event('MAIL_02','ID: '.$mailMainID.'
1558			// '.$counters['add'].'[!br!]'.$_POST['email_from_name']."
1559			// &lt;".$_POST['email_from_email'],E_LOG_INFORMATIVE,'');
1560		}
1561
1562		// We've got all the email addresses here - display a confirmation form
1563		// Include start/end dates for send
1564		//	$text = "<form action='".e_SELF.'?mode=marksend&amp;m='.$mailMainID."'
1565		// id='email_send' method='post'>";
1566
1567		$text = "
1568			<form action='" . e_SELF . "' id='email_send' method='post'>
1569			<fieldset id='email-send'>
1570			<table class='table adminlist'>
1571			<colgroup>
1572				<col class='col-label' />
1573				<col class='col-control' />
1574			</colgroup>
1575			<tbody>";
1576
1577		$text .= $this->showMailDetail($mailData, 'send');
1578
1579		$text .= '<tr><td>' . LAN_MAILOUT_03 . '</td><td>'; // TO
1580
1581		// Add in core and any plugin selectors here
1582		foreach($this->mailHandlers as $key => $m)
1583		{
1584
1585			if($m->mailerEnabled && ($contentArray = $m->showSelect(FALSE, $mailData['mail_selectors'][$key])))
1586			{
1587
1588				$text .= $m->mailerName.':<ul>';
1589				foreach($contentArray as $val)
1590				{
1591					$text .= "<li>" . $val['caption'] . " : " . $val['html'] . "</li>";
1592				}
1593				$text .= '</ul>';
1594			}
1595		}
1596
1597		$text .= '</td></tr>';
1598
1599		// Figures - number of emails to send, number of duplicates stripped
1600
1601		$totalRecipients = !empty($mailData['mail_togo_count']) ? $mailData['mail_togo_count'] : $counters['add'];
1602
1603		$text .= '<tr><td>' . LAN_MAILOUT_173 . '</td><td>' . $totalRecipients . "<input type='hidden' name='mailIDConf' value='{$mailMainID}' /></td></tr>";
1604		$text .= '<tr><td>' . LAN_MAILOUT_71 . '</td><td> ' . $counters['add'] . ' ' . LAN_MAILOUT_69 . $counters['dups'] . LAN_MAILOUT_70 . '</td></tr>';
1605		$text .= "</tbody></table>\n</fieldset>";
1606
1607		$this->updateCounter($mailMainID,'total',$counters['add']);
1608
1609		$text .= $this->makeAdvancedOptions(TRUE);
1610		// Show the table of advanced options
1611
1612		$text .= "<div class='buttons-bar center'>";
1613		$text .= "<a href='".e_SELF."?mode=main&action=sendnow&id=".$mailMainID."' class='btn btn-primary'>".LAN_MAILOUT_158."</a>";
1614
1615	//	$text .= $frm->admin_button('email_sendnow', "Send Now", 'primary');
1616		$text .= $frm->admin_button('email_send', LAN_MAILOUT_269);
1617
1618		// $text .= "<input  type='submit' name='email_send' value=\"".LAN_SEND."\" />";
1619
1620		if(!$fromHold)
1621		{
1622			$text .= $frm->admin_button('email_hold', LAN_HOLD, 'warning');
1623			$text .= $frm->admin_button('email_cancel', LAN_CANCEL, 'delete');
1624			// $text .= "&nbsp;<input  type='submit' name='email_hold' value=\"".LAN_HOLD."\"
1625			// />";
1626			// $text .= "&nbsp;<input  type='submit' name='email_cancel'
1627			// value=\"".LAN_CANCEL."\" />";
1628		}
1629
1630		$text .= $frm->hidden('email_id', $mailMainID);
1631
1632		$text .= "</div>
1633		</form>
1634		</div>";
1635
1636		return $text;
1637		//	e107::getRender()->tablerender(ADLAN_136.SEP.LAN_MAILOUT_179, $mes->render().
1638		// $text);
1639	}// End of previewed email
1640
1641	/**
1642	 *
1643	 */
1644	protected function makeAdvancedOptions($initHide = FALSE)
1645	{
1646		// Separate table for advanced mailout options
1647		// mail_notify_complete field
1648		$text = "
1649			<legend>" . LAN_MAILOUT_242 . "</legend>
1650			<fieldset id='email-send-options'>
1651			<table class='table adminlist'>
1652			<colgroup>
1653				<col class='col-label' />
1654				<col class='col-control' />
1655			</colgroup>
1656			<tbody>";
1657
1658		$text .= "<tr><td>" . LAN_MAILOUT_238 . "</td><td>" . $this->makeCalendar('mail_earliest_time', '', CORE_DATE_ORDER) . "</td></tr>";
1659		$text .= "<tr><td>" . LAN_MAILOUT_239 . "</td><td>" . $this->makeCalendar('mail_latest_time', '', CORE_DATE_ORDER) . "</td></tr>";
1660		// Can comment the two lines above, uncomment two lines below, and default
1661		// time/date is shown. May or may not be preferable
1662		//		$text .=
1663		// "<tr><td>".LAN_MAILOUT_238."</td><td>".$this->makeCalendar('mail_earliest_time',
1664		// time(), CORE_DATE_ORDER)."</td></tr>";
1665		//		$text .=
1666		// "<tr><td>".LAN_MAILOUT_239."</td><td>".$this->makeCalendar('mail_latest_time',
1667		// time()+86400, CORE_DATE_ORDER)."</td></tr>";
1668		$text .= "<tr><td>" . LAN_MAILOUT_240 . "</td><td><input type='checkbox' value='1' name='mail_notify_complete' />" . LAN_MAILOUT_241 . "</td></tr>";
1669		$text .= "</tbody></table>\n</fieldset>";
1670		return $text;
1671	}
1672
1673	/**
1674	 *
1675	 */
1676	public function makeCalendar($calName, $calVal = '', $dateOrder = 'dmy')
1677	{
1678		// Determine formatting strings this way, to give sensible default
1679		switch ($dateOrder)
1680		{
1681			case 'mdy':
1682				$dFormat = '%m/%d/%y';
1683				$tFormat = '%H:%M';
1684			break;
1685			case 'ymd':
1686				$dFormat = '%Y/%m/%d';
1687				$tFormat = ' %H:%M';
1688			break;
1689			case 'dmy':
1690			default:
1691				$dFormat = '%d/%m/%Y';
1692				$tFormat = ' %H:%M';
1693		}
1694
1695		$options = array(
1696			'type' => 'datetime',
1697			'format' => $dFormat . " " . $tFormat,
1698			//	'timeformat' => $tFormat,
1699			'firstDay' => 1, // 0 = Sunday.
1700			'size' => 12
1701		);
1702		//		$options['dateFormat'] 	= $dformat;
1703		//		$options['timeFormat'] 	= $tformat;
1704
1705		return e107::getForm()->datepicker($calName, $calVal, $options);
1706	}
1707
1708
1709	/**
1710	 * Show recipients of an email
1711	 *
1712	 * @param $mailid - number of email
1713	 * @param $nextPage - 'mode' specification for page to return to following delete
1714	 * @return text for display
1715	 */
1716	/*
1717	public function showmailRecipients($mailID, $nextPage = 'saved')
1718	{
1719		$gen = new convert;
1720		$frm = e107::getForm();
1721		$mes = e107::getMessage();
1722		$tp = e107::getParser();
1723		$ns = e107::getRender();
1724
1725		$mailData = $this->retrieveEmail($mailID);
1726
1727		if($mailData === FALSE)
1728		{
1729			$mes->addInfo(LAN_MAILOUT_79);
1730			$ns->tablerender(ADLAN_136 . SEP . LAN_MAILOUT_171, $mes->render() . $text);
1731			exit ;
1732		}
1733
1734		$text .= "
1735			<form action='" . e_SELF . '?' . e_QUERY . "' id='email_recip_header' method='post'>
1736			<fieldset id='email-recip_header'>
1737			<table class='table adminlist'>
1738			<colgroup>
1739				<col class='col-label' />
1740				<col class='col-control' />
1741			</colgroup>
1742
1743			<tbody>";
1744
1745		$text .= $this->showMailDetail($mailData, 'basic');
1746		$text .= '<tr><td>' . LAN_MAILOUT_172 . '</td><td>' . $this->statusToText($mailData['mail_content_status']) . "<input type='hidden' name='mailIDConf' value='{$mailID}' /></td></tr>";
1747		if($mailData['mail_content_status'] != MAIL_STATUS_SAVED)
1748		{
1749			$text .= '<tr><td>' . LAN_MAILOUT_173 . '</td><td>' . ($mailData['mail_togo_count'] + $mailData['mail_sent_count'] + $mailData['mail_fail_count']) . '</td></tr>';
1750		}
1751
1752		$text .= "</tbody></table>\n</fieldset></form>";
1753
1754		// List of recipients
1755		// in $_GET, asc = sort order, fld = sort field
1756		$count = $this->selectTargetStatus($mailID, $this->showFrom, $this->showCount, '*', FALSE, $this->sortField, $this->sortOrder);
1757		$totalCount = $this->getTargetCount();
1758
1759		if($count == 0)
1760		{
1761			$text .= "<span class='required'>" . LAN_MAILOUT_253 . '</span>';
1762		}
1763		else
1764		{
1765			$text .= "
1766				<form action='" . e_SELF . "?mode=recipients&amp;m={$mailID}&amp;count={$count}&amp;frm={$this->showFrom}&amp;fld={$this->sortField}&amp;asc={$this->sortOrder}&amp;savepage={$nextPage}' id='email_recip_body' method='post'>
1767				<fieldset id='email-recip_body'>
1768				<table class='table adminlist'>";
1769
1770			$fieldPrefs = $this->calcFieldSpec('recipients', TRUE);
1771			// Get columns to display
1772
1773			// Must use '&' rather than '&amp;' in query pattern
1774			$text .= $frm->colGroup($this->fields['mail_recipients'], $this->fieldPref) . $frm->thead($this->fields['mail_recipients'], $this->fieldPref, 'mode=' . 'recipients&amp;m=' . $mailID . "&fld=[FIELD]&asc=[ASC]&frm=[FROM]") . "<tbody>";
1775
1776			while($row = $this->getNextTargetStatus(FALSE))
1777			{
1778				//	print_a($row);
1779				$text .= '<tr>';
1780				foreach($fieldPrefs as $fieldName)
1781				{
1782					// Output column data value
1783					$text .= '<td>';
1784					if(isset($row[$fieldName]))
1785					{
1786						$proctype = varset($this->fields['mail_recipients'][$fieldName]['proc'], 'default');
1787						switch ($proctype)
1788						{
1789							case 'username':
1790								$text .= $this->getUserName($row[$fieldName]);
1791							break;
1792							case 'sdatetime':
1793								$text .= $gen->convert_date($row[$fieldName], 'short');
1794							break;
1795							case 'trunc200':
1796								$text .= $tp->text_truncate($row[$fieldName], 200, '...');
1797							break;
1798							case 'chars':
1799								// Show generated html as is
1800								$text .= htmlspecialchars($row[$fieldName], ENT_COMPAT, 'UTF-8');
1801							break;
1802							case 'contentstatus':
1803								$text .= $this->statusToText($row[$fieldName]);
1804							break;
1805							case 'selectors':
1806								$text .= 'cannot display';
1807							break;
1808							case 'array':
1809								if(is_array($row[$fieldName]))
1810								{
1811									$nl = '';
1812									foreach($row[$fieldName] as $k => $v)
1813									{
1814										if($v)
1815										{
1816											$text .= $nl . $k . ' => ' . $v;
1817											$nl = '<br />';
1818										}
1819									}
1820								}
1821								else
1822								{
1823									$text .= 'bad data: ';
1824								}
1825							break;
1826							case 'default':
1827							default:
1828								$text .= $row[$fieldName];
1829						}
1830					}
1831					else
1832					{
1833						// Special stuff
1834						$text .= 'special';
1835					}
1836					$text .= '</td>';
1837				}
1838				// Add in options here
1839				$text .= '<td>' . $this->makeTargetOptions('recipients', $row) . '</td>';
1840				$text .= '</tr>';
1841			}
1842
1843			$text .= "</tbody></table>\n</fieldset></form><br /><br />";
1844
1845			if($totalCount > $count)
1846			{
1847				$parms = "{$totalCount},{$this->showCount},{$this->showFrom}," . e_SELF . "?mode=recipients&amp;m={$mailID}&amp;count={$this->showCount}&amp;frm=[FROM]&amp;fld={$this->sortField}&amp;asc={$this->sortOrder}&amp;savepage={$nextPage}";
1848				$text .= $tp->parseTemplate("{NEXTPREV={$parms}}");
1849			}
1850		}
1851
1852		$ns->tablerender(ADLAN_136 . SEP . LAN_MAILOUT_181, $mes->render() . $text);
1853	}
1854	*/
1855
1856
1857	/**
1858	 * Clean up mailout DB
1859	 * Dump array of results to admin log
1860	 *
1861	 * @return boolean TRUE if no errors, FALSE if errors
1862	 */
1863	public function dbTidy()
1864	{
1865		$noError = TRUE;
1866		$results = array();
1867		$this->checkDB(2);
1868		// Make sure DB object created
1869
1870		// First thing, delete temporary records from both tables
1871		if(($res = $this->db2->db_Delete('mail_content', '`mail_content_status` = ' . MAIL_STATUS_TEMP)) === FALSE)
1872		{
1873			$results[] = 'Error ' . $this->db2->getLastErrorNumber() . ':' . $this->db2->getLastErrorText() . ' deleting temporary records from mail_content';
1874			$noError = FALSE;
1875		}
1876		else
1877		{
1878			if($res)
1879				$results[] = str_replace(array(
1880					'[x]',
1881					'[y]'
1882				), array(
1883					$res,
1884					'mail_content'
1885				), LAN_MAILOUT_227);
1886		}
1887		if(($res = $this->db2->delete('mail_recipients', '`mail_status` = ' . MAIL_STATUS_TEMP)) === FALSE)
1888		{
1889			$results[] = 'Error ' . $this->db2->getLastErrorNumber() . ':' . $this->db2->getLastErrorText() . ' deleting temporary records from mail_recipients';
1890			$noError = FALSE;
1891		}
1892		else
1893		{
1894			if($res)
1895				$results[] = str_replace(array(
1896					'[x]',
1897					'[y]'
1898				), array(
1899					$res,
1900					'mail_recipients'
1901				), LAN_MAILOUT_227);
1902		}
1903
1904		// Now look for 'orphaned' recipient records
1905		if(($res = $this->db2->gen("DELETE `#mail_recipients` FROM `#mail_recipients`
1906					LEFT JOIN `#mail_content` ON `#mail_recipients`.`mail_detail_id` = `#mail_content`.`mail_source_id`
1907					WHERE `#mail_content`.`mail_source_id` IS NULL")) === FALSE)
1908		{
1909			$results[] = 'Error ' . $this->db2->getLastErrorNumber() . ':' . $this->db2->getLastErrorText() . ' deleting orphaned records from mail_recipients';
1910			$noError = FALSE;
1911		}
1912		elseif($res)
1913		{
1914			if($res)
1915				$results[] = str_replace('[x]', $res, LAN_MAILOUT_226);
1916		}
1917
1918		// Scan content table for anomalies, out of time records
1919		if(($res = $this->db2->gen("SELECT * FROM `#mail_content`
1920					WHERE (`mail_content_status` >" . MAIL_STATUS_FAILED . ") AND (`mail_content_status` <=" . MAIL_STATUS_MAX_ACTIVE . ")
1921					AND ((`mail_togo_count`=0) OR ( (`mail_last_date` != 0) AND (`mail_last_date` < " . time() . ")))")) === FALSE)
1922		{
1923			$results[] = 'Error ' . $this->db2->getLastErrorNumber() . ':' . $this->db2->getLastErrorText() . ' checking bad status in mail_content';
1924			$noError = FALSE;
1925		}
1926		else
1927		{
1928			$items = array();
1929			// Store record number of any content record that needs to be changed
1930			while($row = $this->db2->fetch())
1931			{
1932				$items[] = $row['mail_source_id'];
1933				if($row['mail_source_id'])
1934				{
1935					if(FALSE == $this->cancelEmail($row['mail_source_id']))
1936					{
1937						$results[] = 'Error cancelling email ref: ' . $row['mail_source_id'];
1938					}
1939					else
1940					{
1941						$results[] = 'Email cancelled: ' . $row['mail_source_id'];
1942					}
1943				}
1944			}
1945			if(count($items))
1946				$results[] = str_replace(array(
1947					'[x]',
1948					'[y]'
1949				), array(
1950					count($items),
1951					implode(', ', $items)
1952				), LAN_MAILOUT_228);
1953		}
1954
1955		//Finally - check for inconsistent recipient and content status records -
1956		// basically verify counts
1957		if(($res = $this->db2->gen("SELECT COUNT(mr.`mail_status`) AS mr_count, mr.`mail_status`,
1958					mc.`mail_source_id`, mc.`mail_togo_count`, mc.`mail_sent_count`, mc.`mail_fail_count`, mc.`mail_bounce_count`, mc.`mail_source_id` FROM `#mail_recipients` AS mr
1959					LEFT JOIN `#mail_content` AS mc ON mr.`mail_detail_id` = mc.`mail_source_id`
1960					WHERE mc.`mail_content_status` <= " . MAIL_STATUS_MAX_ACTIVE . "
1961					GROUP BY mr.`mail_status`, mc.`mail_source_id` ORDER BY mc.`mail_source_id`
1962					")) === FALSE)
1963		{
1964			$results[] = 'Error ' . $this->db2->getLastErrorNumber() . ':' . $this->db2->getLastErrorText() . ' assembling email counts';
1965			$noError = FALSE;
1966		}
1967		else
1968		{
1969			$lastMail = 0;
1970			// May get several rows per mail
1971			$notLast = TRUE;
1972			// This forces one more loop, so we can clean up for last record read
1973			$changeCount = 0;
1974			$saveRow = array();
1975			while(($row = $this->db2->fetch()) || $notLast)
1976			{
1977				if(($lastMail > 0 && $row === FALSE) || ($lastMail != $row['mail_source_id']))
1978				{
1979					// Change of mail ID here - handle any accumulated info
1980					if($lastMail > 0)
1981					{
1982						// Need to verify counts for mail just read
1983						$changes = array();
1984						foreach($counters as $k => $v)
1985						{
1986							if($saveRow[$k] != $v)
1987							{
1988								$changes[$k] = $v;
1989								// Assume the counters have got it right
1990							}
1991						}
1992						if(count($changes))
1993						{
1994							// *************** Update mail record here *********************
1995							$this->checkDB(1);
1996							$this->db->update('mail_content', array(
1997								'data' => $changes,
1998								'WHERE' => '`mail_source_id` = ' . $lastMail,
1999								'_FIELDS' => $this->dbTypes['mail_content']
2000							));
2001							$line = "Count update for {$saveRow['mail_source_id']} - {$saveRow['mail_togo_count']}, {$saveRow['mail_sent_count']}, {$saveRow['mail_fail_count']}, {$saveRow['mail_bounce_count']} => ";
2002							$line .= implode(', ', $counters);
2003							$results[] = $line;
2004							$changeCount++;
2005							//echo $line.'<br />';
2006						}
2007					}
2008
2009					// Now reset for current mail
2010					$lastMail = $row['mail_source_id'];
2011					$counters = array(
2012						'mail_togo_count' => 0,
2013						'mail_sent_count' => 0,
2014						'mail_fail_count' => 0,
2015						'mail_bounce_count' => 0
2016					);
2017					$saveRow = $row;
2018				}
2019				if($row === FALSE)
2020					$notLast = FALSE;
2021				// We get one record for each mail_status value for a given email - use them to
2022				// update counts
2023				if($notLast)
2024				{
2025					switch ($row['mail_status'])
2026					{
2027						case MAIL_STATUS_SENT:
2028							// Mail sent. Email handler happy, but may have bounced (or may be yet to bounce)
2029							$counters['mail_sent_count'] += $row['mr_count'];
2030						break;
2031						case MAIL_STATUS_BOUNCED:
2032							$counters['mail_sent_count'] += $row['mr_count'];
2033							// It was sent, so increment that counter
2034							$counters['mail_bounce_count'] += $row['mr_count'];
2035							//...but bounced, so extra status
2036						break;
2037						case MAIL_STATUS_CANCELLED:
2038						// Cancelled email - treat as a failure
2039						case MAIL_STATUS_FAILED:
2040							$counters['mail_fail_count'] += $row['mr_count'];
2041							// Never sent at all
2042						break;
2043						case MAIL_STATUS_PARTIAL:
2044							// Shouldn't get this on individual emails - ignore if we do
2045						break;
2046						default:
2047							if(($row['mail_status'] >= MAIL_STATUS_PENDING) && ($row['mail_status'] <= MAIL_STATUS_MAX_ACTIVE))
2048							{
2049								$counters['mail_togo_count'] += $row['mr_count'];
2050								// Still in the queue
2051							}
2052					}
2053				}
2054			}
2055			if($changeCount)
2056				$results[] = str_replace('[x]', $changeCount, LAN_MAILOUT_237);
2057		}
2058
2059		e107::getLog()->add('MAIL_05', implode('[!br!]', $results), E_LOG_INFORMATIVE, '');
2060		return $noError;
2061	}
2062
2063	/**
2064	 *	Get a list of all the available email templates, by name and variable name
2065	 *
2066	 *	@param string $sel - currently (all|system|user) - selects template type
2067	 *
2068	 *	@return array - key is the variable name of the template, value is the stored
2069	 * template name
2070	 */
2071	public function getEmailTemplateNames($sel = 'all')
2072	{
2073		$ret = array();
2074
2075		$templates = e107::getCoreTemplate('email', false, 'front', false);
2076
2077		foreach($templates as $key => $layout)
2078		{
2079			if(vartrue($layout['name']))
2080			{
2081				$ret[$key] = $layout['name'];
2082			}
2083
2084		}
2085
2086		return $ret;
2087		/*
2088
2089		 foreach (array(e_CORE.'templates/email_template.php',
2090		THEME.'templates/email_template.php') as $templateFileName )	// Override file
2091		then defaults
2092		 if (is_readable($templateFileName))
2093		 {
2094		 require($templateFileName);
2095		 $tVars = get_defined_vars();
2096		 if (isset($tVars['GLOBALS'])) unset($tVars['GLOBALS']);
2097		 foreach ($tVars as $tKey => $tData)
2098		 {
2099		 if (is_array($tData) && isset($tData['template_name']))
2100		 {
2101		 if (!isset($tData['template_type']) || ($tData['template_type'] == 'all') ||
2102		($tData['template_type'] == $sel))
2103		 {
2104		 $ret[$tKey] = $tData['template_name'];
2105		 }
2106		 }
2107		 if ($tKey != 'ret')
2108		 {
2109		 unset($tVars[$tKey]);
2110		 }
2111		 }
2112		 }
2113
2114		 print_a($ret);
2115		 return $ret;
2116
2117		 */
2118	}
2119
2120
2121
2122
2123	public static function mailerPrefsTable($pref, $id='mailer')
2124	{
2125
2126		$frm = e107::getForm();
2127
2128		$mailers = array('php'=>'php','smtp'=>'smtp','sendmail'=>'sendmail');
2129
2130		$smtp_opts = explode(',',varset($pref['smtp_options'],''));
2131		$smtpdisp = ($pref[$id] != 'smtp') ? "style='display:none;'" : '';
2132
2133		$text = $frm->select($id, $mailers, $pref[$id])."
2134		<span class='field-help'>".LAN_MAILOUT_116."</span>";
2135
2136		$text .= "<div id='smtp' {$smtpdisp}>
2137		<table class='table table-bordered adminlist' style='margin-top:10px;width:auto;margin-right:auto;margin-left:0'>
2138		<colgroup>
2139			<col class='col-label' />
2140			<col class='col-control' />
2141		</colgroup>
2142		";
2143
2144
2145		$ports = array(25=>'25 ('.LAN_DEFAULT.")",26=>'26',465=>'465 (SSL)', 587=>'587', 2465=>'2465', 2525=>'2525', 2587=>'2587');
2146
2147		$text .= "
2148		<tr>
2149		<td>".LAN_MAILOUT_87.":&nbsp;&nbsp;</td>
2150		<td>".$frm->text('smtp_server',$pref['smtp_server'], 128, array('size'=>'xxlarge'))."</td>
2151		</tr>
2152
2153		<tr>
2154		<td>".LAN_MAILOUT_88.":</td>
2155		<td style='width:50%;' >".$frm->text('smtp_username',$pref['smtp_username'], 128, array('size'=>'xxlarge', 'placeholder'=>"(".LAN_OPTIONAL.")"))."</td>
2156		</tr>
2157
2158		<tr>
2159		<td>".LAN_MAILOUT_89.":</td>
2160		<td>".$frm->password('smtp_password',$pref['smtp_password'], 128, array('size'=>'xxlarge', 'required'=>false, 'pattern'=>'.{4,}', 'placeholder'=>"(".LAN_OPTIONAL.")", 'autocomplete'=>'new-password'))."
2161		</td>
2162		</tr>
2163
2164		<tr>
2165		<td>".LAN_MAILOUT_261."</td>
2166		<td>".$frm->select('smtp_port',$ports, $pref['smtp_port'])."
2167		</td>
2168		</tr>
2169
2170		<tr>
2171		<td>".LAN_MAILOUT_90."</td><td>
2172		<select class='tbox' name='smtp_options'>\n
2173
2174		<option value=''>".LAN_NONE."</option>\n";
2175		$selected = (in_array('secure=SSL',$smtp_opts) ? " selected='selected'" : '');
2176		$text .= "<option value='smtp_ssl'{$selected}>".LAN_MAILOUT_92."</option>\n";
2177		$selected = (in_array('secure=TLS',$smtp_opts) ? " selected='selected'" : '');
2178		$text .= "<option value='smtp_tls'{$selected}>".LAN_MAILOUT_93."</option>\n";
2179		$selected = (in_array('pop3auth',$smtp_opts) ? " selected='selected'" : '');
2180		$text .= "<option value='smtp_pop3auth'{$selected}>".LAN_MAILOUT_91."</option>\n";
2181		$text .= "</select></td></tr>";
2182
2183		$text .= "<tr>
2184			<td><label for='smtp_keepalive'>".LAN_MAILOUT_57."</label></td><td>\n";
2185
2186		$text .= $frm->radio_switch('smtp_keepalive', $pref['smtp_keepalive'])."
2187			</td>
2188			</tr>";
2189
2190
2191		$text .= "<tr>
2192			<td><label for='smtp_useVERP'>".LAN_MAILOUT_95."</label></td><td>".$frm->radio_switch('smtp_useVERP',(in_array('useVERP',$smtp_opts)))."
2193				</td>
2194			</tr>
2195			</table></div>";
2196
2197		/* FIXME - posting SENDMAIL path triggers Mod-Security rules. use define() in e107_config.php instead.
2198			// Sendmail. -------------->
2199
2200				$text .= "<div id='sendmail' {$senddisp}><table style='margin-right:0px;margin-left:auto;border:0px'>";
2201				$text .= "
2202				<tr>
2203				<td>".LAN_MAILOUT_20.":&nbsp;&nbsp;</td>
2204				<td>
2205				<input class='tbox' type='text' name='sendmail' size='60' value=\"".(!$pref['sendmail'] ? "/usr/sbin/sendmail -t -i -r ".$pref['siteadminemail'] : $pref['sendmail'])."\" maxlength='80' />
2206				</td>
2207				</tr>
2208
2209				</table></div>";
2210			*/
2211
2212		e107::js('footer-inline', "
2213
2214			$('#".$id."').on('change', function() {
2215
2216				var type = $(this).val();
2217
2218				if(type == 'smtp')
2219				{
2220					$('#smtp').show('slow');
2221					$('#sendmail').hide('slow');
2222					return;
2223				}
2224
2225				if(type =='sendmail')
2226				{
2227					$('#smtp').hide('slow');
2228					$('#sendmail').show('slow');
2229					return;
2230				}
2231
2232				$('#smtp').hide('slow');
2233				$('#sendmail').hide('slow');
2234
2235
2236			});
2237
2238
2239		");
2240
2241
2242
2243
2244
2245
2246		return $text;
2247
2248
2249	}
2250
2251
2252}
2253
2254