function testFindRowByColumnValue() { $input = array(0 => array('ID' => 100, 'Name' => 'Cat', 'Sound' => 'Meow', 'Type' => 'Mammal'), 1 => array('ID' => 200, 'Name' => 'Dog', 'Sound' => 'Bark', 'Type' => 'Mammal'), 2 => array('ID' => 300, 'Name' => 'Wolf', 'Sound' => 'Howl', 'Type' => 'Mammal'), 3 => array('ID' => 400, 'Name' => 'Cow', 'Sound' => 'Moo', 'Type' => 'Mammal'), 4 => array('ID' => 500, 'Name' => 'Snake', 'Sound' => 'Hiss', 'Type' => 'Reptile')); /* Test simple 'finding' functionality. */ $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 100), 0); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 200), 1); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 300), 2); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 400), 3); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 500), 4); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 500.0), 4); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', '500'), 4); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'Type', 'Mammal'), 0); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'Sound', 'Hiss'), 4); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'ID', 600), false); /* Test skipping. */ $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'Type', 'Mammal', 1), 1); $this->assertIdentical(ResultSetUtility::findRowByColumnValue($input, 'Type', 'Mammal', 2), 2); /* Test strict matching. */ $this->assertIdentical(ResultSetUtility::findRowByColumnValueStrict($input, 'Sound', 'Hiss'), 4); $this->assertIdentical(ResultSetUtility::findRowByColumnValueStrict($input, 'ID', '500'), false); $this->assertIdentical(ResultSetUtility::findRowByColumnValueStrict($input, 'ID', 500.0), false); /* Just in case strict and non-strict functions aren't identical... */ $this->assertIdentical(ResultSetUtility::findRowByColumnValueStrict($input, 'Type', 'Mammal', 1), 1); $this->assertIdentical(ResultSetUtility::findRowByColumnValueStrict($input, 'Type', 'Mammal', 2), 2); }
private function onSearch() { $wildCardCompanyName = ''; $wildCardKeyTechnologies = ''; /* Bail out to prevent an error if the GET string doesn't even contain * a field named 'wildCardString' at all. */ if (!isset($_GET['wildCardString'])) { $this->listByView('No wild card string specified.'); return; } $query = trim($_GET['wildCardString']); /* Set up sorting. */ if ($this->isRequiredIDValid('page', $_GET)) { $currentPage = $_GET['page']; } else { $currentPage = 1; } $searchPager = new SearchPager(CANDIDATES_PER_PAGE, $currentPage, $this->_siteID, $_GET); if ($searchPager->isSortByValid('sortBy', $_GET)) { $sortBy = $_GET['sortBy']; } else { $sortBy = 'name'; } if ($searchPager->isSortDirectionValid('sortDirection', $_GET)) { $sortDirection = $_GET['sortDirection']; } else { $sortDirection = 'ASC'; } $baseURL = CATSUtility::getFilteredGET(array('sortBy', 'sortDirection', 'page'), '&'); $searchPager->setSortByParameters($baseURL, $sortBy, $sortDirection); if (!eval(Hooks::get('CLIENTS_ON_SEARCH_PRE'))) { return; } /* Get our current searching mode. */ $mode = $this->getTrimmedInput('mode', $_GET); /* Execute the search. */ $search = new SearchCompanies($this->_siteID); switch ($mode) { case 'searchByName': $wildCardCompanyName = $query; $rs = $search->byName($query, $sortBy, $sortDirection); break; case 'searchByKeyTechnologies': $wildCardKeyTechnologies = $query; $rs = $search->byKeyTechnologies($query, $sortBy, $sortDirection); break; default: $this->listByView('Invalid search mode.'); return; break; } foreach ($rs as $rowIndex => $row) { if ($row['isHot'] == 1) { $rs[$rowIndex]['linkClass'] = 'jobLinkHot'; } else { $rs[$rowIndex]['linkClass'] = 'jobLinkCold'; } if (!empty($row['ownerFirstName'])) { $rs[$rowIndex]['ownerAbbrName'] = StringUtility::makeInitialName($row['ownerFirstName'], $row['ownerLastName'], false, LAST_NAME_MAXLEN); } else { $rs[$rowIndex]['ownerAbbrName'] = 'None'; } } $companyIDs = implode(',', ResultSetUtility::getColumnValues($rs, 'companyID')); $exportForm = ExportUtility::getForm(DATA_ITEM_COMPANY, $companyIDs, 40, 15); /* Save the search. */ $savedSearches = new SavedSearches($this->_siteID); $savedSearches->add(DATA_ITEM_COMPANY, $query, $_SERVER['REQUEST_URI'], false); $savedSearchRS = $savedSearches->get(DATA_ITEM_COMPANY); $query = urlencode(htmlspecialchars($query)); if (!eval(Hooks::get('CLIENTS_ON_SEARCH_POST'))) { return; } $this->_template->assign('savedSearchRS', $savedSearchRS); $this->_template->assign('active', $this); $this->_template->assign('subActive', 'Search Companies'); $this->_template->assign('exportForm', $exportForm); $this->_template->assign('pager', $searchPager); $this->_template->assign('rs', $rs); $this->_template->assign('isResultsMode', true); $this->_template->assign('wildCardCompanyName', $wildCardCompanyName); $this->_template->assign('wildCardString', $query); $this->_template->assign('wildCardKeyTechnologies', $wildCardKeyTechnologies); $this->_template->assign('mode', $mode); $this->_template->display('./modules/companies/Search.tpl'); }
/** * Returns an array of events in a month, keyed by each day of the month. * There will always be a key present for each day of the month, but if * there are no events for a day then it's corresponding value will be an * empty array. * * @param integer Month number (1-12). * @param integer Year (four-digit). * @return array Multi-dimensional result set array. */ public function getEventArray($month, $year) { // FIXME: Rewrite this query to use date ranges in WHERE, so that // indexes can be used. $sql = sprintf("SELECT\n calendar_event.calendar_event_id AS eventID,\n calendar_event.data_item_id AS dataItemID,\n calendar_event.data_item_type AS dataItemType,\n calendar_event.joborder_id AS jobOrderID,\n calendar_event.duration AS duration,\n calendar_event.all_day AS allDay,\n calendar_event.title AS title,\n calendar_event.description AS description,\n calendar_event.reminder_enabled AS reminderEnabled,\n calendar_event.reminder_email AS reminderEmail,\n calendar_event.reminder_time AS reminderTime,\n calendar_event.public AS public,\n DATE_FORMAT(\n calendar_event.date, '%%d'\n ) AS day,\n DATE_FORMAT(\n calendar_event.date, '%%m'\n ) AS month,\n DATE_FORMAT(\n calendar_event.date, '%%y'\n ) AS year,\n DATE_FORMAT(\n calendar_event.date, '%%m-%%d-%%y'\n ) AS date,\n DATE_FORMAT(\n calendar_event.date, '%%h:%%i %%p'\n ) AS time,\n DATE_FORMAT(\n calendar_event.date, '%%H'\n ) AS hour,\n DATE_FORMAT(\n calendar_event.date, '%%i'\n ) AS minute,\n calendar_event.date AS dateSort,\n DATE_FORMAT(\n calendar_event.date_created, '%%m-%%d-%%y (%%h:%%i %%p)'\n ) AS dateCreated,\n calendar_event_type.calendar_event_type_id AS eventType,\n calendar_event_type.short_description AS eventTypeDescription,\n entered_by_user.user_id AS userID,\n entered_by_user.first_name AS enteredByFirstName,\n entered_by_user.last_name AS enteredByLastName\n FROM\n calendar_event\n LEFT JOIN calendar_event_type\n ON calendar_event.type = calendar_event_type.calendar_event_type_id\n LEFT JOIN user AS entered_by_user\n ON calendar_event.entered_by = entered_by_user.user_id\n WHERE\n DATE_FORMAT(calendar_event.date, '%%c') = %s\n AND\n DATE_FORMAT(calendar_event.date, '%%Y') = %s\n AND\n calendar_event.site_id = %s\n ORDER BY\n dateSort ASC", $month, $year, $this->_siteID); $rs = $this->_db->getAllAssoc($sql); /* Build an array of result set arrays for each day of the month. * Days without any events scheduled will have an empty array. */ $daysInMonth = DateUtility::getDaysInMonth($month, $year); for ($i = 1; $i <= $daysInMonth; ++$i) { /* See if we can find a row in the result set that has 'day' set * to $i. */ $firstOffset = ResultSetUtility::findRowByColumnValue($rs, 'day', $i); /* Found? If yes, $firstOffset now contains the offset of the row; * otherwise false. */ if ($firstOffset === false) { /* No events for this date. */ $array[$i] = array(); continue; } /* Store the first row we found that has 'day' set to $i. */ $array[$i] = array($rs[$firstOffset]); /* There could be more than one row that has 'day' set to $i * (multiple events on the same day). We are going to tell * findRowByColumnValue() to skip the first row (we found it * and stored it already), and then keep increasing the number * of rows to skip until we can't find any more rows. */ for ($skip = 1;; ++$skip) { $nextOffset = ResultSetUtility::findRowByColumnValue($rs, 'day', $i, $skip); if ($nextOffset === false) { /* No more rows for this date. */ break; } /* Found another one; store the row. */ $array[$i][] = $rs[$nextOffset]; } } return $array; }
/** * Processes an Add Activity / Schedule Event form and displays * contacts/AddActivityScheduleEventModal.tpl. This is factored out * for code clarity. * * @param boolean from joborders module perspective * @param integer "regarding" job order ID or -1 * @param string module directory * @return void */ private function _addActivityScheduleEvent($regardingID, $directoryOverride = '') { /* Module directory override for fatal() calls. */ if ($directoryOverride != '') { $moduleDirectory = $directoryOverride; } else { $moduleDirectory = $this->_moduleDirectory; } /* Bail out if we don't have a valid candidate ID. */ if (!$this->isRequiredIDValid('contactID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.'); } $contactID = $_POST['contactID']; //if (!eval(Hooks::get('CONTACT_ON_ADD_ACTIVITY_SCHEDULE_EVENT_PRE'))) return; if ($this->isChecked('addActivity', $_POST)) { /* Bail out if we don't have a valid job order ID. */ if (!$this->isOptionalIDValid('activityTypeID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid activity type ID.'); } $activityTypeID = $_POST['activityTypeID']; $activityNote = $this->getTrimmedInput('activityNote', $_POST); $activityNote = htmlspecialchars($activityNote); /* Add the activity entry. */ $activityEntries = new ActivityEntries($this->_siteID); $activityID = $activityEntries->add($contactID, DATA_ITEM_CONTACT, $activityTypeID, $activityNote, $this->_userID, $regardingID); $activityTypes = $activityEntries->getTypes(); $activityTypeDescription = ResultSetUtility::getColumnValueByIDValue($activityTypes, 'typeID', $activityTypeID, 'type'); $activityAdded = true; } else { $activityAdded = false; $activityNote = ''; $activityTypeDescription = ''; } if ($this->isChecked('scheduleEvent', $_POST)) { /* Bail out if we received an invalid date. */ $trimmedDate = $this->getTrimmedInput('dateAdd', $_POST); if (empty($trimmedDate) || !DateUtility::validate('-', $trimmedDate, DATE_FORMAT_MMDDYY)) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid date.'); } /* Bail out if we don't have a valid event type. */ if (!$this->isRequiredIDValid('eventTypeID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid event type ID.'); } /* Bail out if we don't have a valid time format ID. */ if (!isset($_POST['allDay']) || $_POST['allDay'] != '0' && $_POST['allDay'] != '1') { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid time format ID.'); } $eventTypeID = $_POST['eventTypeID']; if ($_POST['allDay'] == 1) { $allDay = true; } else { $allDay = false; } $publicEntry = $this->isChecked('publicEntry', $_POST); $reminderEnabled = $this->isChecked('reminderToggle', $_POST); $reminderEmail = $this->getTrimmedInput('sendEmail', $_POST); $reminderTime = $this->getTrimmedInput('reminderTime', $_POST); $duration = -1; /* Is this a scheduled event or an all day event? */ if ($allDay) { $date = DateUtility::convert('-', $trimmedDate, DATE_FORMAT_MMDDYY, DATE_FORMAT_YYYYMMDD); $hour = 12; $minute = 0; $meridiem = 'AM'; } else { /* Bail out if we don't have a valid hour. */ if (!isset($_POST['hour'])) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid hour.'); } /* Bail out if we don't have a valid minute. */ if (!isset($_POST['minute'])) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid minute.'); } /* Bail out if we don't have a valid meridiem value. */ if (!isset($_POST['meridiem']) || $_POST['meridiem'] != 'AM' && $_POST['meridiem'] != 'PM') { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid meridiem value.'); } $hour = $_POST['hour']; $minute = $_POST['minute']; $meridiem = $_POST['meridiem']; /* Convert formatted time to UNIX timestamp. */ $time = strtotime(sprintf('%s:%s %s', $hour, $minute, $meridiem)); /* Create MySQL date string w/ 24hr time (YYYY-MM-DD HH:MM:SS). */ $date = sprintf('%s %s', DateUtility::convert('-', $trimmedDate, DATE_FORMAT_MMDDYY, DATE_FORMAT_YYYYMMDD), date('H:i:00', $time)); } $description = $this->getTrimmedInput('description', $_POST); $title = $this->getTrimmedInput('title', $_POST); /* Bail out if any of the required fields are empty. */ if (empty($title)) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Required fields are missing.'); } if ($regardingID > 0) { $eventJobOrderID = $regardingID; } else { $eventJobOrderID = -1; } $calendar = new Calendar($this->_siteID); $eventID = $calendar->addEvent($eventTypeID, $date, $description, $allDay, $this->_userID, $contactID, DATA_ITEM_CONTACT, $eventJobOrderID, $title, $duration, $reminderEnabled, $reminderEmail, $reminderTime, $publicEntry, $_SESSION['CATS']->getTimeZoneOffset()); if ($eventID <= 0) { CommonErrors::fatalModal(COMMONERROR_RECORDERROR, $this, 'Failed to add calendar event.'); } /* Extract the date parts from the specified date. */ $parsedDate = strtotime($date); $formattedDate = date('l, F jS, Y', $parsedDate); $calendar = new Calendar($this->_siteID); $calendarEventTypes = $calendar->getAllEventTypes(); $eventTypeDescription = ResultSetUtility::getColumnValueByIDValue($calendarEventTypes, 'typeID', $eventTypeID, 'description'); $eventHTML = sprintf('<p>An event of type <span class="bold">%s</span> has been scheduled on <span class="bold">%s</span>.</p>', htmlspecialchars($eventTypeDescription), htmlspecialchars($formattedDate)); $eventScheduled = true; } else { $eventHTML = '<p>No event has been scheduled.</p>'; $eventScheduled = false; } if (isset($_GET['onlyScheduleEvent'])) { $onlyScheduleEvent = true; } else { $onlyScheduleEvent = false; } if (!$activityAdded && !$eventScheduled) { $changesMade = false; } else { $changesMade = true; } if (!eval(Hooks::get('CANDIDATE_ON_ADD_ACTIVITY_CHANGE_STATUS_POST'))) { return; } $this->_template->assign('contactID', $contactID); $this->_template->assign('regardingID', $regardingID); $this->_template->assign('activityAdded', $activityAdded); $this->_template->assign('activityDescription', $activityNote); $this->_template->assign('activityType', $activityTypeDescription); $this->_template->assign('eventScheduled', $eventScheduled); $this->_template->assign('onlyScheduleEvent', $onlyScheduleEvent); $this->_template->assign('eventHTML', $eventHTML); $this->_template->assign('changesMade', $changesMade); $this->_template->assign('isFinishedMode', true); $this->_template->display('./modules/contacts/AddActivityScheduleEventModal.tpl'); }
} /* Instantiate a new AddressParser */ $addressParser = new AddressParser(); /* Feed the AddressParser a the address block from POST data and parse * the address. */ $addressBlock = urldecode($_REQUEST['addressBlock']); $addressParser->parse($addressBlock, $mode); /* Get the parsed address as an associative array. */ $parsedAddressArray = $addressParser->getAddressArray(); $phoneNumbers = $parsedAddressArray['phoneNumbers']; /* Fetch individual phone numbers. */ $homePhoneRow = ResultSetUtility::findRowByColumnValue($phoneNumbers, 'type', 'home'); $workPhoneRow = ResultSetUtility::findRowByColumnValue($phoneNumbers, 'type', 'work'); $cellPhoneRow = ResultSetUtility::findRowByColumnValue($phoneNumbers, 'type', 'cell'); $faxRow = ResultSetUtility::findRowByColumnValue($phoneNumbers, 'type', 'fax'); if ($homePhoneRow !== false) { $homePhone = $phoneNumbers[$homePhoneRow]['number']; } else { $homePhone = ''; } if ($cellPhoneRow !== false) { $cellPhone = $phoneNumbers[$cellPhoneRow]['number']; } else { $cellPhone = ''; } if ($workPhoneRow !== false) { $workPhone = $phoneNumbers[$workPhoneRow]['number']; } else { $workPhone = ''; }
protected function _getPhoneNumbers() { /* Sanity check. It is possible that the only line of the address * block has been removed during e-mail address extraction. */ if (empty($this->_addressBlock)) { return array(); } $unknownNumbers = array(); $numbers = array(); /* Loop through each line of the address block and attempt to extract * and identify phone numbers. */ foreach ($this->_addressBlock as $lineNumber => $line) { /* Skip lines that don't contain phone numbers. */ if (!StringUtility::containsPhoneNumber($line)) { continue; } /* Regular expressions to help identify phone number types. */ $cell = '/cell|[\\x28\\x5b][CM][\\x29\\x5d]|mob(:?ile|\\b)|\\bc[:\\x5d]|\\bm[:\\x5d]/i'; $home = '/[\\x28\\x5b]H[\\x29\\x5d]|home|evening|night|house/i'; $work = '/work|off(:?ice|\\b)|[\\x28\\x5b][WO][\\x29\\x5d]|direct|day(?:time)?|job/i'; $general = '/[\\x28\\x5b]PH?[\\x29\\x5d]|primary|voice|main|toll|ph(:?one|\\b)/i'; $fax = '/[\\x28\\x5b]FX?[\\x29\\x5d]|fax|facsimile|\\bFX?[:\\x5d]/i'; $tty = '/\\bTT[YD]\\b/i'; $pager = '/pager|beeper/i'; /* Look for keywords that might tell us what type of number it is. * First check to see if the line is ONLY a phone number. If not, * try do identify what kind of phone number it is. * * \x28 is a '(', \x5b is a '[', \x29 is a ')', \x5d is a ']'. */ if (preg_match($cell, $line)) { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'cell'); } else { if (preg_match($home, $line)) { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'home'); } else { if (preg_match($work, $line)) { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'work'); } else { if (preg_match($general, $line)) { if ($this->_mode != ADDRESSPARSER_MODE_COMPANY) { $unknownNumbers[] = StringUtility::extractPhoneNumber($line); } else { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'general'); } } else { if (preg_match($fax, $line)) { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'fax'); } else { if (preg_match($tty, $line)) { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'tty'); } else { if (preg_match($pager, $line)) { $numbers[] = array('number' => StringUtility::extractPhoneNumber($line), 'type' => 'pager'); } else { if (StringUtility::isPhoneNumber($line)) { /* In this case, the line contains only a phone number, and is * truely unknown. */ $unknownNumbers[] = StringUtility::extractPhoneNumber($line); } else { /* In this case, the line contains other data besides just a * phone number. We just can't identify it as anything. */ $unknownNumbers[] = StringUtility::extractPhoneNumber($line); } } } } } } } } } /* Figure out which phone number types we've already found. We'll * use this below. */ $homePhoneRow = ResultSetUtility::findRowByColumnValue($numbers, 'type', 'home'); $workPhoneRow = ResultSetUtility::findRowByColumnValue($numbers, 'type', 'work'); $cellPhoneRow = ResultSetUtility::findRowByColumnValue($numbers, 'type', 'cell'); /* Did we find any unknown phone numbers? If so, we have to try to * guess their types. */ $unknownCount = count($unknownNumbers); if ($unknownCount == 1) { /* If we're only missing one of the three phone number types, and we * found a number on a line by itself, we will assume that the extra * number is one of the missing ones. * * If we don't have a work number, but we have a home number * and a cell number, this is probably a work number. */ if ($workPhoneRow === false && $homePhoneRow !== false && $cellPhoneRow !== false) { $numbers[] = array('number' => $unknownNumbers[0], 'type' => 'work'); } else { if ($homePhoneRow === false && $workPhoneRow !== false && $cellPhoneRow !== false) { $numbers[] = array('number' => $unknownNumbers[0], 'type' => 'home'); } else { if ($cellPhoneRow === false && $workPhoneRow !== false && $homePhoneRow !== false) { $numbers[] = array('number' => $unknownNumbers[0], 'type' => 'cell'); } else { if ($cellPhoneRow !== false && $workPhoneRow !== false && $homePhoneRow !== false) { /* We already know all the phone numbers we need to know, and * it's probably not a fax number, as fax numbers are usually * labeled. Nothing to do except mark it as unknown. */ $numbers[] = array('number' => $unknownNumbers[0], 'type' => 'unknown'); } else { /* We have more than one phone number missing. We will make a * "best guess" according to the mode we are in. */ switch ($this->_mode) { case ADDRESSPARSER_MODE_PERSON: if ($homePhoneRow === false) { $type = 'home'; } else { if ($cellPhoneRow === false) { $type = 'cell'; } else { if ($workPhoneRow === false) { $type = 'work'; } else { $type = 'unknown'; } } } break; case ADDRESSPARSER_MODE_CONTACT: /* 'Contacts' are more likely to list a work or cell * number than a home number. */ if ($workPhoneRow === false) { $type = 'work'; } else { if ($cellPhoneRow === false) { $type = 'cell'; } else { if ($homePhoneRow === false) { $type = 'home'; } else { $type = 'unknown'; } } } break; case ADDRESSPARSER_MODE_COMPANY: // FIXME: Here we should be looking for "general". // We could also have two phone phone numbers. $type = 'general'; break; default: /* Error! Invalid mode. */ $type = 'unknown'; break; } $numbers[] = array('number' => $unknownNumbers[0], 'type' => $type); } } } } } else { if ($unknownCount > 1) { // FIXME } } return $numbers; }
public function onSearch() { $query_jobTitle = ''; $query_companyName = ''; /* Bail out to prevent an error if the GET string doesn't even contain * a field named 'wildCardString' at all. */ if (!isset($_GET['wildCardString'])) { $this->listByView('No wild card string specified.'); return; } $query = trim($_GET['wildCardString']); /* Set up sorting. */ if ($this->isRequiredIDValid('page', $_GET)) { $currentPage = $_GET['page']; } else { $currentPage = 1; } $searchPager = new SearchPager( CANDIDATES_PER_PAGE, $currentPage, $this->_siteID, $_GET ); if ($searchPager->isSortByValid('sortBy', $_GET)) { $sortBy = $_GET['sortBy']; } else { $sortBy = 'title'; } if ($searchPager->isSortDirectionValid('sortDirection', $_GET)) { $sortDirection = $_GET['sortDirection']; } else { $sortDirection = 'ASC'; } $baseURL = CATSUtility::getFilteredGET( array('sortBy', 'sortDirection', 'page'), '&' ); $searchPager->setSortByParameters($baseURL, $sortBy, $sortDirection); /* Get our current searching mode. */ $mode = $this->getTrimmedInput('mode', $_GET); /* Execute the search. */ $search = new SearchJobOrders($this->_siteID); switch ($mode) { case 'searchByJobTitle': $query_jobTitle = $query; $rs = $search->byTitle($query, $sortBy, $sortDirection, false); break; case 'searchByCompanyName': $query_companyName = $query; $rs = $search->byCompanyName($query, $sortBy, $sortDirection, false); break; default: $this->listByView('Invalid search mode.'); return; break; } foreach ($rs as $rowIndex => $row) { /* Convert '00-00-00' dates to empty strings. */ $rs[$rowIndex]['startDate'] = DateUtility::fixZeroDate( $row['startDate'] ); if ($row['isHot'] == 1) { $rs[$rowIndex]['linkClass'] = 'jobLinkHot'; } else { $rs[$rowIndex]['linkClass'] = 'jobLinkCold'; } $rs[$rowIndex]['recruiterAbbrName'] = StringUtility::makeInitialName( $row['recruiterFirstName'], $row['recruiterLastName'], false, LAST_NAME_MAXLEN ); $rs[$rowIndex]['ownerAbbrName'] = StringUtility::makeInitialName( $row['ownerFirstName'], $row['ownerLastName'], false, LAST_NAME_MAXLEN ); } /* Save the search. */ $savedSearches = new SavedSearches($this->_siteID); $savedSearches->add( DATA_ITEM_JOBORDER, $query, $_SERVER['REQUEST_URI'], false ); $savedSearchRS = $savedSearches->get(DATA_ITEM_JOBORDER); $query = urlencode(htmlspecialchars($query)); $jobOderIDs = implode(',', ResultSetUtility::getColumnValues($rs, 'jobOrderID')); $exportForm = ExportUtility::getForm( DATA_ITEM_JOBORDER, $jobOderIDs, 29, 5 ); $this->_template->assign('active', $this); $this->_template->assign('subActive', 'Search Job Orders'); $this->_template->assign('pager', $searchPager); $this->_template->assign('exportForm', $exportForm); $this->_template->assign('wildCardString', $query); $this->_template->assign('wildCardString_jobTitle', $query_jobTitle); $this->_template->assign('wildCardString_companyName', $query_companyName); $this->_template->assign('savedSearchRS', $savedSearchRS); $this->_template->assign('rs', $rs); $this->_template->assign('isResultsMode', true); $this->_template->assign('mode', $mode); if (!eval(Hooks::get('JO_ON_SEARCH'))) return; $this->_template->display('./modules/joborders/Search.php'); }
/** * Processes an Add Activity / Change Status form and displays * candidates/AddActivityChangeStatusModal.tpl. This is factored out * for code clarity. * * @param boolean from joborders module perspective * @param integer "regarding" job order ID or -1 * @param string module directory * @return void */ private function _addActivityChangeStatus($isJobOrdersMode, $regardingID, $directoryOverride = '') { $notificationHTML = ''; $pipelines = new Pipelines($this->_siteID); $statusRS = $pipelines->getStatusesForPicking(); /* Module directory override for fatal() calls. */ if ($directoryOverride != '') { $moduleDirectory = $directoryOverride; } else { $moduleDirectory = $this->_moduleDirectory; } /* Bail out if we don't have a valid candidate ID. */ if (!$this->isRequiredIDValid('candidateID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid candidate ID.'); } /* Do we have a valid status ID. */ if (!$this->isOptionalIDValid('statusID', $_POST)) { $statusID = -1; } else { $statusID = $_POST['statusID']; } $candidateID = $_POST['candidateID']; if (!eval(Hooks::get('CANDIDATE_ON_ADD_ACTIVITY_CHANGE_STATUS_PRE'))) { return; } if ($this->isChecked('addActivity', $_POST)) { /* Bail out if we don't have a valid job order ID. */ if (!$this->isOptionalIDValid('activityTypeID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid activity type ID.'); } $activityTypeID = $_POST['activityTypeID']; $activityNote = $this->getTrimmedInput('activityNote', $_POST); $activityNote = htmlspecialchars($activityNote); // FIXME: Move this to a highlighter-method? */ if (strpos($activityNote, 'Status change: ') === 0) { foreach ($statusRS as $data) { $activityNote = StringUtility::replaceOnce($data['status'], '<span style="color: #ff6c00;">' . $data['status'] . '</span>', $activityNote); } } /* Add the activity entry. */ $activityEntries = new ActivityEntries($this->_siteID); $activityID = $activityEntries->add($candidateID, DATA_ITEM_CANDIDATE, $activityTypeID, $activityNote, $this->_userID, $regardingID); $activityTypes = $activityEntries->getTypes(); $activityTypeDescription = ResultSetUtility::getColumnValueByIDValue($activityTypes, 'typeID', $activityTypeID, 'type'); $activityAdded = true; } else { $activityAdded = false; $activityNote = ''; $activityTypeDescription = ''; } if ($regardingID <= 0 || $statusID == -1) { $statusChanged = false; $oldStatusDescription = ''; $newStatusDescription = ''; } else { $data = $pipelines->get($candidateID, $regardingID); /* Bail out if we got an empty result set. */ if (empty($data)) { $this->fatalModal('The specified pipeline entry could not be found.'); } $validStatus = ResultSetUtility::findRowByColumnValue($statusRS, 'statusID', $statusID); /* If the status is invalid or unchanged, don't mess with it. */ if ($validStatus === false || $statusID == $data['status']) { $oldStatusDescription = ''; $newStatusDescription = ''; $statusChanged = false; } else { $oldStatusDescription = $data['status']; $newStatusDescription = ResultSetUtility::getColumnValueByIDValue($statusRS, 'statusID', $statusID, 'status'); if ($oldStatusDescription != $newStatusDescription) { $statusChanged = true; } else { $statusChanged = false; } } if ($statusChanged && $this->isChecked('triggerEmail', $_POST)) { $customMessage = $this->getTrimmedInput('customMessage', $_POST); // FIXME: Actually validate the e-mail address? if (empty($data['candidateEmail'])) { $email = ''; $notificationHTML = '<p><span class="bold">Error:</span> An e-mail notification' . ' could not be sent to the candidate because the candidate' . ' does not have a valid e-mail address.</p>'; } else { if (empty($customMessage)) { $email = ''; $notificationHTML = '<p><span class="bold">Error:</span> An e-mail notification' . ' will not be sent because the message text specified was blank.</p>'; } else { if ($this->_accessLevel == ACCESS_LEVEL_DEMO) { $email = ''; $notificationHTML = '<p><span class="bold">Error:</span> Demo users can not send' . ' E-Mails. No E-Mail was sent.</p>'; } else { $email = $data['candidateEmail']; $notificationHTML = '<p>An e-mail notification has been sent to the candidate.</p>'; } } } } else { $email = ''; $customMessage = ''; $notificationHTML = '<p>No e-mail notification has been sent to the candidate.</p>'; } /* Set the pipeline entry's status, but don't send e-mails for now. */ $pipelines->setStatus($candidateID, $regardingID, $statusID, $email, $customMessage); /* If status = placed, and open positions > 0, reduce number of open positions by one. */ if ($statusID == PIPELINE_STATUS_PLACED && is_numeric($data['openingsAvailable']) && $data['openingsAvailable'] > 0) { $jobOrders = new JobOrders($this->_siteID); $jobOrders->updateOpeningsAvailable($regardingID, $data['openingsAvailable'] - 1); } } if ($this->isChecked('scheduleEvent', $_POST)) { /* Bail out if we received an invalid date. */ $trimmedDate = $this->getTrimmedInput('dateAdd', $_POST); if (empty($trimmedDate) || !DateUtility::validate('-', $trimmedDate, DATE_FORMAT_MMDDYY)) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid date.'); } /* Bail out if we don't have a valid event type. */ if (!$this->isRequiredIDValid('eventTypeID', $_POST)) { CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid event type ID.'); } /* Bail out if we don't have a valid time format ID. */ if (!isset($_POST['allDay']) || $_POST['allDay'] != '0' && $_POST['allDay'] != '1') { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid time format ID.'); } $eventTypeID = $_POST['eventTypeID']; if ($_POST['allDay'] == 1) { $allDay = true; } else { $allDay = false; } $publicEntry = $this->isChecked('publicEntry', $_POST); $reminderEnabled = $this->isChecked('reminderToggle', $_POST); $reminderEmail = $this->getTrimmedInput('sendEmail', $_POST); $reminderTime = $this->getTrimmedInput('reminderTime', $_POST); $duration = $this->getTrimmedInput('duration', $_POST); /* Is this a scheduled event or an all day event? */ if ($allDay) { $date = DateUtility::convert('-', $trimmedDate, DATE_FORMAT_MMDDYY, DATE_FORMAT_YYYYMMDD); $hour = 12; $minute = 0; $meridiem = 'AM'; } else { /* Bail out if we don't have a valid hour. */ if (!isset($_POST['hour'])) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid hour.'); } /* Bail out if we don't have a valid minute. */ if (!isset($_POST['minute'])) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this, 'Invalid minute.'); } /* Bail out if we don't have a valid meridiem value. */ if (!isset($_POST['meridiem']) || $_POST['meridiem'] != 'AM' && $_POST['meridiem'] != 'PM') { $this->fatalModal('Invalid meridiem value.', $moduleDirectory); } $hour = $_POST['hour']; $minute = $_POST['minute']; $meridiem = $_POST['meridiem']; /* Convert formatted time to UNIX timestamp. */ $time = strtotime(sprintf('%s:%s %s', $hour, $minute, $meridiem)); /* Create MySQL date string w/ 24hr time (YYYY-MM-DD HH:MM:SS). */ $date = sprintf('%s %s', DateUtility::convert('-', $trimmedDate, DATE_FORMAT_MMDDYY, DATE_FORMAT_YYYYMMDD), date('H:i:00', $time)); } $description = $this->getTrimmedInput('description', $_POST); $title = $this->getTrimmedInput('title', $_POST); /* Bail out if any of the required fields are empty. */ if (empty($title)) { CommonErrors::fatalModal(COMMONERROR_MISSINGFIELDS, $this); return; /*$this->fatalModal( 'Required fields are missing.', $moduleDirectory );*/ } if ($regardingID > 0) { $eventJobOrderID = $regardingID; } else { $eventJobOrderID = -1; } $calendar = new Calendar($this->_siteID); $eventID = $calendar->addEvent($eventTypeID, $date, $description, $allDay, $this->_userID, $candidateID, DATA_ITEM_CANDIDATE, $eventJobOrderID, $title, $duration, $reminderEnabled, $reminderEmail, $reminderTime, $publicEntry, $_SESSION['CATS']->getTimeZoneOffset()); if ($eventID <= 0) { $this->fatalModal('Failed to add calendar event.', $moduleDirectory); } /* Extract the date parts from the specified date. */ $parsedDate = strtotime($date); $formattedDate = date('l, F jS, Y', $parsedDate); $calendar = new Calendar($this->_siteID); $calendarEventTypes = $calendar->getAllEventTypes(); $eventTypeDescription = ResultSetUtility::getColumnValueByIDValue($calendarEventTypes, 'typeID', $eventTypeID, 'description'); $eventHTML = sprintf('<p>An event of type <span class="bold">%s</span> has been scheduled on <span class="bold">%s</span>.</p>', htmlspecialchars($eventTypeDescription), htmlspecialchars($formattedDate)); $eventScheduled = true; } else { $eventHTML = '<p>No event has been scheduled.</p>'; $eventScheduled = false; } if (isset($_GET['onlyScheduleEvent'])) { $onlyScheduleEvent = true; } else { $onlyScheduleEvent = false; } if (!$statusChanged && !$activityAdded && !$eventScheduled) { $changesMade = false; } else { $changesMade = true; } if (!eval(Hooks::get('CANDIDATE_ON_ADD_ACTIVITY_CHANGE_STATUS_POST'))) { return; } $this->_template->assign('candidateID', $candidateID); $this->_template->assign('regardingID', $regardingID); $this->_template->assign('oldStatusDescription', $oldStatusDescription); $this->_template->assign('newStatusDescription', $newStatusDescription); $this->_template->assign('statusChanged', $statusChanged); $this->_template->assign('activityAdded', $activityAdded); $this->_template->assign('activityDescription', $activityNote); $this->_template->assign('activityType', $activityTypeDescription); $this->_template->assign('eventScheduled', $eventScheduled); $this->_template->assign('eventHTML', $eventHTML); $this->_template->assign('notificationHTML', $notificationHTML); $this->_template->assign('onlyScheduleEvent', $onlyScheduleEvent); $this->_template->assign('changesMade', $changesMade); $this->_template->assign('isFinishedMode', true); $this->_template->assign('isJobOrdersMode', $isJobOrdersMode); $this->_template->display('./modules/candidates/AddActivityChangeStatusModal.tpl'); }