function commitCandidate() { $conf = $_POST["conf"]; $candidates = new Candidates(); if ($conf["candidateid"]) { $candidates->update('id=' . $conf["candidateid"], $conf); } else { $conf["candidateid"] = $candidates->create($conf); } updateEvents($conf); if ($conf["note"]) { createCandidateNote($conf["candidateid"], $conf["note"]); } goHere("index.php?mode=maxine/index&action=candidatelist"); }
public function onApplyToJobOrder($siteID, $candidateID = false) { $jobOrders = new JobOrders($siteID); $careerPortalSettings = new CareerPortalSettings($siteID); if (!$this->isRequiredIDValid('ID', $_POST)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.'); return; } $jobOrderID = $_POST['ID']; $jobOrderData = $jobOrders->get($jobOrderID); if (!isset($jobOrderData['public']) || $jobOrderData['public'] == 0) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'The specified job order could not be found.'); return; } $lastName = $this->getTrimmedInput('lastName', $_POST); $middleName = $this->getTrimmedInput('middleName', $_POST); $firstName = $this->getTrimmedInput('firstName', $_POST); $email = $this->getTrimmedInput('email', $_POST); $email2 = $this->getTrimmedInput('email2', $_POST); $address = $this->getTrimmedInput('address', $_POST); $city = $this->getTrimmedInput('city', $_POST); $state = $this->getTrimmedInput('state', $_POST); $zip = $this->getTrimmedInput('zip', $_POST); $source = $this->getTrimmedInput('source', $_POST); $phone = $this->getTrimmedInput('phone', $_POST); $phoneHome = $this->getTrimmedInput('phoneHome', $_POST); $phoneCell = $this->getTrimmedInput('phoneCell', $_POST); $bestTimeToCall = $this->getTrimmedInput('bestTimeToCall', $_POST); $keySkills = $this->getTrimmedInput('keySkills', $_POST); $extraNotes = $this->getTrimmedInput('extraNotes', $_POST); $employer = $this->getTrimmedInput('employer', $_POST); $gender = $this->getTrimmedInput('eeogender', $_POST); $race = $this->getTrimmedInput('eeorace', $_POST); $veteran = $this->getTrimmedInput('eeoveteran', $_POST); $disability = $this->getTrimmedInput('eeodisability', $_POST); if (empty($firstName)) { CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'First Name is a required field - please have your administrator edit your templates to include the first name field.'); } if (empty($lastName)) { CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'Last Name is a required field - please have your administrator edit your templates to include the last name field.'); } if (empty($email)) { CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'E-Mail address is a required field - please have your administrator edit your templates to include the email field.'); } if (empty($source)) { $source = 'Online Careers Website'; } $users = new Users(CATS_ADMIN_SITE); $automatedUser = $users->getAutomatedUser(); /* Find if another user with same e-mail exists. If so, update the user * to contain the new information. */ $candidates = new Candidates($siteID); /** * Save basic information in a cookie in case the site is using registration to * process repeated postings, etc. */ $fields = array('firstName', 'lastName', 'email', 'address', 'city', 'state', 'zip', 'phone', 'phoneHome', 'phoneCell' ); $storedVal = ''; foreach ($fields as $field) { eval('$tmp = sprintf(\'"%s"="%s"\', $field, urlencode($' . $field . '));'); $storedVal .= $tmp; } // Store their information for an hour only (about 1 session), if they return they can log in again and // specify "remember me" which stores it for 2 weeks. @setcookie($this->getCareerPortalCookieName($siteID), $storedVal, time()+60*60); if ($candidateID !== false) { $candidate = $candidates->get($candidateID); // Candidate exists and registered. Update their profile with new values (if provided) $candidates->update( $candidateID, $candidate['isActive'] ? true : false, $firstName, $middleName, $lastName, $email, $email2, $phoneHome, $phoneCell, $phone, $address, $city, $state, $zip, $source, $keySkills, '', $employer, '', '', '', $candidate['notes'], '', $bestTimeToCall, $automatedUser['userID'], $automatedUser['userID'], $gender, $race, $veteran, $disability ); /* Update extra feilds */ $candidates->extraFields->setValuesOnEdit($candidateID); } else { // Lookup the candidate by e-mail, use that candidate instead if found (but don't update profile) $candidateID = $candidates->getIDByEmail($email); } if ($candidateID === false || $candidateID < 0) { /* New candidate. */ $candidateID = $candidates->add( $firstName, $middleName, $lastName, $email, $email2, $phoneHome, $phoneCell, $phone, $address, $city, $state, $zip, $source, $keySkills, '', $employer, '', '', '', 'Candidate submitted these notes with first application: ' . "\n\n" . $extraNotes, '', $bestTimeToCall, $automatedUser['userID'], $automatedUser['userID'], $gender, $race, $veteran, $disability ); /* Update extra fields. */ $candidates->extraFields->setValuesOnEdit($candidateID); } // If the candidate was added and a questionnaire exists for the job order if ($candidateID > 0 && ($questionnaireID = $jobOrderData['questionnaireID'])) { $questionnaireLib = new Questionnaire($siteID); // Perform any actions specified by the questionnaire $questionnaireLib->doActions($questionnaireID, $candidateID, $_POST); } $fileUploaded = false; /* Upload resume (no questionnaire) */ if (isset($_FILES['file']) && !empty($_FILES['file']['name'])) { $attachmentCreator = new AttachmentCreator($siteID); $attachmentCreator->createFromUpload( DATA_ITEM_CANDIDATE, $candidateID, 'file', false, true ); if ($attachmentCreator->isError()) { CommonErrors::fatal(COMMONERROR_FILEERROR, $this, $attachmentCreator->getError()); return; } $duplicatesOccurred = $attachmentCreator->duplicatesOccurred(); $isTextExtractionError = $attachmentCreator->isTextExtractionError(); $textExtractionErrorMessage = $attachmentCreator->getTextExtractionError(); // FIXME: Show parse errors! $fileUploaded = true; $resumePath = $attachmentCreator->getNewFilePath(); } /* Upload resume (with questionnaire) */ else if (isset($_POST['file']) && !empty($_POST['file'])) { $resumePath = ''; $newFilePath = FileUtility::getUploadFilePath($siteID, 'careerportaladd', $_POST['file']); if ($newFilePath !== false) { $attachmentCreator = new AttachmentCreator($siteID); $attachmentCreator->createFromFile( DATA_ITEM_CANDIDATE, $candidateID, $newFilePath, false, '', true, true ); if ($attachmentCreator->isError()) { CommonErrors::fatal(COMMONERROR_FILEERROR, $this, $attachmentCreator->getError()); return; } $duplicatesOccurred = $attachmentCreator->duplicatesOccurred(); $isTextExtractionError = $attachmentCreator->isTextExtractionError(); $textExtractionErrorMessage = $attachmentCreator->getTextExtractionError(); // FIXME: Show parse errors! $fileUploaded = true; $resumePath = $attachmentCreator->getNewFilePath(); } } $pipelines = new Pipelines($siteID); $activityEntries = new ActivityEntries($siteID); /* Is the candidate already in the pipeline for this job order? */ $rs = $pipelines->get($candidateID, $jobOrderID); if (count($rs) == 0) { /* Attempt to add the candidate to the pipeline. */ if (!$pipelines->add($candidateID, $jobOrderID)) { CommonErrors::fatal(COMMONERROR_RECORDERROR, $this, 'Failed to add candidate to pipeline.'); } // FIXME: For some reason, pipeline entries like to disappear between // the above add() and this get(). WTF? $rs = $pipelines->get($candidateID, $jobOrderID); if (isset($rs['candidateJobOrderID'])) $pipelines->updateRatingValue($rs['candidateJobOrderID'], -1); $newApplication = true; } else { $newApplication = false; } /* Build activity note. */ if (!$newApplication) { $activityNote = 'User re-applied through candidate portal'; } else { $activityNote = 'User applied through candidate portal'; } if ($fileUploaded) { if (!$duplicatesOccurred) { $activityNote .= ' <span style="font-weight: bold;">and' . ' attached a new resume (<a href="' . $resumePath . '">Download</a>)</span>'; } else { $activityNote .= ' and attached an existing resume (<a href="' . $resumePath . '">Download</a>)'; } } if (!empty($extraNotes)) { $activityNote .= '; added these notes: ' . $extraNotes; } /* Add the activity note. */ $activityID = $activityEntries->add( $candidateID, DATA_ITEM_CANDIDATE, ACTIVITY_OTHER, $activityNote, $automatedUser['userID'], $jobOrderID ); /* Send an E-Mail describing what happened. */ $emailTemplates = new EmailTemplates($siteID); $candidatesEmailTemplateRS = $emailTemplates->getByTag( 'EMAIL_TEMPLATE_CANDIDATEAPPLY' ); if (!isset($candidatesEmailTemplateRS['textReplaced']) || empty($candidatesEmailTemplateRS['textReplaced']) || $candidatesEmailTemplateRS['disabled'] == 1) { $candidatesEmailTemplate = ''; } else { $candidatesEmailTemplate = $candidatesEmailTemplateRS['textReplaced']; } /* Replace e-mail template variables. */ /* E-Mail #1 - to candidate */ $stringsToFind = array( '%CANDFIRSTNAME%', '%CANDFULLNAME%', '%JBODOWNER%', '%JBODTITLE%', '%JBODCLIENT%' ); $replacementStrings = array( $firstName, $firstName . ' ' . $lastName, $jobOrderData['ownerFullName'], $jobOrderData['title'], $jobOrderData['companyName'] //'<a href="http://' . $_SERVER['HTTP_HOST'] . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')) . '?m=candidates&a=show&candidateID=' . $candidateID . '">'. // 'http://' . $_SERVER['HTTP_HOST'] . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')) . '?m=candidates&a=show&candidateID=' . $candidateID . '</a>' ); $candidatesEmailTemplate = str_replace( $stringsToFind, $replacementStrings, $candidatesEmailTemplate ); $emailContents = $candidatesEmailTemplate; if (!empty($emailContents)) { if(!$candidates->isLoaded()) { $candidates->load($candidateID); } $candidates->sendEMail( $automatedUser['userID'], $email, CAREERS_CANDIDATEAPPLY_SUBJECT, $emailContents ); } /* E-Mail #2 - to owner */ $candidatesEmailTemplateRS = $emailTemplates->getByTag( 'EMAIL_TEMPLATE_CANDIDATEPORTALNEW' ); if (!isset($candidatesEmailTemplateRS['textReplaced']) || empty($candidatesEmailTemplateRS['textReplaced']) || $candidatesEmailTemplateRS['disabled'] == 1) { $candidatesEmailTemplate = ''; } else { $candidatesEmailTemplate = $candidatesEmailTemplateRS['textReplaced']; } // FIXME: This will break if 'http' is elsewhere in the URL. $uri = str_replace('employment', '', $_SERVER['REQUEST_URI']); $uri = str_replace('http://', 'http', $uri); $uri = str_replace('//', '/', $uri); $uri = str_replace('http', 'http://', $uri); $uri = str_replace('/careers', '', $uri); /* Replace e-mail template variables. */ $stringsToFind = array( '%CANDFIRSTNAME%', '%CANDFULLNAME%', '%JBODOWNER%', '%CANDOWNER%', // Because the candidate was just added, we assume '%JBODTITLE%', // the candidate owner = job order owner. '%JBODCLIENT%', '%CANDCATSURL%', '%JBODID%', '%JBODCATSURL%' ); $replacementStrings = array( $firstName, $firstName . ' ' . $lastName, $jobOrderData['ownerFullName'], $jobOrderData['ownerFullName'], $jobOrderData['title'], $jobOrderData['companyName'], '<a href="http://' . $_SERVER['HTTP_HOST'] . substr($uri, 0, strpos($uri, '?')) . '?m=candidates&a=show&candidateID=' . $candidateID . '">'. 'http://' . $_SERVER['HTTP_HOST'] . substr($uri, 0, strpos($uri, '?')) . '?m=candidates&a=show&candidateID=' . $candidateID . '</a>', $jobOrderData['jobOrderID'], '<a href="http://' . $_SERVER['HTTP_HOST'] . substr($uri, 0, strpos($uri, '?')) . '?m=joborders&a=show&jobOrderID=' . $jobOrderData['jobOrderID'] . '">'. 'http://' . $_SERVER['HTTP_HOST'] . substr($uri, 0, strpos($uri, '?')) . '?m=joborders&a=show&jobOrderID=' . $jobOrderData['jobOrderID'] . '</a>', ); $candidatesEmailTemplate = str_replace( $stringsToFind, $replacementStrings, $candidatesEmailTemplate ); $emailContents = $candidatesEmailTemplate; if (!empty($emailContents)) { if(!$jobOrders->isLoaded()) { $jobOrders->load($jobOrderID); } $jobOrders->sendEmail( $automatedUser['userID'], $jobOrderData['owner_email'], CAREERS_OWNERAPPLY_SUBJECT, $emailContents ); if ($jobOrderData['owner_email'] != $jobOrderData['recruiter_email']) { $jobOrders->sendEmail( $automatedUser['userID'], $jobOrderData['recruiter_email'], CAREERS_OWNERAPPLY_SUBJECT, $emailContents ); } } }
/** * It is assumed the applicant has completed a questionnaire using the Career * Portal and has been added to CATS as a candidate. Based on their responses * to the questionnaire, perform any actions provided by the questionnaire * based on their responses (which should be in post provided by postData); * * @param ID of the attached questionnaire ID * @param integer candidate_id from candidate table * @param array $_POST equivilent data */ public function doActions($questionnaireID, $candidateID, $postData) { // Get the candidate (if exists) $candidate = new Candidates($this->_siteID); if (!count($cData = $candidate->get($candidateID))) { return false; } // Default values (which may be changed by actions) $source = $notes = $keySkills = ''; $isHot = $canRelocate = 0; $isActive = 1; $qData = $this->get($questionnaireID); if (is_array($qData) && !empty($qData)) { if (!count($questions = $this->getQuestions($qData['questionnaireID']))) { return false; } foreach ($questions as $question) { $answerText = ''; switch ($question['questionType']) { case QUESTIONNAIRE_QUESTION_TYPE_CHECKBOX: // Multiple answers possible $answerIDs = array(); foreach ($question['answers'] as $answer) { $index = sprintf('questionnaire%dQuestion%dAnswer%d', $qData['questionnaireID'], $question['questionID'], $answer['answerID']); if (isset($postData[$index])) { $answerIDs[] = $answer['answerID']; } } break; case QUESTIONNAIRE_QUESTION_TYPE_RADIO: case QUESTIONNAIRE_QUESTION_TYPE_SELECT: // One answer $index = sprintf('questionnaire%dQuestion%d', $qData['questionnaireID'], $question['questionID']); $answerIDs = array(isset($postData[$index]) ? intval($postData[$index]) : false); break; case QUESTIONNAIRE_QUESTION_TYPE_TEXT: default: // text answer $index = sprintf('questionnaire%dQuestion%d', $qData['questionnaireID'], $question['questionID']); $answerText = substr(trim(isset($postData[$index]) ? $postData[$index] : ''), 0, 255); $answerIDs = array(); break; } foreach ($answerIDs as $answerID) { foreach ($question['answers'] as $answer) { if ($answer['answerID'] == $answerID) { if ($answerText != '') { $answerText .= ', '; } $answerText .= $answer['answerText']; // Perform any actions (if there are any) if (strlen($answer['actionSource'])) { if (strlen($source)) { $source .= ', '; } $source .= $answer['actionSource']; } if (strlen($answer['actionNotes'])) { if (strlen($notes)) { $notes .= ', '; } $notes .= $answer['actionNotes']; } if (strlen($answer['actionKeySkills'])) { if (strlen($keySkills)) { $keySkills .= ', '; } $keySkills .= $answer['actionKeySkills']; } if ($answer['actionIsHot']) { $isHot = 1; } if (!$answer['actionIsActive']) { $isActive = 0; } if ($answer['actionCanRelocate']) { $canRelocate = 1; } } } } // Log textual response (not multiple choice) // Save this candidates response $this->log($candidateID, $qData['title'], $qData['description'], $question['questionText'], $answerText); } } return $candidate->update($cData['candidateID'], $isActive ? true : false, $cData['firstName'], $cData['middleName'], $cData['lastName'], $cData['email1'], $cData['email2'], $cData['phoneHome'], $cData['phoneCell'], $cData['phoneWork'], $cData['address'], $cData['city'], $cData['state'], $cData['zip'], $source, $keySkills, $cData['dateAvailable'], $cData['currentEmployer'], $canRelocate ? true : false, $cData['currentPay'], $cData['desiredPay'], $notes, $cData['webSite'], $cData['bestTimeToCall'], $cData['owner'], $isHot ? true : false, $cData['email1'], $cData['email1']); }
private function onEdit() { if ($this->_accessLevel < ACCESS_LEVEL_EDIT) { CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.'); } $candidates = new Candidates($this->_siteID); /* Bail out if we don't have a valid candidate ID. */ if (!$this->isRequiredIDValid('candidateID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); return; } /* Bail out if we don't have a valid owner user ID. */ if (!$this->isOptionalIDValid('owner', $_POST)) { CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid owner user ID.'); } /* Bail out if we received an invalid availability date; if not, go * ahead and convert the date to MySQL format. */ $dateAvailable = $this->getTrimmedInput('dateAvailable', $_POST); if (!empty($dateAvailable)) { if (!DateUtility::validate('-', $dateAvailable, DATE_FORMAT_MMDDYY)) { CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid availability date.'); } /* Convert start_date to something MySQL can understand. */ $dateAvailable = DateUtility::convert('-', $dateAvailable, DATE_FORMAT_MMDDYY, DATE_FORMAT_YYYYMMDD); } $formattedPhoneHome = StringUtility::extractPhoneNumber($this->getTrimmedInput('phoneHome', $_POST)); if (!empty($formattedPhoneHome)) { $phoneHome = $formattedPhoneHome; } else { $phoneHome = $this->getTrimmedInput('phoneHome', $_POST); } $formattedPhoneCell = StringUtility::extractPhoneNumber($this->getTrimmedInput('phoneCell', $_POST)); if (!empty($formattedPhoneCell)) { $phoneCell = $formattedPhoneCell; } else { $phoneCell = $this->getTrimmedInput('phoneCell', $_POST); } $formattedPhoneWork = StringUtility::extractPhoneNumber($this->getTrimmedInput('phoneWork', $_POST)); if (!empty($formattedPhoneWork)) { $phoneWork = $formattedPhoneWork; } else { $phoneWork = $this->getTrimmedInput('phoneWork', $_POST); } $candidateID = $_POST['candidateID']; $owner = $_POST['owner']; /* Can Relocate */ $canRelocate = $this->isChecked('canRelocate', $_POST); $isHot = $this->isChecked('isHot', $_POST); /* Change ownership email? */ if ($this->isChecked('ownershipChange', $_POST) && $owner > 0) { $candidateDetails = $candidates->get($candidateID); $users = new Users($this->_siteID); $ownerDetails = $users->get($owner); if (!empty($ownerDetails)) { $emailAddress = $ownerDetails['email']; /* Get the change status email template. */ $emailTemplates = new EmailTemplates($this->_siteID); $statusChangeTemplateRS = $emailTemplates->getByTag('EMAIL_TEMPLATE_OWNERSHIPASSIGNCANDIDATE'); if (empty($statusChangeTemplateRS) || empty($statusChangeTemplateRS['textReplaced'])) { $statusChangeTemplate = ''; } else { $statusChangeTemplate = $statusChangeTemplateRS['textReplaced']; } /* Replace e-mail template variables. */ $stringsToFind = array('%CANDOWNER%', '%CANDFIRSTNAME%', '%CANDFULLNAME%', '%CANDCATSURL%'); $replacementStrings = array($ownerDetails['fullName'], $candidateDetails['firstName'], $candidateDetails['firstName'] . ' ' . $candidateDetails['lastName'], '<a href="http://' . $_SERVER['HTTP_HOST'] . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')) . '?m=candidates&a=show&candidateID=' . $candidateID . '">' . 'http://' . $_SERVER['HTTP_HOST'] . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')) . '?m=candidates&a=show&candidateID=' . $candidateID . '</a>'); $statusChangeTemplate = str_replace($stringsToFind, $replacementStrings, $statusChangeTemplate); $email = $statusChangeTemplate; } else { $email = ''; $emailAddress = ''; } } else { $email = ''; $emailAddress = ''; } $isActive = $this->isChecked('isActive', $_POST); $firstName = $this->getTrimmedInput('firstName', $_POST); $middleName = $this->getTrimmedInput('middleName', $_POST); $lastName = $this->getTrimmedInput('lastName', $_POST); $email1 = $this->getTrimmedInput('email1', $_POST); $email2 = $this->getTrimmedInput('email2', $_POST); $address = $this->getTrimmedInput('address', $_POST); $city = $this->getTrimmedInput('city', $_POST); $state = $this->getTrimmedInput('state', $_POST); $zip = $this->getTrimmedInput('zip', $_POST); $source = $this->getTrimmedInput('source', $_POST); $keySkills = $this->getTrimmedInput('keySkills', $_POST); $currentEmployer = $this->getTrimmedInput('currentEmployer', $_POST); $currentPay = $this->getTrimmedInput('currentPay', $_POST); $desiredPay = $this->getTrimmedInput('desiredPay', $_POST); $notes = $this->getTrimmedInput('notes', $_POST); $webSite = $this->getTrimmedInput('webSite', $_POST); $bestTimeToCall = $this->getTrimmedInput('bestTimeToCall', $_POST); $gender = $this->getTrimmedInput('gender', $_POST); $race = $this->getTrimmedInput('race', $_POST); $veteran = $this->getTrimmedInput('veteran', $_POST); $disability = $this->getTrimmedInput('disability', $_POST); /* Candidate source list editor. */ $sourceCSV = $this->getTrimmedInput('sourceCSV', $_POST); /* Bail out if any of the required fields are empty. */ if (empty($firstName) || empty($lastName)) { CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'Required fields are missing.'); } if (!eval(Hooks::get('CANDIDATE_ON_EDIT_PRE'))) { return; } /* Update the candidate record. */ $updateSuccess = $candidates->update($candidateID, $isActive, $firstName, $middleName, $lastName, $email1, $email2, $phoneHome, $phoneCell, $phoneWork, $address, $city, $state, $zip, $source, $keySkills, $dateAvailable, $currentEmployer, $canRelocate, $currentPay, $desiredPay, $notes, $webSite, $bestTimeToCall, $owner, $isHot, $email, $emailAddress, $gender, $race, $veteran, $disability); if (!$updateSuccess) { CommonErrors::fatal(COMMONERROR_RECORDERROR, $this, 'Failed to update candidate.'); } /* Update extra fields. */ $candidates->extraFields->setValuesOnEdit($candidateID); /* Update possible source list */ $sources = $candidates->getPossibleSources(); $sourcesDifferences = ListEditor::getDifferencesFromList($sources, 'name', 'sourceID', $sourceCSV); $candidates->updatePossibleSources($sourcesDifferences); if (!eval(Hooks::get('CANDIDATE_ON_EDIT_POST'))) { return; } CATSUtility::transferRelativeURI('m=candidates&a=show&candidateID=' . $candidateID); }