|
Server : Apache/2.4.62 System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64 User : www ( 80) PHP Version : 8.3.8 Disable Function : NONE Directory : /domains/irtiweb/CATS/modules/contacts/ |
Upload File : |
<?php
/*
* CATS
* Contacts Module
*
* Copyright (C) 2005 - 2007 Cognizo Technologies, Inc.
*
*
* The contents of this file are subject to the CATS Public License
* Version 1.1a (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.catsone.com/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is "CATS Standard Edition".
*
* The Initial Developer of the Original Code is Cognizo Technologies, Inc.
* Portions created by the Initial Developer are Copyright (C) 2005 - 2007
* (or from the year in which this file was created to the year 2007) by
* Cognizo Technologies, Inc. All Rights Reserved.
*
*
* $Id: ContactsUI.php 3444 2007-11-06 23:16:27Z will $
*/
include_once('./lib/StringUtility.php');
include_once('./lib/ResultSetUtility.php');
include_once('./lib/DateUtility.php');
include_once('./lib/Contacts.php');
include_once('./lib/Companies.php');
include_once('./lib/JobOrders.php');
include_once('./lib/ActivityEntries.php');
include_once('./lib/Export.php');
include_once('./lib/ExtraFields.php');
include_once('./lib/Calendar.php');
include_once('./lib/CommonErrors.php');
class ContactsUI extends UserInterface
{
/* Maximum number of characters of the job notes to show without the user
* clicking "[More]"
*/
const NOTES_MAXLEN = 500;
/* Maximum number of characters of the company name to show on the main
* contacts listing.
*/
const TRUNCATE_CLIENT_NAME = 22;
/* Maximum number of characters of the contact's title to show on the main
* contacts listing.
*/
const TRUNCATE_TITLE = 24;
public function __construct()
{
parent::__construct();
$this->_authenticationRequired = true;
$this->_moduleDirectory = 'contacts';
$this->_moduleName = 'contacts';
$this->_moduleTabText = 'Contacts';
$this->_subTabs = array(
'Add Contact' => CATSUtility::getIndexName() . '?m=contacts&a=add*al='.ACCESS_LEVEL_EDIT,
'Search Contacts' => CATSUtility::getIndexName() . '?m=contacts&a=search',
'Cold Call List' => CATSUtility::getIndexName() . '?m=contacts&a=showColdCallList'
);
}
public function handleRequest()
{
$action = $this->getAction();
if (!eval(Hooks::get('CONTACTS_HANDLE_REQUEST'))) return;
switch ($action)
{
case 'show':
$this->show();
break;
case 'add':
if ($this->isPostBack())
{
$this->onAdd();
}
else
{
$this->add();
}
break;
case 'edit':
if ($this->isPostBack())
{
$this->onEdit();
}
else
{
$this->edit();
}
break;
case 'delete':
$this->onDelete();
break;
case 'search':
include_once('./lib/Search.php');
if ($this->isGetBack())
{
$this->onSearch();
}
else
{
$this->search();
}
break;
case 'addActivityScheduleEvent':
if ($this->isPostBack())
{
$this->onAddActivityScheduleEvent();
}
else
{
$this->addActivityScheduleEvent();
}
break;
case 'showColdCallList':
$this->showColdCallList();
break;
case 'downloadVCard':
include_once('./lib/VCard.php');
$this->downloadVCard();
break;
/* Main contacts page. */
case 'listByView':
default:
$this->listByView();
break;
}
}
/*
* Called by handleRequest() to process loading the list / main page.
*/
private function listByView($errMessage = '')
{
if (!eval(Hooks::get('CONTACTS_LIST_BY_VIEW_TOP'))) return;
$dataGridProperties = DataGrid::getRecentParamaters("contacts:ContactsListByViewDataGrid");
/* If this is the first time we visited the datagrid this session, the recent paramaters will
* be empty. Fill in some default values. */
if ($dataGridProperties == array())
{
$dataGridProperties = array('rangeStart' => 0,
'maxResults' => 15,
'filterVisible' => false);
}
$dataGrid = DataGrid::get("contacts:ContactsListByViewDataGrid", $dataGridProperties);
$this->_template->assign('active', $this);
$this->_template->assign('dataGrid', $dataGrid);
$this->_template->assign('userID', $_SESSION['CATS']->getUserID());
$this->_template->assign('errMessage', $errMessage);
$contacts = new Contacts($this->_siteID);
$this->_template->assign('totalContacts', $contacts->getCount());
if (!eval(Hooks::get('CONTACTS_LIST_BY_VIEW'))) return;
$this->_template->display('./modules/contacts/Contacts.tpl');
}
/*
* Called by handleRequest() to process loading the details page.
*/
private function show()
{
/* Bail out if we don't have a valid contact ID. */
if (!$this->isRequiredIDValid('contactID', $_GET))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.');
}
$contactID = $_GET['contactID'];
$contacts = new Contacts($this->_siteID);
$data = $contacts->get($contactID);
/* Bail out if we got an empty result set. */
if (empty($data))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'The specified contact ID could not be found.');
}
/* We want to handle formatting the city and state here instead
* of in the template.
*/
$data['cityAndState'] = StringUtility::makeCityStateString(
$data['city'], $data['state']
);
/*
* Replace newlines with <br />, fix HTML "special" characters, and
* strip leading empty lines and spaces.
*/
$data['notes'] = trim(
nl2br(htmlspecialchars($data['notes'], ENT_QUOTES))
);
/* Chop $data['notes'] to make $data['shortNotes']. */
if (strlen($data['notes']) > self::NOTES_MAXLEN)
{
$data['shortNotes'] = substr(
$data['notes'], 0, self::NOTES_MAXLEN
);
$isShortNotes = true;
}
else
{
$data['shortNotes'] = $data['notes'];
$isShortNotes = false;
}
/* Hot contacts [can] have different title styles than normal contacts. */
if ($data['isHotContact'] == 1)
{
$data['titleClassContact'] = 'jobTitleHot';
}
else
{
$data['titleClassContact'] = 'jobTitleCold';
}
/* Hot companies [can] also have different title styles than normal companies. */
if ($data['isHotCompany'] == 1)
{
$data['titleClassCompany'] = 'jobTitleHot';
}
else
{
$data['titleClassCompany'] = 'jobTitleCold';
}
$jobOrders = new JobOrders($this->_siteID);
$jobOrdersRS = $jobOrders->getAll(JOBORDERS_STATUS_ALL, -1, -1, $contactID);
if (!empty($jobOrdersRS))
{
foreach ($jobOrdersRS as $rowIndex => $row)
{
/* Convert '00-00-00' dates to empty strings. */
$jobOrdersRS[$rowIndex]['startDate'] = DateUtility::fixZeroDate(
$jobOrdersRS[$rowIndex]['startDate']
);
/* Hot jobs [can] have different title styles than normal
* jobs.
*/
if ($jobOrdersRS[$rowIndex]['isHot'] == 1)
{
$jobOrdersRS[$rowIndex]['linkClass'] = 'jobLinkHot';
}
else
{
$jobOrdersRS[$rowIndex]['linkClass'] = 'jobLinkCold';
}
$jobOrdersRS[$rowIndex]['recruiterAbbrName'] = StringUtility::makeInitialName(
$jobOrdersRS[$rowIndex]['recruiterFirstName'],
$jobOrdersRS[$rowIndex]['recruiterLastName'],
false,
LAST_NAME_MAXLEN
);
$jobOrdersRS[$rowIndex]['ownerAbbrName'] = StringUtility::makeInitialName(
$jobOrdersRS[$rowIndex]['ownerFirstName'],
$jobOrdersRS[$rowIndex]['ownerLastName'],
false,
LAST_NAME_MAXLEN
);
}
}
$activityEntries = new ActivityEntries($this->_siteID);
$activityRS = $activityEntries->getAllByDataItem($contactID, DATA_ITEM_CONTACT);
if (!empty($activityRS))
{
foreach ($activityRS as $rowIndex => $row)
{
if (empty($activityRS[$rowIndex]['notes']))
{
$activityRS[$rowIndex]['notes'] = '(No Notes)';
}
if (empty($activityRS[$rowIndex]['jobOrderID']) ||
empty($activityRS[$rowIndex]['regarding']))
{
$activityRS[$rowIndex]['regarding'] = 'General';
}
$activityRS[$rowIndex]['enteredByAbbrName'] = StringUtility::makeInitialName(
$activityRS[$rowIndex]['enteredByFirstName'],
$activityRS[$rowIndex]['enteredByLastName'],
false,
LAST_NAME_MAXLEN
);
}
}
/* Get upcoming calendar entries. */
$calendarRS = $contacts->getUpcomingEvents($contactID);
if (!empty($calendarRS))
{
foreach ($calendarRS as $rowIndex => $row)
{
$calendarRS[$rowIndex]['enteredByAbbrName'] = StringUtility::makeInitialName(
$calendarRS[$rowIndex]['enteredByFirstName'],
$calendarRS[$rowIndex]['enteredByLastName'],
false,
LAST_NAME_MAXLEN
);
}
}
/* Add an MRU entry. */
$_SESSION['CATS']->getMRU()->addEntry(
DATA_ITEM_CONTACT, $contactID, $data['firstName'] . ' ' . $data['lastName']
);
/* Get extra fields. */
$extraFieldRS = $contacts->extraFields->getValuesForShow($contactID);
/* Is the user an admin - can user see history? */
if ($this->_accessLevel < ACCESS_LEVEL_DEMO)
{
$privledgedUser = false;
}
else
{
$privledgedUser = true;
}
$this->_template->assign('active', $this);
$this->_template->assign('data', $data);
$this->_template->assign('isShortNotes', $isShortNotes);
$this->_template->assign('jobOrdersRS', $jobOrdersRS);
$this->_template->assign('extraFieldRS', $extraFieldRS);
$this->_template->assign('calendarRS', $calendarRS);
$this->_template->assign('activityRS', $activityRS);
$this->_template->assign('contactID', $contactID);
$this->_template->assign('privledgedUser', $privledgedUser);
$this->_template->assign('sessionCookie', $_SESSION['CATS']->getCookie());
if (!eval(Hooks::get('CONTACTS_SHOW'))) return;
$this->_template->display('./modules/contacts/Show.tpl');
}
/*
* Called by handleRequest() to process loading the add page.
*/
private function add()
{
/* Bail if we don't have add permision. */
if ($this->_accessLevel < ACCESS_LEVEL_EDIT)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
$companies = new Companies($this->_siteID);
$contacts = new Contacts($this->_siteID);
/* Do we have a selected_company_id? */
if ($_SESSION['CATS']->isHrMode())
{
$selectedCompanyID = $companies->getDefaultCompany();
$companyRS = $companies->get($selectedCompanyID);
$reportsToRS = $contacts->getAll(-1, $selectedCompanyID);
}
else if (!$this->isRequiredIDValid('selected_company_id', $_GET))
{
$selectedCompanyID = false;
$companyRS = array();
$reportsToRS = array();
}
else
{
$selectedCompanyID = $_GET['selected_company_id'];
$companyRS = $companies->get($selectedCompanyID);
$reportsToRS = $contacts->getAll(-1, $_GET['selected_company_id']);
}
/* Get extra fields. */
$extraFieldRS = $contacts->extraFields->getValuesForAdd();
$defaultCompanyID = $companies->getDefaultCompany();
if ($defaultCompanyID !== false)
{
$defaultCompanyRS = $companies->get($defaultCompanyID);
}
else
{
$defaultCompanyRS = array();
}
if (!eval(Hooks::get('CONTACTS_ADD'))) return;
$this->_template->assign('defaultCompanyID', $defaultCompanyID);
$this->_template->assign('defaultCompanyRS', $defaultCompanyRS);
$this->_template->assign('active', $this);
$this->_template->assign('extraFieldRS', $extraFieldRS);
$this->_template->assign('subActive', 'Add Contact');
$this->_template->assign('companyRS', $companyRS);
$this->_template->assign('reportsToRS', $reportsToRS);
$this->_template->assign('selectedCompanyID', $selectedCompanyID);
$this->_template->assign('sessionCookie', $_SESSION['CATS']->getCookie());
$this->_template->display('./modules/contacts/Add.tpl');
}
/*
* Called by handleRequest() to process saving / submitting the add page.
*/
private function onAdd()
{
/* Bail if we don't have add permision. */
if ($this->_accessLevel < ACCESS_LEVEL_EDIT)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
/* Bail out if we don't have a valid company ID. */
if (!$this->isRequiredIDValid('companyID', $_POST))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid company ID.');
}
$formattedPhoneWork = StringUtility::extractPhoneNumber(
$this->getTrimmedInput('phoneWork', $_POST)
);
if (!empty($formattedPhoneWork))
{
$phoneWork = $formattedPhoneWork;
}
else
{
$phoneWork = $this->getTrimmedInput('phoneWork', $_POST);
}
$formattedPhoneCell = StringUtility::extractPhoneNumber(
$this->getTrimmedInput('phoneCell', $_POST)
);
if (!empty($formattedPhoneCell))
{
$phoneCell = $formattedPhoneCell;
}
else
{
$phoneCell = $this->getTrimmedInput('phoneCell', $_POST);
}
$formattedPhoneOther = StringUtility::extractPhoneNumber(
$this->getTrimmedInput('phoneOther', $_POST)
);
if (!empty($formattedPhoneOther))
{
$phoneOther = $formattedPhoneOther;
}
else
{
$phoneOther = $this->getTrimmedInput('phoneOther', $_POST);
}
$companyID = $_POST['companyID'];
$firstName = $this->getTrimmedInput('firstName', $_POST);
$lastName = $this->getTrimmedInput('lastName', $_POST);
$title = $this->getTrimmedInput('title', $_POST);
$department = $this->getTrimmedInput('department', $_POST);
$reportsTo = $this->getTrimmedInput('reportsTo', $_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);
$notes = $this->getTrimmedInput('notes', $_POST);
/* Hot contact? */
$isHot = $this->isChecked('isHot', $_POST);
/* Departments list editor. */
$departmentsCSV = $this->getTrimmedInput('departmentsCSV', $_POST);
/* Bail out if any of the required fields are empty. */
if (empty($firstName) || empty($lastName) || empty($title))
{
CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'Required fields are missing.');
}
/* Update departments. */
$companies = new Companies($this->_siteID);
$departments = $companies->getDepartments($companyID);
$departmentsDifferences = ListEditor::getDifferencesFromList(
$departments, 'name', 'departmentID', $departmentsCSV
);
$companies->updateDepartments($companyID, $departmentsDifferences);
if (!eval(Hooks::get('CONTACTS_ON_ADD_PRE'))) return;
$contacts = new Contacts($this->_siteID);
$contactID = $contacts->add(
$companyID, $firstName, $lastName, $title, $department, $reportsTo,
$email1, $email2, $phoneWork, $phoneCell, $phoneOther, $address,
$city, $state, $zip, $isHot, $notes, $this->_userID, $this->_userID
);
if ($contactID <= 0)
{
CommonErrors::fatal(COMMONERROR_RECORDERROR, $this, 'Failed to add contact.');
}
/* Update extra fields. */
$contacts->extraFields->setValuesOnEdit($contactID);
if (!eval(Hooks::get('CONTACTS_ON_ADD_POST'))) return;
if (isset($_GET['v']) && $_GET['v'] != -1)
{
CATSUtility::transferRelativeURI(
'm=companies&a=show&companyID=' . $_GET['v']
);
}
else
{
CATSUtility::transferRelativeURI(
'm=contacts&a=show&contactID=' . $contactID
);
}
}
/*
* Called by handleRequest() to process loading the edit page.
*/
private function edit()
{
if ($this->_accessLevel < ACCESS_LEVEL_EDIT)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
/* Bail out if we don't have a valid contact ID. */
if (!$this->isRequiredIDValid('contactID', $_GET))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.');
}
$contactID = $_GET['contactID'];
$contacts = new Contacts($this->_siteID);
$data = $contacts->getForEditing($contactID);
/* Bail out if we got an empty result set. */
if (empty($data))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'The specified contact ID could not be found.');
}
$companies = new Companies($this->_siteID);
$companiesRS = $companies->getSelectList();
$users = new Users($this->_siteID);
$usersRS = $users->getSelectList();
/* Add an MRU entry. */
$_SESSION['CATS']->getMRU()->addEntry(
DATA_ITEM_CONTACT, $contactID, $data['firstName'] . ' ' . $data['lastName']
);
/* Get extra fields. */
$extraFieldRS = $contacts->extraFields->getValuesForEdit($contactID);
/* Get departments. */
$departmentsRS = $companies->getDepartments($data['companyID']);
$departmentsString = ListEditor::getStringFromList($departmentsRS, 'name');
$emailTemplates = new EmailTemplates($this->_siteID);
$statusChangeTemplateRS = $emailTemplates->getByTag(
'EMAIL_TEMPLATE_OWNERSHIPASSIGNCONTACT'
);
if (!isset($statusChangeTemplateRS['disabled']) || $statusChangeTemplateRS['disabled'] == 1)
{
$emailTemplateDisabled = true;
}
else
{
$emailTemplateDisabled = false;
}
$reportsToRS = $contacts->getAll(-1, $data['companyID']);
if ($this->_accessLevel == ACCESS_LEVEL_DEMO)
{
$canEmail = false;
}
else
{
$canEmail = true;
}
$companies = new Companies($this->_siteID);
$defaultCompanyID = $companies->getDefaultCompany();
if ($defaultCompanyID !== false)
{
$defaultCompanyRS = $companies->get($defaultCompanyID);
}
else
{
$defaultCompanyRS = array();
}
if (!eval(Hooks::get('CONTACTS_EDIT'))) return;
$this->_template->assign('defaultCompanyID', $defaultCompanyID);
$this->_template->assign('defaultCompanyRS', $defaultCompanyRS);
$this->_template->assign('canEmail', $canEmail);
$this->_template->assign('emailTemplateDisabled', $emailTemplateDisabled);
$this->_template->assign('active', $this);
$this->_template->assign('data', $data);
$this->_template->assign('companiesRS', $companiesRS);
$this->_template->assign('extraFieldRS', $extraFieldRS);
$this->_template->assign('departmentsRS', $departmentsRS);
$this->_template->assign('departmentsString', $departmentsString);
$this->_template->assign('usersRS', $usersRS);
$this->_template->assign('reportsToRS', $reportsToRS);
$this->_template->assign('contactID', $contactID);
$this->_template->assign('sessionCookie', $_SESSION['CATS']->getCookie());
$this->_template->display('./modules/contacts/Edit.tpl');
}
/*
* Called by handleRequest() to process saving / submitting the edit page.
*/
private function onEdit()
{
if ($this->_accessLevel < ACCESS_LEVEL_EDIT)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
/* Bail out if we don't have a valid contact ID. */
if (!$this->isRequiredIDValid('contactID', $_POST))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.');
}
/* Bail out if we don't have a valid company ID. */
if (!$this->isRequiredIDValid('companyID', $_POST))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid company ID.');
}
/* 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.');
}
$contactID = $_POST['contactID'];
$companyID = $_POST['companyID'];
$owner = $_POST['owner'];
$formattedPhoneWork = StringUtility::extractPhoneNumber(
$this->getTrimmedInput('phoneWork', $_POST)
);
if (!empty($formattedPhoneWork))
{
$phoneWork = $formattedPhoneWork;
}
else
{
$phoneWork = $this->getTrimmedInput('phoneWork', $_POST);
}
$formattedPhoneCell = StringUtility::extractPhoneNumber(
$this->getTrimmedInput('phoneCell', $_POST)
);
if (!empty($formattedPhoneCell))
{
$phoneCell = $formattedPhoneCell;
}
else
{
$phoneCell = $this->getTrimmedInput('phoneCell', $_POST);
}
$formattedPhoneOther = StringUtility::extractPhoneNumber(
$this->getTrimmedInput('phoneOther', $_POST)
);
if (!empty($formattedPhoneOther))
{
$phoneOther = $formattedPhoneOther;
}
else
{
$phoneOther = $this->getTrimmedInput('phoneOther', $_POST);
}
$contacts = new Contacts($this->_siteID);
if ($this->isChecked('ownershipChange', $_POST) && $owner > 0)
{
$contactDetails = $contacts->get($contactID);
$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_OWNERSHIPASSIGNCONTACT'
);
if (empty($statusChangeTemplateRS) ||
empty($statusChangeTemplateRS['textReplaced']))
{
$statusChangeTemplate = '';
}
else
{
$statusChangeTemplate = $statusChangeTemplateRS['textReplaced'];
}
/* Replace e-mail template variables. */
$stringsToFind = array(
'%CONTOWNER%',
'%CONTFIRSTNAME%',
'%CONTFULLNAME%',
'%CONTCLIENTNAME%',
'%CONTCATSURL%'
);
$replacementStrings = array(
$ownerDetails['fullName'],
$contactDetails['firstName'],
$contactDetails['firstName'] . ' ' . $contactDetails['lastName'],
$contactDetails['companyName'],
'<a href="http://' . $_SERVER['HTTP_HOST'] . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')) . '?m=contacts&a=show&contactID=' . $contactID . '">'.
'http://' . $_SERVER['HTTP_HOST'] . substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '?')) . '?m=contacts&a=show&contactID=' . $contactID . '</a>'
);
$statusChangeTemplate = str_replace(
$stringsToFind,
$replacementStrings,
$statusChangeTemplate
);
$email = $statusChangeTemplate;
}
else
{
$email = '';
$emailAddress = '';
}
}
else
{
$email = '';
$emailAddress = '';
}
$firstName = $this->getTrimmedInput('firstName', $_POST);
$lastName = $this->getTrimmedInput('lastName', $_POST);
$title = $this->getTrimmedInput('title', $_POST);
$department = $this->getTrimmedInput('department', $_POST);
$reportsTo = $this->getTrimmedInput('reportsTo', $_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);
$notes = $this->getTrimmedInput('notes', $_POST);
$isHot = $this->isChecked('isHot', $_POST);
$leftCompany = $this->isChecked('leftCompany', $_POST);
/* Departments list editor. */
$departmentsCSV = $this->getTrimmedInput('departmentsCSV', $_POST);
/* Bail out if any of the required fields are empty. */
if (empty($firstName) || empty($lastName) || empty($title))
{
CommonErrors::fatal(COMMONERROR_MISSINGFIELDS, $this, 'Required fields are missing.');
}
if (!eval(Hooks::get('CONTACTS_ON_EDIT_PRE'))) return;
/* Update departments. */
$companies = new Companies($this->_siteID);
$departments = $companies->getDepartments($companyID);
$departmentsDifferences = ListEditor::getDifferencesFromList(
$departments, 'name', 'departmentID', $departmentsCSV
);
$companies->updateDepartments($companyID, $departmentsDifferences);
if (!$contacts->update($contactID, $companyID, $firstName, $lastName,
$title, $department, $reportsTo, $email1, $email2, $phoneWork, $phoneCell,
$phoneOther, $address, $city, $state, $zip, $isHot,
$leftCompany, $notes, $owner, $email, $emailAddress))
{
CommonErrors::fatal(COMMONERROR_RECORDERROR, $this, 'Failed to update contact.');
}
/* Update extra fields. */
$contacts->extraFields->setValuesOnEdit($contactID);
if (!eval(Hooks::get('CONTACTS_ON_EDIT_POST'))) return;
CATSUtility::transferRelativeURI(
'm=contacts&a=show&contactID=' . $contactID
);
}
/*
* Called by handleRequest() to process deleting a contact.
*/
private function onDelete()
{
if ($this->_accessLevel < ACCESS_LEVEL_DELETE)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
/* Bail out if we don't have a valid contact ID. */
if (!$this->isRequiredIDValid('contactID', $_GET))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.');
}
$contactID = $_GET['contactID'];
if (!eval(Hooks::get('CONTACTS_DELETE_PRE'))) return;
$contacts = new Contacts($this->_siteID);
$contacts->delete($contactID);
/* Delete the MRU entry if present. */
$_SESSION['CATS']->getMRU()->removeEntry(
DATA_ITEM_CONTACT, $contactID
);
if (!eval(Hooks::get('CONTACTS_DELETE_POST'))) return;
CATSUtility::transferRelativeURI('m=contacts&a=listByView');
}
/*
* Called by handleRequest() to process loading the search page.
*/
private function search()
{
$savedSearches = new SavedSearches($this->_siteID);
$savedSearchRS = $savedSearches->get(DATA_ITEM_CONTACT);
if (!eval(Hooks::get('CONTACTS_SEARCH'))) return;
$this->_template->assign('wildCardString', '');
$this->_template->assign('savedSearchRS', $savedSearchRS);
$this->_template->assign('active', $this);
$this->_template->assign('subActive', 'Search Contacts');
$this->_template->assign('isResultsMode', false);
$this->_template->assign('wildCardContactName', '');
$this->_template->assign('wildCardCompanyName', '');
$this->_template->assign('wildCardContactTitle', '');
$this->_template->assign('mode', '');
$this->_template->display('./modules/contacts/Search.tpl');
}
/*
* Called by handleRequest() to process displaying the search results.
*/
private function onSearch()
{
$wildCardContactName = '';
$wildCardCompanyName = '';
$wildCardContactTitle = '';
/* Bail out to prevent an error if the GET string doesn't even contain
* a field named 'wildCardString' at all.
*/
if (!isset($_GET['wildCardString']))
{
CommonErrors::fatal(COMMONERROR_WILDCARDSTRING, $this, 'No wild card string specified.');
}
$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 = 'lastName';
}
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 ContactsSearch($this->_siteID);
switch ($mode)
{
case 'searchByFullName':
$wildCardContactName = $query;
$rs = $search->byFullName($query, $sortBy, $sortDirection);
break;
case 'searchByCompanyName':
$wildCardCompanyName = $query;
$rs = $search->byCompanyName($query, $sortBy, $sortDirection);
break;
case 'searchByTitle':
$wildCardContactTitle = $query;
$rs = $search->byTitle($query, $sortBy, $sortDirection);
break;
default:
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid search mode.');
break;
}
foreach ($rs as $rowIndex => $row)
{
if ($row['isHotContact'] == 1)
{
$rs[$rowIndex]['linkClassContact'] = 'jobLinkHot';
}
else
{
$rs[$rowIndex]['linkClassContact'] = 'jobLinkCold';
}
if ($row['leftCompany'] == 1)
{
$rs[$rowIndex]['linkClassCompany'] = 'jobLinkDead';
}
else if ($row['isHotCompany'] == 1)
{
$rs[$rowIndex]['linkClassCompany'] = 'jobLinkHot';
}
else
{
$rs[$rowIndex]['linkClassCompany'] = 'jobLinkCold';
}
if (!empty($row['ownerFirstName']))
{
$rs[$rowIndex]['ownerAbbrName'] = StringUtility::makeInitialName(
$row['ownerFirstName'],
$row['ownerLastName'],
false,
LAST_NAME_MAXLEN
);
}
else
{
$rs[$rowIndex]['ownerAbbrName'] = 'None';
}
}
$contactIDs = implode(',', ResultSetUtility::getColumnValues($rs, 'contactID'));
$exportForm = ExportUtility::getForm(
DATA_ITEM_CONTACT, $contactIDs, 40, 15
);
/* Save the search. */
$savedSearches = new SavedSearches($this->_siteID);
$savedSearches->add(
DATA_ITEM_CONTACT,
$query,
$_SERVER['REQUEST_URI'],
false
);
$savedSearchRS = $savedSearches->get(DATA_ITEM_CONTACT);
$query = urlencode(htmlspecialchars($query));
if (!eval(Hooks::get('CONTACTS_ON_SEARCH'))) return;
$this->_template->assign('savedSearchRS', $savedSearchRS);
$this->_template->assign('active', $this);
$this->_template->assign('pager', $searchPager);
$this->_template->assign('exportForm', $exportForm);
$this->_template->assign('subActive', 'Search Contacts');
$this->_template->assign('rs', $rs);
$this->_template->assign('isResultsMode', true);
$this->_template->assign('wildCardString', $query);
$this->_template->assign('wildCardContactName', $wildCardContactName);
$this->_template->assign('wildCardCompanyName', $wildCardCompanyName);
$this->_template->assign('wildCardContactTitle', $wildCardContactTitle);
$this->_template->assign('mode', $mode);
$this->_template->display('./modules/contacts/Search.tpl');
}
/*
* Called by handleRequest() to process loading the cold call list.
*/
private function showColdCallList()
{
$contacts = new Contacts($this->_siteID);
$rs = $contacts->getColdCallList();
if (!eval(Hooks::get('CONTACTS_COLD_CALL_LIST'))) return;
$this->_template->assign('active', $this);
$this->_template->assign('subActive', 'Cold Call List');
$this->_template->assign('rs', $rs);
$this->_template->display('./modules/contacts/ColdCallList.tpl');
}
//TODO: Document me.
private function addActivityScheduleEvent()
{
if ($this->_accessLevel < ACCESS_LEVEL_EDIT)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
/* Bail out if we don't have a valid candidate ID. */
if (!$this->isRequiredIDValid('contactID', $_GET))
{
CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.');
}
$contactID = $_GET['contactID'];
$contacts = new Contacts($this->_siteID);
$contactData = $contacts->get($contactID);
$regardingRS = $contacts->getJobOrdersArray($contactID);
$calendar = new Calendar($this->_siteID);
$calendarEventTypes = $calendar->getAllEventTypes();
/* Are we in "Only Schedule Event" mode? */
$onlyScheduleEvent = $this->isChecked('onlyScheduleEvent', $_GET);
if (!eval(Hooks::get('CONTACTS_ADD_ACTIVITY_SCHEDULE_EVENT'))) return;
if (SystemUtility::isSchedulerEnabled() && !$_SESSION['CATS']->isDemo())
{
$allowEventReminders = true;
}
else
{
$allowEventReminders = false;
}
$this->_template->assign('contactID', $contactID);
$this->_template->assign('regardingRS', $regardingRS);
$this->_template->assign('allowEventReminders', $allowEventReminders);
$this->_template->assign('userEmail', $_SESSION['CATS']->getEmail());
$this->_template->assign('onlyScheduleEvent', $onlyScheduleEvent);
$this->_template->assign('calendarEventTypes', $calendarEventTypes);
$this->_template->assign('isFinishedMode', false);
$this->_template->display(
'./modules/contacts/AddActivityScheduleEventModal.tpl'
);
}
//TODO: Document me.
private function onAddActivityScheduleEvent()
{
if ($this->_accessLevel < ACCESS_LEVEL_EDIT)
{
CommonErrors::fatal(COMMONERROR_PERMISSION, $this, 'Invalid user level for action.');
}
/* Bail out if we don't have a valid regardingjob order ID. */
if (!$this->isOptionalIDValid('regardingID', $_POST))
{
CommonErrors::fatalModal(COMMONERROR_BADINDEX, $this, 'Invalid job order ID.');
}
$regardingID = $_POST['regardingID'];
$this->_addActivityScheduleEvent($regardingID);
}
/*
* Called by handleRequest() to process downloading of a contact's vCard.
*
* Example vCard output in doc/NOTES.
*/
private function downloadVCard()
{
/* Bail out if we don't have a valid contact ID. */
if (!$this->isRequiredIDValid('contactID', $_GET))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'Invalid contact ID.');
}
$contactID = $_GET['contactID'];
$contacts = new Contacts($this->_siteID);
$contact = $contacts->get($contactID);
$companies = new Companies($this->_siteID);
$company = $companies->get($contact['companyID']);
/* Bail out if we got an empty result set. */
if (empty($contact))
{
CommonErrors::fatal(COMMONERROR_BADINDEX, $this, 'The specified contact ID could not be found.');
}
/* Create a new vCard. */
$vCard = new VCard();
$vCard->setName($contact['lastName'], $contact['firstName']);
if (!empty($contact['phoneWork']))
{
$vCard->setPhoneNumber($contact['phoneWork'], 'PREF;WORK;VOICE');
}
if (!empty($contact['phoneCell']))
{
$vCard->setPhoneNumber($contact['phoneCell'], 'CELL;VOICE');
}
/* FIXME: Add fax to contacts and use setPhoneNumber('WORK;FAX') here */
$addressLines = explode("\n", $contact['address']);
$address1 = trim($addressLines[0]);
if (isset($addressLines[1]))
{
$address2 = trim($addressLines[1]);
}
else
{
$address2 = '';
}
$vCard->setAddress(
$address1, $address2, $contact['city'],
$contact['state'], $contact['zip']
);
if (!empty($contact['email1']))
{
$vCard->setEmail($contact['email1']);
}
if (!empty($company['url']))
{
$vCard->setURL($company['url']);
}
$vCard->setTitle($contact['title']);
$vCard->setOrganization($company['name']);
if (!eval(Hooks::get('CONTACTS_GET_VCARD'))) return;
$vCard->printVCardWithHeaders();
}
/**
* Formats SQL result set for display. This is factored out for code
* clarity.
*
* @param array result set from listByView()
* @return array formatted result set
*/
private function _formatListByViewResults($resultSet)
{
if (empty($resultSet))
{
return $resultSet;
}
foreach ($resultSet as $rowIndex => $row)
{
if (!empty($resultSet[$rowIndex]['ownerFirstName']))
{
$resultSet[$rowIndex]['ownerAbbrName'] = StringUtility::makeInitialName(
$resultSet[$rowIndex]['ownerFirstName'],
$resultSet[$rowIndex]['ownerLastName'],
false,
LAST_NAME_MAXLEN
);
}
else
{
$resultSet[$rowIndex]['ownerAbbrName'] = 'None';
}
/* Hot contacts [can] have different title styles than normal
* companies.
*/
if ($resultSet[$rowIndex]['isHotContact'] == 1)
{
$resultSet[$rowIndex]['linkClassContact'] = 'jobLinkHot';
}
else
{
$resultSet[$rowIndex]['linkClassContact'] = 'jobLinkCold';
}
/* Strikethrough on no longer associated companies takes priority
* over hot companies.
*/
if ($resultSet[$rowIndex]['leftCompany'] == 1)
{
$resultSet[$rowIndex]['linkClassCompany'] = 'jobLinkDead';
}
else if ($resultSet[$rowIndex]['isHotCompany'] == 1)
{
$resultSet[$rowIndex]['linkClassCompany'] = 'jobLinkHot';
}
else
{
$resultSet[$rowIndex]['linkClassCompany'] = 'jobLinkCold';
}
/* Truncate Company Name column */
if (strlen($resultSet[$rowIndex]['companyName']) > self::TRUNCATE_CLIENT_NAME)
{
$resultSet[$rowIndex]['companyName'] = substr(
$resultSet[$rowIndex]['companyName'], 0, self::TRUNCATE_CLIENT_NAME
) . "...";
}
/* Truncate Title column */
if (strlen($resultSet[$rowIndex]['title']) > self::TRUNCATE_TITLE)
{
$resultSet[$rowIndex]['title'] = substr(
$resultSet[$rowIndex]['title'], 0, self::TRUNCATE_TITLE
) . "...";
}
}
if (!eval(Hooks::get('CONTACTS_FORMAT_LIST_BY_VIEW'))) return;
return $resultSet;
}
/**
* 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'
);
}
}
?>