QwikClock is an employee time tracking app.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

api.php 7.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. <?php
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. * Simple JSON API to allow other apps to access data from this app.
  7. *
  8. * Requests can be sent via either GET or POST requests. POST is recommended
  9. * as it has a lower chance of being logged on the server, exposing unencrypted
  10. * user passwords.
  11. */
  12. require __DIR__ . '/required.php';
  13. require_once __DIR__ . '/lib/login.php';
  14. require_once __DIR__ . '/lib/userinfo.php';
  15. header("Content-Type: application/json");
  16. $username = $VARS['username'];
  17. $password = $VARS['password'];
  18. if (user_exists($username) !== true || (authenticate_user($username, $password, $errmsg) !== true && checkAPIKey($password) !== true) || account_has_permission($username, "QWIKCLOCK") !== true) {
  19. header("HTTP/1.1 403 Unauthorized");
  20. die("\"403 Unauthorized\"");
  21. }
  22. $userinfo = getUserByUsername($username);
  23. // query max results
  24. $max = 20;
  25. if (preg_match("/^[0-9]+$/", $VARS['max']) === 1 && $VARS['max'] <= 1000) {
  26. $max = (int) $VARS['max'];
  27. }
  28. switch ($VARS['action']) {
  29. case "ping":
  30. $out = ["status" => "OK", "maxresults" => $max, "pong" => true];
  31. exit(json_encode($out));
  32. case "punchin":
  33. if ($database->has('punches', ['AND' => ['uid' => $userinfo['uid'], 'out' => null]])) {
  34. die(json_encode(["status" => "ERROR", "msg" => lang("already punched in", false)]));
  35. }
  36. $shiftid = null;
  37. if ($database->has('assigned_shifts', ['uid' => $userinfo['uid']])) {
  38. $minclockintime = strtotime("now + 5 minutes");
  39. $shifts = $database->select('shifts', ["[>]assigned_shifts" => ['shiftid' => 'shiftid']], ["shifts.shiftid", "start", "end", "days"], ["AND" => ['uid' => $userinfo['uid'], 'start[<=]' => date("H:i:s", $minclockintime)]]);
  40. foreach ($shifts as $shift) {
  41. $curday = substr(date("D"), 0, 2);
  42. if (strpos($shift['days'], $curday) === FALSE) {
  43. continue;
  44. }
  45. if (strtotime($shift['end']) >= strtotime($shift['start'])) {
  46. if (strtotime("now") >= strtotime($shift['end'])) {
  47. continue; // shift is already over
  48. }
  49. }
  50. $shiftid = $shift['shiftid'];
  51. }
  52. if (is_null($shiftid)) {
  53. die(json_encode(["status" => "ERROR", "msg" => lang("not assigned to work now", false)]));
  54. }
  55. }
  56. $database->insert('punches', ['uid' => $userinfo['uid'], 'in' => date("Y-m-d H:i:s"), 'out' => null, 'notes' => '', 'shiftid' => $shiftid]);
  57. exit(json_encode(["status" => "OK", "msg" => lang("punched in", false)]));
  58. case "punchout":
  59. if (!$database->has('punches', ['AND' => ['uid' => $userinfo['uid'], 'out' => null]])) {
  60. die(json_encode(["status" => "ERROR", "msg" => lang("already punched out", false)]));
  61. }
  62. // Stop active job
  63. $database->update('job_tracking', ['end' => date("Y-m-d H:i:s")], ['AND' => ['uid' => $userinfo['uid'], 'end' => null]]);
  64. $database->update('punches', ['uid' => $userinfo['uid'], 'out' => date("Y-m-d H:i:s")], ['out' => null]);
  65. exit(json_encode(["status" => "OK", "msg" => lang("punched out", false)]));
  66. case "getassignedshifts":
  67. $shifts = $database->select('shifts', [
  68. "[>]assigned_shifts" => [
  69. "shiftid" => "shiftid"
  70. ]
  71. ], [
  72. 'shifts.shiftid',
  73. 'shiftname',
  74. 'start',
  75. 'end',
  76. 'days'
  77. ], [
  78. "uid" => $userinfo['uid']
  79. ]
  80. );
  81. for ($i = 0; $i < count($shifts); $i++) {
  82. $shifts[$i]['start_f'] = date(TIME_FORMAT, strtotime($shifts[$i]['start']));
  83. $shifts[$i]['end_f'] = date(TIME_FORMAT, strtotime($shifts[$i]['end']));
  84. $days = [];
  85. $daycodes = str_split($shifts[$i]['days'], 2);
  86. foreach ($daycodes as $day) {
  87. switch ($day) {
  88. case "Su":
  89. $days[] = lang("sunday", false);
  90. break;
  91. case "Mo":
  92. $days[] = lang("monday", false);
  93. break;
  94. case "Tu":
  95. $days[] = lang("tuesday", false);
  96. break;
  97. case "We":
  98. $days[] = lang("wednesday", false);
  99. break;
  100. case "Th":
  101. $days[] = lang("thursday", false);
  102. break;
  103. case "Fr":
  104. $days[] = lang("friday", false);
  105. break;
  106. case "Sa":
  107. $days[] = lang("saturday", false);
  108. break;
  109. }
  110. }
  111. $shifts[$i]['day_list'] = $days;
  112. }
  113. exit(json_encode(["status" => "OK", "shifts" => $shifts]));
  114. case "getjobs":
  115. $jobs = [];
  116. if ($database->count("job_groups") > 0) {
  117. require_once __DIR__ . "/lib/userinfo.php";
  118. $groups = getGroupsByUID($userinfo['uid']);
  119. $gids = [];
  120. foreach ($groups as $g) {
  121. $gids[] = $g['id'];
  122. }
  123. $jobs = $database->select('jobs', ['[>]job_groups' => ['jobid']], ['jobs.jobid (id)', 'jobname (name)', 'jobcode (code)', 'color'], ["AND" => ["OR" => ['groupid' => $gids, 'groupid #-1' => -1], 'deleted' => 0]]);
  124. } else {
  125. $jobs = $database->select('jobs', ['jobid (id)', 'jobname (name)', 'jobcode (code)', 'color'], ['deleted' => 0]);
  126. }
  127. $jobids = [];
  128. $out = [];
  129. foreach ($jobs as $job) {
  130. if (in_array($job['id'], $jobids)) {
  131. continue;
  132. }
  133. $jobids[] = $job['id'];
  134. $out[] = $job;
  135. }
  136. exit(json_encode(["status" => "OK", "jobs" => $out]));
  137. case "getactivejob":
  138. $jobs = [];
  139. $job = $database->get('job_tracking', ['[>]jobs' => ['jobid']], ['jobs.jobid (id)', 'jobname (name)', 'color', 'start'], ["AND" => ["uid" => $userinfo['uid'], 'end' => null]]);
  140. exit(json_encode(["status" => "OK", "job" => $job]));
  141. case "setjob":
  142. if (is_empty($VARS['job'])) {
  143. exit(json_encode(["status" => "ERROR", "msg" => lang("invalid job", false)]));
  144. }
  145. if ($database->count("job_groups") > 0) {
  146. require_once __DIR__ . "/lib/userinfo.php";
  147. $groups = getGroupsByUID($userinfo['uid']);
  148. $gids = [];
  149. foreach ($groups as $g) {
  150. $gids[] = $g['id'];
  151. }
  152. $job = $database->has('jobs', ['[>]job_groups' => ['jobid']], ["AND" => ["OR" => ['groupid' => $gids, 'groupid #-1' => -1], 'deleted' => 0, 'jobs.jobid' => $VARS['job']]]);
  153. } else {
  154. $job = $database->has('jobs', 'jobid', ['jobid' => $VARS['job']]);
  155. }
  156. if ($job === true) {
  157. // Stop other jobs
  158. $database->update('job_tracking', ['end' => date("Y-m-d H:i:s")], ['AND' => ['uid' => $userinfo['uid'], 'end' => null]]);
  159. $database->insert('job_tracking', ['uid' => $userinfo['uid'], 'jobid' => $VARS['job'], 'start' => date("Y-m-d H:i:s")]);
  160. exit(json_encode(["status" => "OK", "msg" => lang("job changed", false)]));
  161. } else if ($VARS['job'] == "-1") {
  162. $database->update('job_tracking', ['end' => date("Y-m-d H:i:s")], ['AND' => ['uid' => $userinfo['uid'], 'end' => null]]);
  163. exit(json_encode(["status" => "OK", "msg" => lang("job changed", false)]));
  164. } else {
  165. exit(json_encode(["status" => "ERROR", "msg" => lang("invalid job", false)]));
  166. }
  167. break;
  168. default:
  169. http_response_code(404);
  170. die("\"404 Action not found\"");
  171. }