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