public function merge() { 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', $_REQUEST)) { 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', $_REQUEST)) { 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', $_REQUEST); 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', $_REQUEST) ); if (!empty($formattedPhoneHome)) { $phoneHome = $formattedPhoneHome; } else { $phoneHome = $this->getTrimmedInput('phoneHome', $_REQUEST); } $formattedPhoneCell = StringUtility::extractPhoneNumber( $this->getTrimmedInput('phoneCell', $_REQUEST) ); if (!empty($formattedPhoneCell)) { $phoneCell = $formattedPhoneCell; } else { $phoneCell = $this->getTrimmedInput('phoneCell', $_REQUEST); } $formattedPhoneWork = StringUtility::extractPhoneNumber( $this->getTrimmedInput('phoneWork', $_REQUEST) ); if (!empty($formattedPhoneWork)) { $phoneWork = $formattedPhoneWork; } else { $phoneWork = $this->getTrimmedInput('phoneWork', $_REQUEST); } $candidateID = $_REQUEST['candidateID']; $owner = isset($_REQUEST['owner'])?$_REQUEST['owner']:null; /* Can Relocate */ $canRelocate = $this->isChecked('canRelocate', $_REQUEST); $isHot = $this->isChecked('isHot', $_REQUEST); /* Change ownership email? */ if ($this->isChecked('ownershipChange', $_REQUEST) && $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', $_REQUEST); $firstName = $this->getTrimmedInput('firstName', $_REQUEST); $middleName = $this->getTrimmedInput('middleName', $_REQUEST); $lastName = $this->getTrimmedInput('lastName', $_REQUEST); $email1 = $this->getTrimmedInput('email1', $_REQUEST); $email2 = $this->getTrimmedInput('email2', $_REQUEST); $address = $this->getTrimmedInput('address', $_REQUEST); $city = $this->getTrimmedInput('city', $_REQUEST); $state = $this->getTrimmedInput('state', $_REQUEST); $zip = $this->getTrimmedInput('zip', $_REQUEST); $source = $this->getTrimmedInput('source', $_REQUEST); $keySkills = $this->getTrimmedInput('keySkills', $_REQUEST); $currentEmployer = $this->getTrimmedInput('currentEmployer', $_REQUEST); $currentPay = $this->getTrimmedInput('currentPay', $_REQUEST); $desiredPay = $this->getTrimmedInput('desiredPay', $_REQUEST); $notes = $this->getTrimmedInput('notes', $_REQUEST); $webSite = $this->getTrimmedInput('webSite', $_REQUEST); $bestTimeToCall = $this->getTrimmedInput('bestTimeToCall', $_REQUEST); $gender = $this->getTrimmedInput('gender', $_REQUEST); $race = $this->getTrimmedInput('race', $_REQUEST); $veteran = $this->getTrimmedInput('veteran', $_REQUEST); $disability = $this->getTrimmedInput('disability', $_REQUEST); /* Candidate source list editor. */ $sourceCSV = $this->getTrimmedInput('sourceCSV', $_REQUEST); /* 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->merge( $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); //else //{ /* Associate an exsisting resume if the user created a candidate with one. (Bulk) */ if (isset($_POST['associatedAttachment'])) { $attachmentID = $_POST['associatedAttachment']; $attachments = new Attachments($this->_siteID); $newAttachmentID=$attachments->copyAttachment(DATA_ITEM_CANDIDATE, $candidateID, $attachmentID); //trace($newAttachmentID); //$attachments->setDataItemID($newAttachmentID, $candidateID, DATA_ITEM_CANDIDATE); } /* Attach a resume if the user uploaded one. (http POST) */ /* NOTE: This function cannot be called if parsing is enabled */ else if (isset($_FILES['file']) && !empty($_FILES['file']['name'])) { if (!eval(Hooks::get('CANDIDATE_ON_CREATE_ATTACHMENT_PRE'))) return; $attachmentCreator = new AttachmentCreator($this->_siteID); $attachmentCreator->createFromUpload( DATA_ITEM_CANDIDATE, $candidateID, 'file', false, true ); if ($attachmentCreator->isError()) { CommonErrors::fatal(COMMONERROR_FILEERROR, $this, $attachmentCreator->getError()); } if ($attachmentCreator->duplicatesOccurred()) { $this->listByView( 'This attachment has already been added to this candidate.' ); return; } $isTextExtractionError = $attachmentCreator->isTextExtractionError(); $textExtractionErrorMessage = $attachmentCreator->getTextExtractionError(); // FIXME: Show parse errors! if (!eval(Hooks::get('CANDIDATE_ON_CREATE_ATTACHMENT_POST'))) return; } /** * User has loaded and/or parsed a resume. The attachment is saved in a temporary * file already and just needs to be attached. The attachment has also successfully * been DocumentToText converted, so we know it's a good file. */ else if (LicenseUtility::isParsingEnabled()) { /** * Description: User clicks "browse" and selects a resume file. User doesn't click * upload. The resume file is STILL uploaded. * Controversial: User uploads a resume, parses, etc. User selects a new file with * "Browse" but doesn't click "Upload". New file is accepted. * It's technically correct either way, I'm opting for the "use whats in "file" * box over what's already uploaded method to avoid losing resumes on candidate * additions. */ $newFile = FileUtility::getUploadFileFromPost($this->_siteID, 'addcandidate', 'documentFile'); if ($newFile !== false) { $newFilePath = FileUtility::getUploadFilePath($this->_siteID, 'addcandidate', $newFile); $tempFile = $newFile; $tempFullPath = $newFilePath; } else { $attachmentCreated = false; $tempFile = false; $tempFullPath = false; if (isset($_POST['documentTempFile']) && !empty($_POST['documentTempFile'])) { $tempFile = $_POST['documentTempFile']; // Get the path of the file they uploaded already to attach $tempFullPath = FileUtility::getUploadFilePath( $this->_siteID, // ID of the containing site 'addcandidate', // Sub-directory in their storage $tempFile // Name of the file (not pathed) ); } } if ($tempFile !== false && $tempFullPath !== false) { if (!eval(Hooks::get('CANDIDATE_ON_CREATE_ATTACHMENT_PRE'))) return; $attachmentCreator = new AttachmentCreator($this->_siteID); $attachmentCreator->createFromFile( DATA_ITEM_CANDIDATE, $candidateID, $tempFullPath, $tempFile, '', true, true ); if ($attachmentCreator->isError()) { CommonErrors::fatal(COMMONERROR_FILEERROR, $this, $attachmentCreator->getError()); } if ($attachmentCreator->duplicatesOccurred()) { $this->listByView( 'This attachment has already been added to this candidate.' ); return; } $isTextExtractionError = $attachmentCreator->isTextExtractionError(); $textExtractionErrorMessage = $attachmentCreator->getTextExtractionError(); if (!eval(Hooks::get('CANDIDATE_ON_CREATE_ATTACHMENT_POST'))) return; // Remove the cleanup cookie since the file no longer exists setcookie('CATS_SP_TEMP_FILE', ''); $attachmentCreated = true; } if (!$attachmentCreated && isset($_POST['documentText']) && !empty($_POST['documentText'])) { // Resume was pasted into the form and not uploaded from a file if (!eval(Hooks::get('CANDIDATE_ON_CREATE_ATTACHMENT_PRE'))) return; $attachmentCreator = new AttachmentCreator($this->_siteID); $attachmentCreator->createFromText( DATA_ITEM_CANDIDATE, $candidateID, $_POST['documentText'], 'MyResume.txt', true ); if ($attachmentCreator->isError()) { CommonErrors::fatal(COMMONERROR_FILEERROR, $this, $attachmentCreator->getError()); } if ($attachmentCreator->duplicatesOccurred()) { $this->listByView( 'This attachment has already been added to this candidate.' ); return; } if (!eval(Hooks::get('CANDIDATE_ON_CREATE_ATTACHMENT_POST'))) return; } } /* Create a text resume if the user posted one. (automated tool) */ else if (!empty($textResumeBlock)) { $attachmentCreator = new AttachmentCreator($this->_siteID); $attachmentCreator->createFromText( DATA_ITEM_CANDIDATE, $candidateID, $textResumeBlock, $textResumeFilename, true ); if ($attachmentCreator->isError()) { CommonErrors::fatal(COMMONERROR_FILEERROR, $this, $attachmentCreator->getError()); return; //$this->fatal($attachmentCreator->getError()); } $isTextExtractionError = $attachmentCreator->isTextExtractionError(); $textExtractionErrorMessage = $attachmentCreator->getTextExtractionError(); // FIXME: Show parse errors! } //} if(isset($_REQUEST["attachmentID"])) { $attachments = new Attachments($this->_siteID); $attachments->delete($_REQUEST["attachmentID"], true); } if (!eval(Hooks::get('CANDIDATE_ON_EDIT_POST'))) return; CATSUtility::transferRelativeURI( 'm=candidates&a=show&candidateID=' . $candidateID ); }