" method="POST"> <div id="phone_bg"> <!-- Background Image of Iphone --> <div id="phone_screen"> <!-- Screen--> <div id="screen_content"> <!-- Message / Keyboard Area --> <div id="title_area"> <span class="title"><?php echo $chatTitle; ?> </span> </div> <div id="message_area"> <?php echo parseHistory($history); echo '<script type="text/javascript">'; echo 'scroll();'; echo '</script>'; ?> </div> <div id="keyboard_area"> <textarea class="input_area" name="input"></textarea> <input type="reset" name="clear" class="formbutton" value="Clear" style="margin-left:5px;margin-right:5px;" /> <input type="submit" name="submit" class="formbutton" value="Send" style="margin-right:5px;"/> </div> </div> </div> </div>
public function customAjax($id, $data) { global $dbh; global $TYPES; global $SETTINGS; $return = ['status' => 'success']; if ($data['subAction'] == 'view') { //view subAction if ($data['subType'] == 'paystub') { $sth = $dbh->prepare('SELECT date, grossPay, firstDate, lastDate, payType, payAmount FROM paystubs, timesheets WHERE paystubID = :paystubID AND paystubs.timesheetID = timesheets.timesheetID'); $sth->execute([':paystubID' => $data['subID']]); $row = $sth->fetch(); $return['date'] = formatDate($row['date']); $return['grossPay'] = formatCurrency($row['grossPay'], true); $return['startDate'] = formatDate($row['firstDate']); $return['endDate'] = formatDate($row['lastDate']); $parsed = self::parseValue('employee', ['payType' => $row['payType'], 'payAmount' => $row['payAmount']]); $return['payType'] = $parsed['payType']; $return['payAmount'] = $parsed['payAmount']; $sth = $dbh->prepare('SELECT SUM(regularHours) AS regularHours, SUM(overtimeHours) AS overtimeHours, SUM(holidayHours) AS holidayHours, SUM(vacationHours) AS vacationHours FROM timesheetHours, paystubs WHERE paystubID = :paystubID AND paystubs.timesheetID = timesheetHours.timesheetID'); $sth->execute([':paystubID' => $data['subID']]); $row = $sth->fetch(); $return['regularHours'] = formatNumber($row['regularHours'] + 0) . ' hours'; $return['overtimeHours'] = formatNumber($row['overtimeHours'] + 0) . ' hours'; $return['holidayHours'] = formatNumber($row['holidayHours'] + 0) . ' hours'; $return['vacationHours'] = formatNumber($row['vacationHours'] + 0) . ' hours'; } elseif ($data['subType'] == 'timesheet') { $sth = $dbh->prepare('SELECT firstDate, lastDate, status FROM timesheets WHERE timesheetID = :timesheetID'); $sth->execute([':timesheetID' => $data['subID']]); $row = $sth->fetch(); $firstDate = $row['firstDate']; $lastDate = $row['lastDate']; $return['timesheetStatus'] = $row['status']; //this will fill in days with no hours automatically, no row in timesheetHours is needed $sth = $dbh->prepare('SELECT date, regularHours, overtimeHours, holidayHours, vacationHours FROM timesheetHours WHERE timesheetID = :timesheetID'); $sth->execute([':timesheetID' => $data['subID']]); while ($row = $sth->fetch()) { $hours[$row['date']] = [$row['regularHours'], $row['overtimeHours'], $row['holidayHours'], $row['vacationHours']]; } while ($firstDate <= $lastDate) { $table[$firstDate] = isset($hours[$firstDate]) ? $hours[$firstDate] : [0, 0, 0, 0]; $firstDate += 86400; } $typeArr = ['r', 'o', 'h', 'v']; $return['html'] = ''; foreach ($table as $day => $dayArr) { if ($return['timesheetStatus'] == 'E' || $return['timesheetStatus'] == 'P') { $return['html'] .= '<tr><td>' . formatDate($day) . ' ' . date('l', $day) . '</td>'; for ($i = 0; $i < 4; $i++) { $temp = empty($dayArr[$i] + 0) ? '' : formatNumber($dayArr[$i] + 0); $return['html'] .= '<td><input type="text" name="' . $typeArr[$i] . $day . '" autocomplete="off" value="' . $temp . '"></td>'; } $return['html'] .= '</tr>'; } else { $return['html'] .= '<tr><td>' . formatDate($day) . ' ' . date('l', $day) . '</td>'; for ($i = 0; $i < 4; $i++) { $temp = empty($dayArr[$i] + 0) ? '' : formatNumber($dayArr[$i] + 0); $return['html'] .= '<td>' . $temp . '</td>'; } $return['html'] .= '</tr>'; } } } } elseif ($data['subAction'] == 'edit') { if ($data['subType'] == 'timesheet') { $subID = $data['subID']; unset($data['subID']); unset($data['subAction']); unset($data['subType']); //make sure this timesheet has the correct status, get dates for later $sth = $dbh->prepare('SELECT employeeID, firstDate, lastDate, status FROM timesheets WHERE timesheetID = :timesheetID'); $sth->execute([':timesheetID' => $subID]); $row = $sth->fetch(); $employeeID = $row['employeeID']; $firstDate = $row['firstDate']; $lastDate = $row['lastDate']; $timesheetStatus = $row['status']; if ($timesheetStatus == 'E' || $timesheetStatus == 'P') { foreach ($data as $key => $value) { $hourType = substr($key, 0, 1); $ts = substr($key, 1); $value = $value == '' ? 0 : $value; //timesheet is not (and as far as I can think, cannot due to the many variable fields) be a subtype, so we need to manually clean and verify the data $value = str_replace($SETTINGS['thousandsSeparator'], '', $value); $value = str_replace($SETTINGS['decimalFormat'], '.', $value); if (filter_var($value, FILTER_VALIDATE_FLOAT) === false) { $return['status'] = 'fail'; $return[$key] = 'Must be a decimal'; } else { $temp = strrpos($value, '.'); if ($temp === false) { $value .= '.'; $temp = strrpos($value, '.'); } $length = strlen(substr($value, $temp + 1)); if ($length < 2) { $value .= str_repeat('0', 2 - $length); $length = strlen(substr($value, $temp + 1)); } if ($length > 2) { $return['status'] = 'fail'; $return[$key] = 'Must have 2 or fewer digits after the decimal'; } else { if ($value < 0 || $value > 24) { $return['status'] = 'fail'; $return[$key] = 'Must be between 0 and 24'; } } } $typeArr = ['r', 'o', 'h', 'v']; $i = array_search($hourType, $typeArr); if ($i === false) { //if we don't get the right hour type, fail with no error because this would never happen normally $return['status'] = 'fail'; } else { $newHours[$ts][$i] = $value; } } } else { $return['status'] = 'fail'; } //get old hours and then do the update if ($return['status'] != 'fail') { $sth = $dbh->prepare('SELECT date, regularHours, overtimeHours, holidayHours, vacationHours FROM timesheetHours WHERE timesheetID = :timesheetID'); $sth->execute([':timesheetID' => $subID]); while ($row = $sth->fetch()) { $oldHours[$row['date']] = [$row['regularHours'], $row['overtimeHours'], $row['holidayHours'], $row['vacationHours']]; } while ($firstDate <= $lastDate) { $oldHours[$firstDate] = isset($oldHours[$firstDate]) ? $oldHours[$firstDate] : [0, 0, 0, 0]; $firstDate += 86400; } //TODO: check to see if employee has enough vacation time to make the change //need to do it in a foreach loop right here because we need the oldHours to detect the change in vacation time and also do it before we start changing the db //loop through old hours because we know the ts will be right, whereas the ts in new hours could be malicious foreach ($oldHours as $key => $value) { if ($oldHours[$key][0] != $newHours[$key][0] || $oldHours[$key][1] != $newHours[$key][1] || $oldHours[$key][2] != $newHours[$key][2] || $oldHours[$key][3] != $newHours[$key][3]) { if ($oldHours[$key][0] == 0 && $oldHours[$key][1] == 0 && $oldHours[$key][2] == 0 && $oldHours[$key][3] == 0) { //no hours -> some hours $sth = $dbh->prepare('INSERT INTO timesheetHours (timesheetID, date, regularHours, overtimeHours, holidayHours, vacationHours) VALUES(:timesheetID, :date, :regular, :overtime, :holiday, :vacation)'); $sth->execute([':timesheetID' => $subID, ':date' => $key, ':regular' => $newHours[$key][0], ':overtime' => $newHours[$key][1], ':holiday' => $newHours[$key][2], ':vacation' => $newHours[$key][3]]); } elseif ($newHours[$key][0] == 0 && $newHours[$key][1] == 0 && $newHours[$key][2] == 0 && $newHours[$key][3] == 0) { //some hours -> no hours $sth = $dbh->prepare('DELETE FROM timesheetHours WHERE timesheetID = :timesheetID AND date = :date'); $sth->execute([':timesheetID' => $subID, ':date' => $key]); } else { //some hours -> different hours $sth = $dbh->prepare('UPDATE timesheetHours SET regularHours = :regular, overtimeHours = :overtime, holidayHours = :holiday, vacationHours = :vacation WHERE timesheetID = :timesheetID AND date = :date'); $sth->execute([':regular' => $newHours[$key][0], ':overtime' => $newHours[$key][1], ':holiday' => $newHours[$key][2], ':vacation' => $newHours[$key][3], ':timesheetID' => $subID, ':date' => $key]); } } } } } } elseif ($data['subAction'] == 'approve') { if ($data['subType'] == 'timesheet') { $sth = $dbh->prepare('UPDATE timesheets SET status = "A" WHERE timesheetID = :timesheetID'); $sth->execute([':timesheetID' => $data['subID']]); } } elseif ($data['subAction'] == 'changesMadeHistory') { $return['html'] = ''; $limit = (int) $_POST['limit'] == -1 ? 100000 : (int) $_POST['limit']; //cast as int because we can't use a placeholder for LIMIT $sth = $dbh->prepare('SELECT * FROM changes WHERE employeeID = :employeeID ORDER BY changeTime DESC LIMIT ' . $limit); $sth->execute([':employeeID' => $id]); while ($row = $sth->fetch()) { $parsed = parseHistory($row['type'], [$row]); $return['html'] .= '<tr><td data-sort="' . $row['changeTime'] . '">' . formatDateTime($row['changeTime']) . '</td>'; $return['html'] .= '<td>' . getLinkedName($row['type'], $row['id']) . '</td>'; $return['html'] .= '<td>' . $TYPES[$row['type']]['formalName'] . '</td>'; $return['html'] .= '<td>' . $parsed[0]['data'] . '</td></tr>'; } } return $return; }
Inputs: Outputs: */ if ($_POST['action'] == 'history') { $return = ['status' => 'success', 'html' => '']; $limit = (int) $_POST['limit']; //cast as int because we can't use a placeholder for LIMIT $limit = $limit < 0 || $limit > 10000 ? 10000 : $limit; $sth = $dbh->prepare('SELECT * FROM changes WHERE type = :type AND id = :id ORDER BY changeTime DESC LIMIT ' . $limit); $sth->execute([':type' => $_POST['type'], ':id' => $_POST['id']]); $result = $sth->fetchAll(); $parsed = parseHistory($_POST['type'], $result); foreach ($parsed as $row) { $return['html'] .= '<tr><td data-sort="' . $row['changeTime'] . '">' . formatDateTime($row['changeTime']) . '</td>'; $return['html'] .= '<td>' . getLinkedName('employee', $row['employeeID']) . '</td>'; $return['html'] .= '<td>' . $row['data'] . '</td></tr>'; } echo json_encode($return); } /* Function: addAttachment Inputs: Outputs: */ if ($_POST['action'] == 'addAttachment') { $return = ['status' => 'fail']; if ($_FILES['uploadFile']['error'] == 0) {
public function customAjax($id, $data) { global $dbh; global $TYPES; $return = ['status' => 'success']; if ($data['subAction'] == 'add') { //add subAction //TODO: this could possibly be a subType, right now it looks like the dateTime verify type is stopping it, but I'll wait to see when I do more here if ($data['date'] == '') { $return['status'] = 'fail'; $return['date'] = 'Required'; } if ($data['startTime'] == '') { $return['status'] = 'fail'; $return['startTime'] = 'Required'; } if ($data['endTime'] == '') { $return['status'] = 'fail'; $return['endTime'] = 'Required'; } $startDate = DateTime::createFromFormat($SETTINGS['dateTimeFormat'] . '|', $data['date'] . ' ' . $data['startTime']); $startTS = $startDate->getTimestamp(); $endDate = DateTime::createFromFormat($SETTINGS['dateTimeFormat'] . '|', $data['date'] . ' ' . $data['endTime']); $endTS = $endDate->getTimestamp(); if ($return['status'] != 'fail') { if ($startDate === false || $endDate === false) { $return['status'] = 'fail'; $return['date'] = 'Unrecognized date/time format.'; } else { if ($endTS < $startTS) { $return['status'] = 'fail'; $return['endTime'] = 'End Time must be after Start Time.'; } if ($return['status'] != 'fail') { $sth = $dbh->prepare('INSERT INTO vacationRequests (employeeID, submitTime, startTime, endTime, status) VALUES(:employeeID, UNIX_TIMESTAMP(), :startTime, :endTime, "P")'); $sth->execute([':employeeID' => $id, ':startTime' => $startTS, ':endTime' => $endTS]); //TODO: should a call to addChange be here? or is it already logged enough? } } } } elseif ($data['subAction'] == 'changesMadeHistory') { $return['html'] = ''; $limit = (int) $_POST['limit'] == -1 ? 100000 : (int) $_POST['limit']; //cast as int because we can't use a placeholder for LIMIT $sth = $dbh->prepare('SELECT * FROM changes WHERE employeeID = :employeeID ORDER BY changeTime DESC LIMIT ' . $limit); $sth->execute([':employeeID' => $id]); while ($row = $sth->fetch()) { $parsed = parseHistory($row['type'], [$row]); $return['html'] .= '<tr><td data-sort="' . $row['changeTime'] . '">' . formatDateTime($row['changeTime']) . '</td>'; $return['html'] .= '<td>' . getLinkedName($row['type'], $row['id']) . '</td>'; $return['html'] .= '<td>' . $TYPES[$row['type']]['formalName'] . '</td>'; $return['html'] .= '<td>' . $parsed[0]['data'] . '</td></tr>'; } } return $return; }