1<?php
2/* Copyright (C) 2013-2016    Jean-François FERRY <hello@librethic.io>
3 * Copyright (C) 2016         Christophe Battarel <christophe@altairis.fr>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19/**
20 *       \file       htdocs/public/ticket/create_ticket.php
21 *       \ingroup    ticket
22 *       \brief      Display public form to add new ticket
23 */
24
25if (!defined('NOREQUIREUSER')) {
26	define('NOREQUIREUSER', '1');
27}
28if (!defined('NOTOKENRENEWAL')) {
29	define('NOTOKENRENEWAL', '1');
30}
31if (!defined('NOREQUIREMENU')) {
32	define('NOREQUIREMENU', '1');
33}
34if (!defined('NOREQUIREHTML')) {
35	define('NOREQUIREHTML', '1');
36}
37if (!defined('NOLOGIN')) {
38	define("NOLOGIN", 1); // This means this output page does not require to be logged.
39}
40if (!defined('NOCSRFCHECK')) {
41	define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
42}
43if (!defined('NOIPCHECK')) {
44	define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
45}
46if (!defined('NOBROWSERNOTIF')) {
47	define('NOBROWSERNOTIF', '1');
48}
49
50
51require '../../main.inc.php';
52require_once DOL_DOCUMENT_ROOT.'/ticket/class/actions_ticket.class.php';
53require_once DOL_DOCUMENT_ROOT.'/core/class/html.formticket.class.php';
54require_once DOL_DOCUMENT_ROOT.'/core/lib/ticket.lib.php';
55require_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
56require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
57require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
58require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
59require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
60
61// Load translation files required by the page
62$langs->loadLangs(array('companies', 'other', 'mails', 'ticket'));
63
64// Get parameters
65$id = GETPOST('id', 'int');
66$msg_id = GETPOST('msg_id', 'int');
67
68$action = GETPOST('action', 'aZ09');
69
70// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
71$hookmanager->initHooks(array('publicnewticketcard', 'globalcard'));
72
73$object = new Ticket($db);
74$extrafields = new ExtraFields($db);
75
76$extrafields->fetch_name_optionals_label($object->table_element);
77
78
79/*
80 * Actions
81 */
82
83$parameters = array(
84	'id' => $id,
85);
86// Note that $action and $object may have been modified by some hooks
87$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action);
88if ($reshook < 0) {
89	setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
90}
91// Add file in email form
92if (empty($reshook) && GETPOST('addfile', 'alpha') && !GETPOST('add', 'alpha')) {
93	////$res = $object->fetch('','',GETPOST('track_id'));
94	////if($res > 0)
95	////{
96	include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
97
98	// Set tmp directory TODO Use a dedicated directory for temp mails files
99	$vardir = $conf->ticket->dir_output;
100	$upload_dir_tmp = $vardir.'/temp/'.session_id();
101	if (!dol_is_dir($upload_dir_tmp)) {
102		dol_mkdir($upload_dir_tmp);
103	}
104
105	dol_add_file_process($upload_dir_tmp, 0, 0, 'addedfile', '', null, '', 0);
106	$action = 'create_ticket';
107	////}
108}
109
110// Remove file
111if (empty($reshook) && GETPOST('removedfile', 'alpha') && !GETPOST('add', 'alpha')) {
112	include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
113
114	// Set tmp directory
115	$vardir = $conf->ticket->dir_output.'/';
116	$upload_dir_tmp = $vardir.'/temp/'.session_id();
117
118	// TODO Delete only files that was uploaded from email form
119	dol_remove_file_process($_POST['removedfile'], 0, 0);
120	$action = 'create_ticket';
121}
122
123if (empty($reshook) && $action == 'create_ticket' && GETPOST('add', 'alpha')) {
124	$error = 0;
125	$origin_email = GETPOST('email', 'alpha');
126	if (empty($origin_email)) {
127		$error++;
128		array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Email")));
129		$action = '';
130	} else {
131		// Search company saved with email
132		$searched_companies = $object->searchSocidByEmail($origin_email, '0');
133
134		// Chercher un contact existant avec cette adresse email
135		// Le premier contact trouvé est utilisé pour déterminer le contact suivi
136		$contacts = $object->searchContactByEmail($origin_email);
137
138		// Option to require email exists to create ticket
139		if (!empty($conf->global->TICKET_EMAIL_MUST_EXISTS) && !$contacts[0]->socid) {
140			$error++;
141			array_push($object->errors, $langs->trans("ErrorEmailMustExistToCreateTicket"));
142			$action = '';
143		}
144	}
145
146	if (!GETPOST("subject", "restricthtml")) {
147		$error++;
148		array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("Subject")));
149		$action = '';
150	} elseif (!GETPOST("message", "restricthtml")) {
151		$error++;
152		array_push($object->errors, $langs->trans("ErrorFieldRequired", $langs->transnoentities("message")));
153		$action = '';
154	}
155
156	// Check email address
157	if (!isValidEmail($origin_email)) {
158		$error++;
159		array_push($object->errors, $langs->trans("ErrorBadEmailAddress", $langs->transnoentities("email")));
160		$action = '';
161	}
162
163	// Check Captcha code if is enabled
164	if (!empty($conf->global->MAIN_SECURITY_ENABLECAPTCHA)) {
165		$sessionkey = 'dol_antispam_value';
166		$ok = (array_key_exists($sessionkey, $_SESSION) === true && (strtolower($_SESSION[$sessionkey]) === strtolower(GETPOST('code', 'none'))));
167		if (!$ok) {
168			$error++;
169			array_push($object->errors, $langs->trans("ErrorBadValueForCode"));
170			$action = '';
171		}
172	}
173
174	if (!$error) {
175		$object->db->begin();
176
177		$object->track_id = generate_random_id(16);
178
179		$object->subject = GETPOST("subject", "restricthtml");
180		$object->message = GETPOST("message", "restricthtml");
181		$object->origin_email = $origin_email;
182
183		$object->type_code = GETPOST("type_code", 'aZ09');
184		$object->category_code = GETPOST("category_code", 'aZ09');
185		$object->severity_code = GETPOST("severity_code", 'aZ09');
186		if (is_array($searched_companies)) {
187			$object->fk_soc = $searched_companies[0]->id;
188		}
189
190		if (is_array($contacts) and count($contacts) > 0) {
191			$object->fk_soc = $contacts[0]->socid;
192			$usertoassign = $contacts[0]->id;
193		}
194
195		$ret = $extrafields->setOptionalsFromPost(null, $object);
196
197		// Generate new ref
198		$object->ref = $object->getDefaultRef();
199		if (!is_object($user)) {
200			$user = new User($db);
201		}
202
203		$object->context['disableticketemail'] = 1; // Disable emails sent by ticket trigger when creation is done from this page, emails are already sent later
204
205		$id = $object->create($user);
206		if ($id <= 0) {
207			$error++;
208			$errors = ($object->error ? array($object->error) : $object->errors);
209			array_push($object->errors, $object->error ? array($object->error) : $object->errors);
210			$action = 'create_ticket';
211		}
212
213		if (!$error && $id > 0) {
214			if ($usertoassign > 0) {
215				$object->add_contact($usertoassign, "SUPPORTCLI", 'external', 0);
216			}
217		}
218
219		if (!$error) {
220			$object->db->commit();
221			$action = "infos_success";
222		} else {
223			$object->db->rollback();
224			setEventMessages($object->error, $object->errors, 'errors');
225			$action = 'create_ticket';
226		}
227
228		if (!$error) {
229			$res = $object->fetch($id);
230			if ($res) {
231				// Create form object
232				include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php';
233				include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
234				$formmail = new FormMail($db);
235
236				// Init to avoid errors
237				$filepath = array();
238				$filename = array();
239				$mimetype = array();
240
241				$attachedfiles = $formmail->get_attached_files();
242				$filepath = $attachedfiles['paths'];
243				$filename = $attachedfiles['names'];
244				$mimetype = $attachedfiles['mimes'];
245
246				// Send email to customer
247
248				$subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubject', $object->ref, $object->track_id);
249				$message  = ($conf->global->TICKET_MESSAGE_MAIL_NEW ? $conf->global->TICKET_MESSAGE_MAIL_NEW : $langs->transnoentities('TicketNewEmailBody')).'<br><br>';
250				$message .= $langs->transnoentities('TicketNewEmailBodyInfosTicket').'<br>';
251
252				$url_public_ticket = ($conf->global->TICKET_URL_PUBLIC_INTERFACE ? $conf->global->TICKET_URL_PUBLIC_INTERFACE.'/' : dol_buildpath('/public/ticket/view.php', 2)).'?track_id='.$object->track_id;
253				$infos_new_ticket = $langs->transnoentities('TicketNewEmailBodyInfosTrackId', '<a href="'.$url_public_ticket.'" rel="nofollow noopener">'.$object->track_id.'</a>').'<br>';
254				$infos_new_ticket .= $langs->transnoentities('TicketNewEmailBodyInfosTrackUrl').'<br><br>';
255
256				$message .= $infos_new_ticket;
257				$message .= $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE ? $conf->global->TICKET_MESSAGE_MAIL_SIGNATURE : $langs->transnoentities('TicketMessageMailSignatureText');
258
259				$sendto = GETPOST('email', 'alpha');
260
261				$from = $conf->global->MAIN_INFO_SOCIETE_NOM.' <'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>';
262				$replyto = $from;
263				$sendtocc = '';
264				$deliveryreceipt = 0;
265
266				if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
267					$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
268					$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
269				}
270				include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
271				$mailfile = new CMailFile($subject, $sendto, $from, $message, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', 'tic'.$object->id, '', 'ticket');
272				if ($mailfile->error || $mailfile->errors) {
273					setEventMessages($mailfile->error, $mailfile->errors, 'errors');
274				} else {
275					$result = $mailfile->sendfile();
276				}
277				if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
278					$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
279				}
280
281				// Send email to TICKET_NOTIFICATION_EMAIL_TO
282				$sendto = $conf->global->TICKET_NOTIFICATION_EMAIL_TO;
283				if ($sendto) {
284					$subject = '['.$conf->global->MAIN_INFO_SOCIETE_NOM.'] '.$langs->transnoentities('TicketNewEmailSubjectAdmin', $object->ref, $object->track_id);
285					$message_admin = $langs->transnoentities('TicketNewEmailBodyAdmin', $object->track_id).'<br><br>';
286					$message_admin .= '<ul><li>'.$langs->trans('Title').' : '.$object->subject.'</li>';
287					$message_admin .= '<li>'.$langs->trans('Type').' : '.$object->type_label.'</li>';
288					$message_admin .= '<li>'.$langs->trans('Category').' : '.$object->category_label.'</li>';
289					$message_admin .= '<li>'.$langs->trans('Severity').' : '.$object->severity_label.'</li>';
290					$message_admin .= '<li>'.$langs->trans('From').' : '.$object->origin_email.'</li>';
291					// Extrafields
292					$extrafields->fetch_name_optionals_label($object->table_element);
293					if (is_array($object->array_options) && count($object->array_options) > 0) {
294						foreach ($object->array_options as $key => $value) {
295							$key = substr($key, 8); // remove "options_"
296							$message_admin .= '<li>'.$langs->trans($extrafields->attributes[$object->element]['label'][$key]).' : '.$extrafields->showOutputField($key, $value).'</li>';
297						}
298					}
299					$message_admin .= '</ul>';
300
301					$message_admin .= '<p>'.$langs->trans('Message').' : <br>'.$object->message.'</p>';
302					$message_admin .= '<p><a href="'.dol_buildpath('/ticket/card.php', 2).'?track_id='.$object->track_id.'" rel="nofollow noopener">'.$langs->trans('SeeThisTicketIntomanagementInterface').'</a></p>';
303
304					$from = $conf->global->MAIN_INFO_SOCIETE_NOM.' <'.$conf->global->TICKET_NOTIFICATION_EMAIL_FROM.'>';
305					$replyto = $from;
306
307					if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
308						$old_MAIN_MAIL_AUTOCOPY_TO = $conf->global->MAIN_MAIL_AUTOCOPY_TO;
309						$conf->global->MAIN_MAIL_AUTOCOPY_TO = '';
310					}
311					include_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php';
312					$mailfile = new CMailFile($subject, $sendto, $from, $message_admin, $filepath, $mimetype, $filename, $sendtocc, '', $deliveryreceipt, -1, '', '', 'tic'.$object->id, '', 'ticket');
313					if ($mailfile->error || $mailfile->errors) {
314						setEventMessages($mailfile->error, $mailfile->errors, 'errors');
315					} else {
316						$result = $mailfile->sendfile();
317					}
318					if (!empty($conf->global->TICKET_DISABLE_MAIL_AUTOCOPY_TO)) {
319						$conf->global->MAIN_MAIL_AUTOCOPY_TO = $old_MAIN_MAIL_AUTOCOPY_TO;
320					}
321				}
322			}
323
324			// Copy files into ticket directory
325			$destdir = $conf->ticket->dir_output.'/'.$object->ref;
326			if (!dol_is_dir($destdir)) {
327				dol_mkdir($destdir);
328			}
329			foreach ($filename as $i => $val) {
330				dol_move($filepath[$i], $destdir.'/'.$filename[$i], 0, 1);
331				$formmail->remove_attached_files($i);
332			}
333
334			//setEventMessages($langs->trans('YourTicketSuccessfullySaved'), null, 'mesgs');
335
336			// Make a redirect to avoid to have ticket submitted twice if we make back
337			$messagetoshow = $langs->trans('MesgInfosPublicTicketCreatedWithTrackId', '{s1}', '{s2}');
338			$messagetoshow = str_replace(array('{s1}', '{s2}'), array('<strong>'.$object->track_id.'</strong>', '<strong>'.$object->ref.'</strong>'), $messagetoshow);
339			setEventMessages($messagetoshow, null, 'warnings');
340			setEventMessages($langs->trans('PleaseRememberThisId'), null, 'warnings');
341			header("Location: index.php");
342			exit;
343		}
344	} else {
345		setEventMessages($object->error, $object->errors, 'errors');
346	}
347}
348
349
350
351/*
352 * View
353 */
354
355$form = new Form($db);
356$formticket = new FormTicket($db);
357
358if (!$conf->global->TICKET_ENABLE_PUBLIC_INTERFACE) {
359	print '<div class="error">'.$langs->trans('TicketPublicInterfaceForbidden').'</div>';
360	$db->close();
361	exit();
362}
363
364$arrayofjs = array();
365$arrayofcss = array('/opensurvey/css/style.css', '/ticket/css/styles.css.php');
366
367llxHeaderTicket($langs->trans("CreateTicket"), "", 0, 0, $arrayofjs, $arrayofcss);
368
369
370print '<div class="ticketpublicarea">';
371
372if ($action != "infos_success") {
373	$formticket->withfromsocid = isset($socid) ? $socid : $user->socid;
374	$formticket->withtitletopic = 1;
375	$formticket->withcompany = 0;
376	$formticket->withusercreate = 1;
377	$formticket->fk_user_create = 0;
378	$formticket->withemail = 1;
379	$formticket->ispublic = 1;
380	$formticket->withfile = 2;
381	$formticket->action = 'create_ticket';
382
383	$formticket->param = array('returnurl' => $_SERVER['PHP_SELF'].($conf->entity > 1 ? '?entity='.$conf->entity : ''));
384
385	print load_fiche_titre($langs->trans('NewTicket'), '', '', 0, 0, 'marginleftonly');
386
387	if (empty($conf->global->TICKET_NOTIFICATION_EMAIL_FROM)) {
388		$langs->load("errors");
389		print '<div class="error">';
390		print $langs->trans("ErrorFieldRequired", $langs->transnoentities("TicketEmailNotificationFrom")).'<br>';
391		print $langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentities("Ticket"));
392		print '</div>';
393	} else {
394		print '<div class="info marginleftonly marginrightonly">'.$langs->trans('TicketPublicInfoCreateTicket').'</div>';
395		$formticket->showForm(0, 'edit', 1);
396	}
397}
398
399print '</div>';
400
401// End of page
402htmlPrintOnlinePaymentFooter($mysoc, $langs, 1, $suffix, $object);
403
404llxFooter('', 'public');
405
406$db->close();
407