static function saveUsers($sql, $filename, $how = 'csv') { $exclude = array('name', 'email'); $form = UserForm::getUserForm(); $fields = $form->getExportableFields($exclude); // Field selection callback $fname = function ($f) { return 'cdata.`' . $f->getSelectName() . '` AS __field_' . $f->get('id'); }; $sql = substr_replace($sql, ',' . implode(',', array_map($fname, $fields)) . ' ', strpos($sql, 'FROM '), 0); $sql = substr_replace($sql, 'LEFT JOIN (' . $form->getCrossTabQuery($form->type, 'user_id', $exclude) . ') cdata ON (cdata.user_id = user.id) ', strpos($sql, 'WHERE '), 0); $cdata = array_combine(array_keys($fields), array_values(array_map(function ($f) { return $f->get('label'); }, $fields))); ob_start(); echo self::dumpQuery($sql, array('name' => 'Name', 'organization' => 'Organization', 'email' => 'Email') + $cdata, $how, array('modify' => function (&$record, $keys) use($fields) { foreach ($fields as $k => $f) { if ($f && ($i = array_search($k, $keys)) !== false) { $record[$i] = $f->export($f->to_php($record[$i])); } } return $record; })); $stuff = ob_get_contents(); ob_end_clean(); if ($stuff) { Http::download($filename, "text/{$how}", $stuff); } return false; }
if ($_POST) { switch (strtolower($_REQUEST['do'])) { case 'update': if (!$user) { $errors['err'] = 'Unknown or invalid user.'; } elseif (($acct = $user->getAccount()) && !$acct->update($_POST, $errors)) { $errors['err'] = 'Unable to update user account information'; } elseif ($user->updateInfo($_POST, $errors)) { $msg = 'User updated successfully'; $_REQUEST['a'] = null; } elseif (!$errors['err']) { $errors['err'] = 'Unable to update user profile. Correct any error(s) below and try again!'; } break; case 'create': $form = UserForm::getUserForm()->getForm($_POST); if ($user = User::fromForm($form)) { $msg = Format::htmlchars($user->getName()) . ' added successfully'; $_REQUEST['a'] = null; } elseif (!$errors['err']) { $errors['err'] = 'Unable to add user. Correct any error(s) below and try again.'; } break; case 'confirmlink': if (!$user || !$user->getAccount()) { $errors['err'] = 'Unknown or invalid user account'; } elseif ($user->getAccount()->isConfirmed()) { $errors['err'] = 'Account is already confirmed'; } elseif ($user->getAccount()->sendConfirmEmail()) { $msg = 'Account activation email sent to ' . $user->getEmail(); } else {
function addRemoteUser($bk, $id) { global $thisstaff; if (!$thisstaff) { Http::response(403, 'Login Required'); } elseif (!$bk || !$id) { Http::response(422, 'Backend and customer id required'); } elseif (!($backend = AuthenticationBackend::getSearchDirectoryBackend($bk)) || !($user_info = $backend->lookup($id))) { Http::response(404, 'Customer not found'); } $form = UserForm::getUserForm()->getForm($user_info); $info = array('title' => 'Import Remote Customer'); if (!$user_info) { $info['error'] = 'Unable to find customer in directory'; } include STAFFINC_DIR . 'templates/user-lookup.tmpl.php'; }
<div class="tab_content" id="upload" style="display:none;margin:5px;"> <h2 style="margin-bottom:10px">Import a CSV File</h2> <p> <em>Use the columns shown in the table below. To add more fields, visit the Admin Panel -> Manage -> Forms -> <?php echo UserForm::getUserForm()->get('title'); ?> page to edit the available fields. Only fields with `variable` defined can be imported.</em> </p> <table class="list"><tr> <?php $fields = array(); $data = array(array('name' => 'John Doe', 'email' => '*****@*****.**')); foreach (UserForm::getUserForm()->getFields() as $f) { if ($f->get('name')) { $fields[] = $f->get('name'); } } foreach ($fields as $f) { ?> <th><?php echo mb_convert_case($f, MB_CASE_TITLE); ?> </th> <?php } ?> </tr> <?php
function addCollaborator($tid, $uid = 0) { global $thisstaff; if (!($ticket = Ticket::lookup($tid)) || !$ticket->checkStaffAccess($thisstaff)) { Http::response(404, 'No such ticket'); } $user = $uid ? User::lookup($uid) : null; //If not a post then assume new collaborator form if (!$_POST) { return self::_addcollaborator($ticket, $user); } $user = $form = null; if (isset($_POST['id']) && $_POST['id']) { //Existing user/ $user = User::lookup($_POST['id']); } else { //We're creating a new user! $form = UserForm::getUserForm()->getForm($_POST); $user = User::fromForm($form); } $errors = $info = array(); if ($user) { if ($user->getId() == $ticket->getOwnerId()) { $errors['err'] = sprintf('Ticket owner, %s, is a collaborator by default!', Format::htmlchars($user->getName())); } elseif ($c = $ticket->addCollaborator($user, array('isactive' => 1), $errors)) { $note = Format::htmlchars(sprintf('%s <%s> added as a collaborator', Format::htmlchars($c->getName()), $c->getEmail())); $ticket->logNote('New Collaborator Added', $note, $thisstaff, false); $info = array('msg' => sprintf('%s added as a collaborator', Format::htmlchars($c->getName()))); return self::_collaborators($ticket, $info); } } if ($errors && $errors['err']) { $info += array('error' => $errors['err']); } else { $info += array('error' => 'Unable to add collaborator - try again'); } return self::_addcollaborator($ticket, $user, $form, $info); }
// Rotate the CSRF token (original cannot be reused) $ost->getCSRF()->rotate(); } if ($_POST && isset($_POST['luser'])) { if (!$_POST['luser']) { $errors['err'] = __('Valid username or email address is required'); } elseif ($user = UserAuthenticationBackend::process($_POST['luser'], $_POST['lpasswd'], $errors)) { if ($user instanceof ClientCreateRequest) { if ($cfg && $cfg->isClientRegistrationEnabled()) { // Attempt to automatically register if ($user->attemptAutoRegister()) { Http::redirect('tickets.php'); } // Auto-registration failed. Show the user the info we have $inc = 'register.inc.php'; $user_form = UserForm::getUserForm()->getForm($user->getInfo()); } else { $errors['err'] = __('Access Denied. Contact your help desk administrator to have an account registered for you'); // fall through to show login page again } } else { Http::redirect($_SESSION['_client']['auth']['dest'] ?: 'tickets.php'); } } elseif (!$errors['err']) { $errors['err'] = __('Invalid username or password - try again!'); } $suggest_pwreset = true; } elseif ($_POST && isset($_POST['lticket'])) { if (!Validator::is_email($_POST['lemail'])) { $errors['err'] = __('Valid email address and ticket number required'); } elseif ($user = UserAuthenticationBackend::process($_POST['lemail'], $_POST['lticket'], $errors)) {
function attemptAutoRegister() { global $cfg; if (!$cfg) { return false; } // Attempt to automatically register $this_form = UserForm::getUserForm()->getForm($this->getInfo()); $bk = $this->getBackend(); $defaults = array('timezone_id' => $cfg->getDefaultTimezoneId(), 'dst' => $cfg->observeDaylightSaving(), 'username' => $this->getUsername()); if ($bk->supportsInteractiveAuthentication()) { // User can only be authenticated against this backend $defaults['backend'] = $bk::$id; } if ($this_form->isValid(function ($f) { return !$f->get('private'); }) && ($U = User::fromVars($this_form->getClean())) && ($acct = ClientAccount::createForUser($U, $defaults)) && $acct->confirm() && ($cl = new ClientSession(new EndUser($U))) && $bk->login($cl, $bk)) { return $cl; } }
function addUser($id, $userId = 0, $remote = false) { global $thisstaff; if (!$thisstaff) { Http::response(403, 'Login Required'); } elseif (!($org = Organization::lookup($id))) { Http::response(404, 'Unknown organization'); } $info = array(); $info['title'] = __('Add User'); $info['action'] = '#orgs/' . $org->getId() . '/add-user'; $info['onselect'] = 'ajax.php/orgs/' . $org->getId() . '/add-user/'; $info['lookup'] = false; if (AuthenticationBackend::getSearchDirectories()) { $info['lookup'] = 'remote'; } if ($_POST) { if ($_POST['id']) { //Existing useer if (!($user = User::lookup($_POST['id']))) { $info['error'] = __('Unknown user selected'); } elseif ($user->getOrgId() == $org->getId()) { $info['error'] = sprintf('%s already belongs to the organization', Format::htmlchars($user->getName())); } } else { //Creating new user $form = UserForm::getUserForm()->getForm($_POST); if (!($user = User::fromForm($form))) { $info['error'] = __('Error adding user - try again!'); } } if (!$info['error'] && $user && $user->setOrganization($org)) { Http::response(201, $user->to_json()); } elseif (!$info['error']) { $info['error'] = __('Unable to add user to the organization - try again'); } } elseif ($remote && $userId) { list($bk, $userId) = explode(':', $userId, 2); if (!($backend = AuthenticationBackend::getSearchDirectoryBackend($bk)) || !($user_info = $backend->lookup($userId))) { Http::response(404, 'User not found'); } $form = UserForm::getUserForm()->getForm($user_info); } elseif ($userId) { //Selected local user $user = User::lookup($userId); } if ($user && $user->getOrgId()) { if ($user->getOrgId() == $org->getId()) { $info['warn'] = __('User already belongs to this organization!'); } else { $info['warn'] = __("Are you sure you want to change the user's organization?"); } } ob_start(); include STAFFINC_DIR . 'templates/user-lookup.tmpl.php'; $resp = ob_get_contents(); ob_end_clean(); return $resp; }
static function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true) { global $ost, $cfg, $thisclient, $_FILES; // Don't enforce form validation for email $field_filter = function ($type) use($origin) { return function ($f) use($origin, $type) { // Ultimately, only offer validation errors for web for // non-internal fields. For email, no validation can be // performed. For other origins, validate as usual switch (strtolower($origin)) { case 'email': return false; case 'staff': // Required 'Contact Information' fields aren't required // when staff open tickets return $type != 'user' || in_array($f->get('name'), array('name', 'email')); case 'web': return !$f->get('private'); default: return true; } }; }; $reject_ticket = function ($message) use(&$errors) { global $ost; $errors = array('errno' => 403, 'err' => __('This help desk is for use by authorized users only')); $ost->logWarning(_S('Ticket Denied'), $message, false); return 0; }; Signal::send('ticket.create.before', null, $vars); // Create and verify the dynamic form entry for the new ticket $form = TicketForm::getNewInstance(); $form->setSource($vars); // If submitting via email or api, ensure we have a subject and such if (!in_array(strtolower($origin), array('web', 'staff'))) { foreach ($form->getFields() as $field) { $fname = $field->get('name'); if ($fname && isset($vars[$fname]) && !$field->value) { $field->value = $field->parse($vars[$fname]); } } } if (!$form->isValid($field_filter('ticket'))) { $errors += $form->errors(); } if ($vars['uid']) { $user = User::lookup($vars['uid']); } $id = 0; $fields = array(); $fields['message'] = array('type' => '*', 'required' => 1, 'error' => __('Message content is required')); switch (strtolower($origin)) { case 'web': $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Select a help topic')); break; case 'staff': $fields['deptId'] = array('type' => 'int', 'required' => 0, 'error' => __('Department selection is required')); $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Help topic selection is required')); $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => __('Invalid date format - must be MM/DD/YY')); case 'api': $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => __('Indicate ticket source')); break; case 'email': $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => __('Unknown system email')); break; default: # TODO: Return error message $errors['err'] = $errors['origin'] = __('Invalid ticket origin given'); } if (!Validator::process($fields, $vars, $errors) && !$errors['err']) { $errors['err'] = __('Missing or invalid data - check the errors and try again'); } //Make sure the due date is valid if ($vars['duedate']) { if (!$vars['time'] || strpos($vars['time'], ':') === false) { $errors['time'] = __('Select a time from the list'); } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) { $errors['duedate'] = __('Invalid due date'); } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) { $errors['duedate'] = __('Due date must be in the future'); } } if (!$errors) { # Perform ticket filter actions on the new ticket arguments $__form = null; if ($vars['topicId']) { if (($__topic = Topic::lookup($vars['topicId'])) && ($__form = $__topic->getForm())) { $__form = $__form->instanciate(); $__form->setSource($vars); } } try { $vars = self::filterTicketData($origin, $vars, array($form, $__form), $user); } catch (RejectedException $ex) { return $reject_ticket(sprintf(_S('Ticket rejected (%s) by filter "%s"'), $ex->vars['email'], $ex->getRejectingFilter()->getName())); } //Make sure the open ticket limit hasn't been reached. (LOOP CONTROL) if ($cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff') && ($_user = TicketUser::lookupByEmail($vars['email'])) && ($openTickets = $_user->getNumOpenTickets()) && $openTickets >= $cfg->getMaxOpenTickets()) { $errors = array('err' => __("You've reached the maximum open tickets allowed.")); $ost->logWarning(sprintf(_S('Ticket denied - %s'), $vars['email']), sprintf(_S('Max open tickets (%1$d) reached for %2$s'), $cfg->getMaxOpenTickets(), $vars['email']), false); return 0; } // Allow vars to be changed in ticket filter and applied to the user // account created or detected if (!$user && $vars['email']) { $user = User::lookupByEmail($vars['email']); } if (!$user) { // Reject emails if not from registered clients (if // configured) if (strcasecmp($origin, 'email') === 0 && !$cfg->acceptUnregisteredEmail()) { list($mailbox, $domain) = explode('@', $vars['email'], 2); // Users not yet created but linked to an organization // are still acceptable if (!Organization::forDomain($domain)) { return $reject_ticket(sprintf(_S('Ticket rejected (%s) (unregistered client)'), $vars['email'])); } } $user_form = UserForm::getUserForm()->getForm($vars); if (!$user_form->isValid($field_filter('user')) || !($user = User::fromVars($user_form->getClean()))) { $errors['user'] = __('Incomplete client information'); } } } if ($vars['topicId']) { if ($topic = Topic::lookup($vars['topicId'])) { if ($topic_form = $topic->getForm()) { $TF = $topic_form->getForm($vars); $topic_form = $topic_form->instanciate(); $topic_form->setSource($vars); if (!$TF->isValid($field_filter('topic'))) { $errors = array_merge($errors, $TF->errors()); } } } else { $errors['topicId'] = 'Invalid help topic selected'; } } // Any error above is fatal. if ($errors) { return 0; } Signal::send('ticket.create.validated', null, $vars); # Some things will need to be unpacked back into the scope of this # function if (isset($vars['autorespond'])) { $autorespond = $vars['autorespond']; } # Apply filter-specific priority if ($vars['priorityId']) { $form->setAnswer('priority', null, $vars['priorityId']); } // If the filter specifies a help topic which has a form associated, // and there was previously either no help topic set or the help // topic did not have a form, there's no need to add it now as (1) // validation is closed, (2) there may be a form already associated // and filled out from the original help topic, and (3) staff // members can always add more forms now // OK...just do it. $statusId = $vars['statusId']; $deptId = $vars['deptId']; //pre-selected Dept if any. $source = ucfirst($vars['source']); // Apply email settings for emailed tickets. Email settings should // trump help topic settins if the email has an associated help // topic if ($vars['emailId'] && ($email = Email::lookup($vars['emailId']))) { $deptId = $deptId ?: $email->getDeptId(); $priority = $form->getAnswer('priority'); if (!$priority || !$priority->getIdValue()) { $form->setAnswer('priority', null, $email->getPriorityId()); } if ($autorespond) { $autorespond = $email->autoRespond(); } if (!isset($topic) && ($T = $email->getTopic()) && $T->isActive()) { $topic = $T; } $email = null; $source = 'Email'; } if (!isset($topic)) { // This may return NULL, no big deal $topic = $cfg->getDefaultTopic(); } // Intenal mapping magic...see if we need to override anything if (isset($topic)) { $deptId = $deptId ?: $topic->getDeptId(); $statusId = $statusId ?: $topic->getStatusId(); $priority = $form->getAnswer('priority'); if (!$priority || !$priority->getIdValue()) { $form->setAnswer('priority', null, $topic->getPriorityId()); } if ($autorespond) { $autorespond = $topic->autoRespond(); } //Auto assignment. if (!isset($vars['staffId']) && $topic->getStaffId()) { $vars['staffId'] = $topic->getStaffId(); } elseif (!isset($vars['teamId']) && $topic->getTeamId()) { $vars['teamId'] = $topic->getTeamId(); } //set default sla. if (isset($vars['slaId'])) { $vars['slaId'] = $vars['slaId'] ?: $cfg->getDefaultSLAId(); } elseif ($topic && $topic->getSLAId()) { $vars['slaId'] = $topic->getSLAId(); } } // Auto assignment to organization account manager if (($org = $user->getOrganization()) && $org->autoAssignAccountManager() && ($code = $org->getAccountManagerId())) { if (!isset($vars['staffId']) && $code[0] == 's') { $vars['staffId'] = substr($code, 1); } elseif (!isset($vars['teamId']) && $code[0] == 't') { $vars['teamId'] = substr($code, 1); } } // Last minute checks $priority = $form->getAnswer('priority'); if (!$priority || !$priority->getIdValue()) { $form->setAnswer('priority', null, $cfg->getDefaultPriorityId()); } $deptId = $deptId ?: $cfg->getDefaultDeptId(); $statusId = $statusId ?: $cfg->getDefaultTicketStatusId(); $topicId = isset($topic) ? $topic->getId() : 0; $ipaddress = $vars['ip'] ?: $_SERVER['REMOTE_ADDR']; $source = $source ?: 'Web'; //We are ready son...hold on to the rails. $number = $topic ? $topic->getNewTicketNumber() : $cfg->getNewTicketNumber(); $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,user_id=' . db_input($user->getId()) . ' ,`number`=' . db_input($number) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source); if (isset($vars['emailId']) && $vars['emailId']) { $sql .= ', email_id=' . db_input($vars['emailId']); } //Make sure the origin is staff - avoid firebug hack! if ($vars['duedate'] && !strcasecmp($origin, 'staff')) { $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time']))); } if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) { return null; } /* -------------------- POST CREATE ------------------------ */ // Save the (common) dynamic form $form->setTicketId($id); $form->save(); // Save the form data from the help-topic form, if any if ($topic_form) { $topic_form->setTicketId($id); $topic_form->save(); } $ticket->loadDynamicData(); $dept = $ticket->getDept(); // Add organizational collaborators if ($org && $org->autoAddCollabs()) { $pris = $org->autoAddPrimaryContactsAsCollabs(); $members = $org->autoAddMembersAsCollabs(); $settings = array('isactive' => true); $collabs = array(); foreach ($org->allMembers() as $u) { if ($members || $pris && $u->isPrimaryContact()) { if ($c = $ticket->addCollaborator($u, $settings, $errors)) { $collabs[] = (string) $c; } } } //TODO: Can collaborators add others? if ($collabs) { //TODO: Change EndUser to name of user. $ticket->logNote(sprintf(_S('Collaborators for %s organization added'), $org->getName()), implode("<br>", $collabs), $org->getName(), false); } } //post the message. $vars['title'] = $vars['subject']; //Use the initial subject as title of the post. $vars['userId'] = $ticket->getUserId(); $message = $ticket->postMessage($vars, $origin, false); // Configure service-level-agreement for this ticket $ticket->selectSLAId($vars['slaId']); // Assign ticket to staff or team (new ticket by staff) if ($vars['assignId']) { $ticket->assign($vars['assignId'], $vars['note']); } else { // Auto assign staff or team - auto assignment based on filter // rules. Both team and staff can be assigned if ($vars['staffId']) { $ticket->assignToStaff($vars['staffId'], _S('Auto Assignment')); } if ($vars['teamId']) { // No team alert if also assigned to an individual agent $ticket->assignToTeam($vars['teamId'], _S('Auto Assignment'), !$vars['staffId']); } } // Apply requested status — this should be done AFTER assignment, // because if it is requested to be closed, it should not cause the // ticket to be reopened for assignment. if ($statusId) { $ticket->setStatus($statusId, false, false); } /********** double check auto-response ************/ //Override auto responder if the FROM email is one of the internal emails...loop control. if ($autorespond && Email::getIdByEmail($ticket->getEmail())) { $autorespond = false; } # Messages that are clearly auto-responses from email systems should # not have a return 'ping' message if (isset($vars['flags']) && $vars['flags']['bounce']) { $autorespond = false; } if ($autorespond && $message->isAutoReply()) { $autorespond = false; } //post canned auto-response IF any (disables new ticket auto-response). if ($vars['cannedResponseId'] && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) { $ticket->markUnAnswered(); //Leave the ticket as unanswred. $autorespond = false; } //Check department's auto response settings // XXX: Dept. setting doesn't affect canned responses. if ($autorespond && $dept && !$dept->autoRespONNewTicket()) { $autorespond = false; } //Don't send alerts to staff when the message is a bounce // this is necessary to avoid possible loop (especially on new ticket) if ($alertstaff && $message->isBounce()) { $alertstaff = false; } /***** See if we need to send some alerts ****/ $ticket->onNewTicket($message, $autorespond, $alertstaff); /************ check if the user JUST reached the max. open tickets limit **********/ if ($cfg->getMaxOpenTickets() > 0 && ($user = $ticket->getOwner()) && $user->getNumOpenTickets() == $cfg->getMaxOpenTickets()) { $ticket->onOpenLimit($autorespond && strcasecmp($origin, 'staff')); } /* Start tracking ticket lifecycle events */ $ticket->logEvent('created'); // Fire post-create signal (for extra email sending, searching) Signal::send('model.created', $ticket); /* Phew! ... time for tea (KETEPA) */ return $ticket; }
function createTicketByWebService($xml) { global $logFilePath; try { if (!empty($xml)) { $nodes = $xml->xpath('/contacts/contact'); } else { logErrors("The xml file can not be loaded "); } for ($i = 0; $i < count($nodes); $i++) { // echo json_encode($nodes[$i]); $data = array(); // $data['recipients'] = array(); $data['subject'] = removeLineBreaker($nodes[$i]->title); if (empty(removeLineBreaker($nodes[$i]->title))) { if (!empty(removeLineBreaker($nodes[$i]->crmsubject2_text))) { $data['subject'] = removeLineBreaker($nodes[$i]->crmsubject2_text); } else { $data['subject'] = "no title"; } } $data['header'] = ""; // $data['mid'] = 1; $data['source'] = "Web"; $data['topicId'] = 2; $data['priorityId'] = 2; $data['crm_contact_id'] = $nodes[$i]->attributes()->id; // $data['flags'] = new ArrayObject(); $data['email'] = trim(removeLineBreaker($nodes[$i]->email)); if (empty($data['email'])) { $data['email'] = "*****@*****.**"; } $data['phone'] = removeLineBreaker($nodes[$i]->phone); if (empty($data['phone'])) { $data['phone'] = ""; } $data['name'] = trim(removeLineBreaker($nodes[$i]->name)); if (empty($data['name'])) { $data['name'] = "Anonymous User"; } $data['orderNumber'] = trim(removeLineBreaker($nodes[$i]->ordernumber)); $data['ordernumber'] = trim(removeLineBreaker($nodes[$i]->ordernumber)); $data['filenumber'] = trim(removeLineBreaker($nodes[$i]->filenumber)); $data['cvr'] = trim(removeLineBreaker($nodes[$i]->cvr)); $data['CVR'] = trim(removeLineBreaker($nodes[$i]->cvr)); $data['message'] = removeLineBreaker($nodes[$i]->content); $data['companyName'] = removeLineBreaker($nodes[$i]->companyname); $data['company'] = removeLineBreaker($nodes[$i]->companyname); $data['business_form_id'] = removeLineBreaker($nodes[$i]->business_form_id); $data['activityCode'] = removeLineBreaker($nodes[$i]->activitycode); $data['activityDescription'] = removeLineBreaker($nodes[$i]->activitydescription); $data['useragent'] = removeLineBreaker($nodes[$i]->useragent); $crmsubject1_id = trim(removeLineBreaker($nodes[$i]->crmsubject_id)); if (is_numeric($crmsubject1_id)) { $data['CRM_filter_subject1'] = removeLineBreaker($nodes[$i]->crmsubject_text); $data['crmsubject1_id'] = intval($crmsubject1_id); $data['crmsubject1_text'] = removeLineBreaker($nodes[$i]->crmsubject_text); } else { die("crmsubject1_id is not numeric"); } $crmsubject2_id = trim(removeLineBreaker($nodes[$i]->crmsubject2_id)); if (is_numeric($crmsubject2_id)) { $data['CRM_filter_subject2'] = removeLineBreaker($nodes[$i]->crmsubject2_text); $data['crmsubject2_id'] = intval($crmsubject2_id); $data['crmsubject2_text'] = removeLineBreaker($nodes[$i]->crmsubject2_text); } else { die("crmsubject2_id is not numeric"); } // $data['flags']['bounce'] = true; $user = null; $acct = null; if (!$user && $data['email']) { $user = User::lookupByEmail($data['email']); } if (!$user) { $user_form = UserForm::getUserForm()->getForm($data); if (!($user = User::fromVars($user_form->getClean()))) { echo 'Unable to register account.'; } if (!($acct = ClientAccount::createForUser($user))) { echo 'Internal error. Unable to create new account'; } } $fileContent = $nodes[$i]->files->file; $data['fileContent'] = $fileContent; $tform = TicketForm::objects()->one()->getForm(); $messageField = $tform->getField('message'); $fileField = $messageField->getWidget()->getAttachments(); for ($j = 0; $j < count($fileContent); $j++) { $fileId = $fileContent[$j]->attributes()->id; $file['name'] = $fileContent[$j]->name; $file['type'] = $fileContent[$j]->mime; $file['encoding'] = 'base64'; // $file['cid'] = false; $url = "https://w2l.dk" . $fileContent[$j]->url; // logErrors("A test"); // $url = $fileContent[$j]->url; // $file['data'] = base64_encode(file_get_contents($url)); if ($file['data'] = getFileContentsSSL($url)) { $timestamp = date("Y-m-d_H:i:s"); // if(!file_put_contents(CLIENTINC_DIR.'erstFile/'.$timestamp.$file['name'], $file['data'])) // logErrors("not able to store the file"); try { $storeCRMFile = "/var/www/html/erstFile/" . $timestamp . $file['name']; echo $storeCRMFile; file_put_contents("/var/www/html/erstFile/" . $timestamp . $file['name'], $file['data']); } catch (Exception $e) { logErrors('Caught exception: ', $e->getMessage(), "\n"); } } else { logErrors("The file url is not valid"); } // try { // $file['id'] = $fileField->uploadAttachment($file); // } // catch (FileUploadError $ex) { // $file['error'] = $file['name'] . ': ' . $ex->getMessage(); // echo $file['error']; // } $data['attachments'][] = $file; // echo $file['data']; // echo "<br/>"; } // echo "22222"; // echo json_encode($data); if (Ticket::lookupForContactId($data['crm_contact_id'])) { $api = new TicketApiController(); $api->createTicket($data); echo "ticket has been generated successfully <br/>"; if (DELETE_ERST_SERVICE_QUEUE) { deleteContactsFromQueue($data['crm_contact_id']); } else { logErrors("please go to include/ost-config to make the DELETE_ERST_SERVICE_QUEUE to true"); } } else { logErrors("ticket with id " . $data['crm_contact_id'] . " has already exists"); } } } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; } }
static function create($vars, &$errors, $origin, $autorespond = true, $alertstaff = true) { global $ost, $cfg, $thisclient, $_FILES; // Don't enforce form validation for email $field_filter = function ($type) use($origin) { return function ($f) use($origin, $type) { // Ultimately, only offer validation errors for web for // non-internal fields. For email, no validation can be // performed. For other origins, validate as usual switch (strtolower($origin)) { case 'email': return false; case 'staff': // Required 'Contact Information' fields aren't required // when staff open tickets return $type != 'user' || in_array($f->get('name'), array('name', 'email')); case 'web': return !$f->get('private'); default: return true; } }; }; $reject_ticket = function ($message) use(&$errors) { global $ost; $errors = array('errno' => 403, 'err' => __('This help desk is for use by authorized users only')); $ost->logWarning(_S('Ticket Denied'), $message, false); return 0; }; Signal::send('ticket.create.before', null, $vars); // Create and verify the dynamic form entry for the new ticket $form = TicketForm::getNewInstance(); $form->setSource($vars); // If submitting via email or api, ensure we have a subject and such if (!in_array(strtolower($origin), array('web', 'staff'))) { foreach ($form->getFields() as $field) { $fname = $field->get('name'); if ($fname && isset($vars[$fname]) && !$field->value) { $field->value = $field->parse($vars[$fname]); } } } if (!$form->isValid($field_filter('ticket'))) { $errors += $form->errors(); } /*INICIO Creado por Anthony Parisi 2016-02-01 Con las siguientes lineas de código, se crea el ticket mediante la API.*/ if (!in_array(strtolower($origin), array('web', 'staff'))) { $errors = array(); } /* FIN */ if ($vars['uid']) { $user = User::lookup($vars['uid']); } $id = 0; $fields = array(); $fields['message'] = array('type' => '*', 'required' => 1, 'error' => __('Message content is required')); switch (strtolower($origin)) { case 'web': $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Select a help topic')); break; case 'staff': $fields['deptId'] = array('type' => 'int', 'required' => 0, 'error' => __('Department selection is required')); $fields['topicId'] = array('type' => 'int', 'required' => 1, 'error' => __('Help topic selection is required')); $fields['duedate'] = array('type' => 'date', 'required' => 0, 'error' => __('Invalid date format - must be MM/DD/YY')); case 'api': $fields['source'] = array('type' => 'string', 'required' => 1, 'error' => __('Indicate ticket source')); break; case 'email': $fields['emailId'] = array('type' => 'int', 'required' => 1, 'error' => __('Unknown system email')); break; default: # TODO: Return error message $errors['err'] = $errors['origin'] = __('Invalid ticket origin given'); } if (!Validator::process($fields, $vars, $errors) && !$errors['err']) { $errors['err'] = __('Missing or invalid data - check the errors and try again'); } //Make sure the due date is valid if ($vars['duedate']) { if (!$vars['time'] || strpos($vars['time'], ':') === false) { $errors['time'] = __('Select a time from the list'); } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) === false) { $errors['duedate'] = __('Invalid due date'); } elseif (strtotime($vars['duedate'] . ' ' . $vars['time']) <= time()) { $errors['duedate'] = __('Due date must be in the future'); } } if (!$errors) { # Perform ticket filter actions on the new ticket arguments $__form = null; if ($vars['topicId']) { if (($__topic = Topic::lookup($vars['topicId'])) && ($__form = $__topic->getForm())) { $__form = $__form->instanciate(); $__form->setSource($vars); } } try { $vars = self::filterTicketData($origin, $vars, array($form, $__form), $user); } catch (RejectedException $ex) { return $reject_ticket(sprintf(_S('Ticket rejected (%s) by filter "%s"'), $ex->vars['email'], $ex->getRejectingFilter()->getName())); } //Make sure the open ticket limit hasn't been reached. (LOOP CONTROL) if ($cfg->getMaxOpenTickets() > 0 && strcasecmp($origin, 'staff') && ($_user = TicketUser::lookupByEmail($vars['email'])) && ($openTickets = $_user->getNumOpenTickets()) && $openTickets >= $cfg->getMaxOpenTickets()) { $errors = array('err' => __("You've reached the maximum open tickets allowed.")); $ost->logWarning(sprintf(_S('Ticket denied - %s'), $vars['email']), sprintf(_S('Max open tickets (%1$d) reached for %2$s'), $cfg->getMaxOpenTickets(), $vars['email']), false); return 0; } // Allow vars to be changed in ticket filter and applied to the user // account created or detected if (!$user && $vars['email']) { $user = User::lookupByEmail($vars['email']); } if (!$user) { // Reject emails if not from registered clients (if // configured) if (strcasecmp($origin, 'email') === 0 && !$cfg->acceptUnregisteredEmail()) { list($mailbox, $domain) = explode('@', $vars['email'], 2); // Users not yet created but linked to an organization // are still acceptable if (!Organization::forDomain($domain)) { return $reject_ticket(sprintf(_S('Ticket rejected (%s) (unregistered client)'), $vars['email'])); } } $user_form = UserForm::getUserForm()->getForm($vars); if (!$user_form->isValid($field_filter('user')) || !($user = User::fromVars($user_form->getClean()))) { $errors['user'] = __('Incomplete client information'); } } } if ($vars['topicId']) { if ($topic = Topic::lookup($vars['topicId'])) { if ($topic_form = $topic->getForm()) { $TF = $topic_form->getForm($vars); $topic_form = $topic_form->instanciate(); $topic_form->setSource($vars); if (!$TF->isValid($field_filter('topic'))) { $errors = array_merge($errors, $TF->errors()); } } } else { $errors['topicId'] = 'Invalid help topic selected'; } } // Any error above is fatal. if ($errors) { return 0; } Signal::send('ticket.create.validated', null, $vars); # Some things will need to be unpacked back into the scope of this # function if (isset($vars['autorespond'])) { $autorespond = $vars['autorespond']; } # Apply filter-specific priority if ($vars['priorityId']) { $form->setAnswer('priority', null, $vars['priorityId']); } // If the filter specifies a help topic which has a form associated, // and there was previously either no help topic set or the help // topic did not have a form, there's no need to add it now as (1) // validation is closed, (2) there may be a form already associated // and filled out from the original help topic, and (3) staff // members can always add more forms now // OK...just do it. $statusId = $vars['statusId']; $deptId = $vars['deptId']; //pre-selected Dept if any. $source = ucfirst($vars['source']); // Apply email settings for emailed tickets. Email settings should // trump help topic settins if the email has an associated help // topic if ($vars['emailId'] && ($email = Email::lookup($vars['emailId']))) { $deptId = $deptId ?: $email->getDeptId(); $priority = $form->getAnswer('priority'); if (!$priority || !$priority->getIdValue()) { $form->setAnswer('priority', null, $email->getPriorityId()); } if ($autorespond) { $autorespond = $email->autoRespond(); } if (!isset($topic) && ($T = $email->getTopic()) && $T->isActive()) { $topic = $T; } $email = null; $source = 'Email'; } if (!isset($topic)) { // This may return NULL, no big deal $topic = $cfg->getDefaultTopic(); } // Intenal mapping magic...see if we need to override anything if (isset($topic)) { $deptId = $deptId ?: $topic->getDeptId(); $statusId = $statusId ?: $topic->getStatusId(); $priority = $form->getAnswer('priority'); if (!$priority || !$priority->getIdValue()) { $form->setAnswer('priority', null, $topic->getPriorityId()); } if ($autorespond) { $autorespond = $topic->autoRespond(); } //Auto assignment. if (!isset($vars['staffId']) && $topic->getStaffId()) { $vars['staffId'] = $topic->getStaffId(); } elseif (!isset($vars['teamId']) && $topic->getTeamId()) { $vars['teamId'] = $topic->getTeamId(); } //set default sla. if (isset($vars['slaId'])) { $vars['slaId'] = $vars['slaId'] ?: $cfg->getDefaultSLAId(); } elseif ($topic && $topic->getSLAId()) { $vars['slaId'] = $topic->getSLAId(); } } // Auto assignment to organization account manager if (($org = $user->getOrganization()) && $org->autoAssignAccountManager() && ($code = $org->getAccountManagerId())) { if (!isset($vars['staffId']) && $code[0] == 's') { $vars['staffId'] = substr($code, 1); } elseif (!isset($vars['teamId']) && $code[0] == 't') { $vars['teamId'] = substr($code, 1); } } // Last minute checks $priority = $form->getAnswer('priority'); if (!$priority || !$priority->getIdValue()) { $form->setAnswer('priority', null, $cfg->getDefaultPriorityId()); } $deptId = $deptId ?: $cfg->getDefaultDeptId(); $statusId = $statusId ?: $cfg->getDefaultTicketStatusId(); $topicId = isset($topic) ? $topic->getId() : 0; $ipaddress = $vars['ip'] ?: $_SERVER['REMOTE_ADDR']; $source = $source ?: 'Web'; //We are ready son...hold on to the rails. $number = $topic ? $topic->getNewTicketNumber() : $cfg->getNewTicketNumber(); $sql = 'INSERT INTO ' . TICKET_TABLE . ' SET created=NOW() ' . ' ,lastmessage= NOW()' . ' ,user_id=' . db_input($user->getId()) . ' ,`number`=' . db_input($number) . ' ,dept_id=' . db_input($deptId) . ' ,topic_id=' . db_input($topicId) . ' ,ip_address=' . db_input($ipaddress) . ' ,source=' . db_input($source); if (isset($vars['emailId']) && $vars['emailId']) { $sql .= ', email_id=' . db_input($vars['emailId']); } //Make sure the origin is staff - avoid firebug hack! if ($vars['duedate'] && !strcasecmp($origin, 'staff')) { $sql .= ' ,duedate=' . db_input(date('Y-m-d G:i', Misc::dbtime($vars['duedate'] . ' ' . $vars['time']))); } if (!db_query($sql) || !($id = db_insert_id()) || !($ticket = Ticket::lookup($id))) { return null; } /* -------------------- POST CREATE ------------------------ */ // Save the (common) dynamic form $form->setTicketId($id); $form->save(); // Save the form data from the help-topic form, if any if ($topic_form) { $topic_form->setTicketId($id); $topic_form->save(); } $ticket->loadDynamicData(); $dept = $ticket->getDept(); // Add organizational collaborators if ($org && $org->autoAddCollabs()) { $pris = $org->autoAddPrimaryContactsAsCollabs(); $members = $org->autoAddMembersAsCollabs(); $settings = array('isactive' => true); $collabs = array(); foreach ($org->allMembers() as $u) { if ($members || $pris && $u->isPrimaryContact()) { if ($c = $ticket->addCollaborator($u, $settings, $errors)) { $collabs[] = (string) $c; } } } //TODO: Can collaborators add others? if ($collabs) { //TODO: Change EndUser to name of user. $ticket->logNote(sprintf(_S('Collaborators for %s organization added'), $org->getName()), implode("<br>", $collabs), $org->getName(), false); } } //post the message. $vars['title'] = $vars['subject']; //Use the initial subject as title of the post. $vars['userId'] = $ticket->getUserId(); $message = $ticket->postMessage($vars, $origin, false); // Configure service-level-agreement for this ticket $ticket->selectSLAId($vars['slaId']); // Assign ticket to staff or team (new ticket by staff) if ($vars['assignId']) { $ticket->assign($vars['assignId'], $vars['note']); } else { // Auto assign staff or team - auto assignment based on filter // rules. Both team and staff can be assigned if ($vars['staffId']) { $ticket->assignToStaff($vars['staffId'], _S('Auto Assignment')); } if ($vars['teamId']) { // No team alert if also assigned to an individual agent $ticket->assignToTeam($vars['teamId'], _S('Auto Assignment'), !$vars['staffId']); } } // Apply requested status — this should be done AFTER assignment, // because if it is requested to be closed, it should not cause the // ticket to be reopened for assignment. if ($statusId) { $ticket->setStatus($statusId, false, false); } /********** double check auto-response ************/ //Override auto responder if the FROM email is one of the internal emails...loop control. if ($autorespond && Email::getIdByEmail($ticket->getEmail())) { $autorespond = false; } # Messages that are clearly auto-responses from email systems should # not have a return 'ping' message if (isset($vars['flags']) && $vars['flags']['bounce']) { $autorespond = false; } if ($autorespond && $message->isAutoReply()) { $autorespond = false; } //post canned auto-response IF any (disables new ticket auto-response). if ($vars['cannedResponseId'] && $ticket->postCannedReply($vars['cannedResponseId'], $message->getId(), $autorespond)) { $ticket->markUnAnswered(); //Leave the ticket as unanswred. $autorespond = false; } //Check department's auto response settings // XXX: Dept. setting doesn't affect canned responses. if ($autorespond && $dept && !$dept->autoRespONNewTicket()) { $autorespond = false; } //Don't send alerts to staff when the message is a bounce // this is necessary to avoid possible loop (especially on new ticket) if ($alertstaff && $message->isBounce()) { $alertstaff = false; } /***** See if we need to send some alerts ****/ $ticket->onNewTicket($message, $autorespond, $alertstaff); /************ check if the user JUST reached the max. open tickets limit **********/ if ($cfg->getMaxOpenTickets() > 0 && ($user = $ticket->getOwner()) && $user->getNumOpenTickets() == $cfg->getMaxOpenTickets()) { $ticket->onOpenLimit($autorespond && strcasecmp($origin, 'staff')); } /* Start tracking ticket lifecycle events */ $ticket->logEvent('created'); // Fire post-create signal (for extra email sending, searching) Signal::send('model.created', $ticket); /*INICIO Anthony Parisi 2016-02-05 Con las siguientes lineas de código, se actualizan los campos de Detalle de su Solicitud en las tablas descritas en la Sentencia SQL*/ if (!in_array(strtolower($origin), array('web', 'staff'))) { //echo "<pre>"; //var_dump($vars); //die($vars['valores']); foreach ($ticket as $key => $value) { if ($key == "id") { $ticket_idAPI = $value; } if ($key == "last_message") { $last_message = $value; $datos = explode("\n", $last_message); $nombre = $vars['name']; $correo = $vars['email']; $telefono = $vars['phone']; $valores = $vars['valores']; $adicional = explode("%%", $valores); //die($adicional[4]); /*$nombre = ucwords(strtolower(substr($datos[0], 20, strlen($datos[0])-21))); $correo = strtolower(substr($datos[1], 20, strlen($datos[1])-21)); $telefono = substr($datos[2], 22, strlen($datos[2])-23); $i = 5; $mensaje = ""; while(strpos($datos[$i], "------------------------------------------------------") === false){ $mensaje .= $datos[$i]; $i++; } for($i=5;$i < (count($datos)-6);$i++){ if(strpos($datos[$i], "TIPO DE PASAJE: ") > -1) $pasaje = substr($datos[$i], 28, strlen($datos[$i])-29); elseif(strpos($datos[$i], "CIUDAD DE ORIGEN: ") > -1) $origen = substr($datos[$i], 18, strlen($datos[$i])-19); elseif(strpos($datos[$i], "CIUDAD DE DESTINO: ") > -1) $destino = substr($datos[$i], 21, strlen($datos[$i])-22); elseif(strpos($datos[$i], "FECHA DE SALIDA: ") > -1) $salida = substr($datos[$i], 17, strlen($datos[$i])-18); elseif(strpos($datos[$i], "FECHA DE REGRESO: ") > -1) $regreso = substr($datos[$i], 20, strlen($datos[$i])-21); elseif(strpos($datos[$i], "CLASE: ") > -1) $clase = substr($datos[$i], 19, strlen($datos[$i])-20); elseif(strpos($datos[$i], "AEROL") > -1) $aerolinea = substr($datos[$i], 14, strlen($datos[$i])-15); } $adultos = substr($datos[count($datos)-5], 9, strlen($datos[count($datos)-5])-10); $mayores = substr($datos[count($datos)-4], 11, strlen($datos[count($datos)-4])-12); $ninos = substr($datos[count($datos)-3], 9, strlen($datos[count($datos)-3])-10); $bebes = substr($datos[count($datos)-2], 8, strlen($datos[count($datos)-2])-9);*/ } } $detail = '{"88":"Cotizacion PopPup"}'; $mysqli = new mysqli(DBHOST, DBUSER, DBPASS, DBNAME); $mysqli->query("UPDATE `ost_form_entry_values` SET `value` = '{$detail}' WHERE field_id = '20' AND `entry_id` = (SELECT id FROM ost_form_entry WHERE object_id = '{$ticket_idAPI}' AND object_type = 'T');"); $mysqli->query("INSERT INTO `ost_ticket__cdata` SET `subject`='88', `ticket_id`= '{$ticket_idAPI}' ON DUPLICATE KEY UPDATE `subject`='88';"); $sqlUser = $mysqli->query("SELECT id FROM ost_user WHERE id = '" . $user->getId() . "' AND `org_id` = 30 LIMIT 1;"); $rowUser = mysqli_num_rows($sqlUser); if ($rowUser <= 0) { $mysqli->query("UPDATE ost_user SET `org_id` = 30, `updated` = NOW() WHERE id = " . $user->getId() . " LIMIT 1;"); } $mysqli->query("INSERT INTO \n `ost_cotizaciones` (\n `ticket_id`, \n `nombre`, \n `correo`, \n `telefono`, \n `mensaje`, \n `tipo_vuelo`, \n `origen`, \n `destino`, \n `salida`, \n `regreso`, \n `clase`, \n `aerolinea`, \n `adultos`, \n `mayores`, \n `ninos`, \n `bebe`) \n VALUES (\n '{$ticket_idAPI}', \n '{$nombre}', \n '{$correo}', \n '{$telefono}', \n '{$adicional['0']}', \n '{$adicional['1']}', \n '{$adicional['2']}', \n '{$adicional['3']}', \n '{$adicional['4']}', \n '{$adicional['5']}', \n '{$adicional['6']}', \n '{$adicional['7']}', \n '{$adicional['8']}', \n '{$adicional['9']}', \n '{$adicional['10']}', \n '{$adicional['11']}');"); } /* FIN */ /* Phew! ... time for tea (KETEPA) */ return $ticket; }
static function importCsv($stream, $defaults = array()) { //Read the header (if any) $headers = array('name' => __('Full Name'), 'email' => __('Email Address')); $uform = UserForm::getUserForm(); $all_fields = $uform->getFields(); $named_fields = array(); $has_header = true; foreach ($all_fields as $f) { if ($f->get('name')) { $named_fields[] = $f; } } if (!($data = fgetcsv($stream, 1000, ","))) { return __('Whoops. Perhaps you meant to send some CSV records'); } if (Validator::is_email($data[1])) { $has_header = false; // We don't have an header! } else { $headers = array(); foreach ($data as $h) { $found = false; foreach ($all_fields as $f) { if (in_array(mb_strtolower($h), array(mb_strtolower($f->get('name')), mb_strtolower($f->get('label'))))) { $found = true; if (!$f->get('name')) { return sprintf(__('%s: Field must have `variable` set to be imported'), $h); } $headers[$f->get('name')] = $f->get('label'); break; } } if (!$found) { $has_header = false; if (count($data) == count($named_fields)) { // Number of fields in the user form matches the number // of fields in the data. Assume things line up $headers = array(); foreach ($named_fields as $f) { $headers[$f->get('name')] = $f->get('label'); } break; } else { return sprintf(__('%s: Unable to map header to a user field'), $h); } } } } // 'name' and 'email' MUST be in the headers if (!isset($headers['name']) || !isset($headers['email'])) { return __('CSV file must include `name` and `email` columns'); } if (!$has_header) { fseek($stream, 0); } $users = $fields = $keys = array(); foreach ($headers as $h => $label) { if (!($f = $uform->getField($h))) { continue; } $name = $keys[] = $f->get('name'); $fields[$name] = $f->getImpl(); } // Add default fields (org_id, etc). foreach ($defaults as $key => $val) { // Don't apply defaults which are also being imported if (isset($header[$key])) { unset($defaults[$key]); } $keys[] = $key; } while (($data = fgetcsv($stream, 1000, ",")) !== false) { if (count($data) == 1 && $data[0] == null) { // Skip empty rows continue; } elseif (count($data) != count($headers)) { return sprintf(__('Bad data. Expected: %s'), implode(', ', $headers)); } // Validate according to field configuration $i = 0; foreach ($headers as $h => $label) { $f = $fields[$h]; $T = $f->parse($data[$i]); if ($f->validateEntry($T) && $f->errors()) { return sprintf(__('%1$s: Invalid data: %2$s'), $label, implode(', ', $f->errors())); } // Convert to database format $data[$i] = $f->to_database($T); $i++; } // Add default fields foreach ($defaults as $key => $val) { $data[] = $val; } $users[] = $data; } foreach ($users as $u) { $vars = array_combine($keys, $u); if (!static::fromVars($vars)) { return sprintf(__('Unable to import user: %s'), print_r($vars, true)); } } return count($users); }