function get_day_id($calendar, $day, $month, $year) { global $conn; $date = date('Y-m-d', strtotime("{$month}/{$day}/{$year}")); if (!$date || !$calendar) { return null; } $can_see = viewer_can_see_calendar($calendar); if (!$can_see) { // can be null or false, see comment above return $can_see; } $result = $conn->query("SELECT id FROM days WHERE date = '{$date}' AND calendar = {$calendar}"); $existing_row = $result->fetch_assoc(); if ($existing_row) { return intval($existing_row['id']); } $conn->query("INSERT INTO ids(table_name) VALUES('days')"); $new_day_id = $conn->insert_id; $conn->query("INSERT INTO days(id, date, calendar) " . "VALUES ({$new_day_id}, '{$date}', {$calendar})"); if ($conn->errno === 0) { return $new_day_id; } else { if ($conn->errno === 1062) { // There's a race condition that can happen if two people start editing // the same date at the same time, and two IDs are created for the same // row. If this happens, the UNIQUE constraint `date_calendar` should be // triggered on the second racer, and for that execution path our last // query will have failed. We will recover by re-querying for the ID here, // and deleting the extra ID we created from the `ids` table. $result = $conn->query("SELECT id FROM days WHERE date = '{$date}' AND calendar = {$calendar}"); $existing_row = $result->fetch_assoc(); $conn->query("DELETE FROM ids WHERE id = {$new_day_id}"); return intval($existing_row['id']); } } return null; }
<?php require_once 'config.php'; require_once 'auth.php'; header("Content-Type: application/json"); if ($https && !isset($_SERVER['HTTPS'])) { // We're using mod_rewrite .htaccess for HTTPS redirect; this shouldn't happen header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); exit; } if (!isset($_POST['calendar']) || !isset($_POST['subscribe'])) { exit(json_encode(array('error' => 'invalid_parameters', 'test' => $_POST))); } $calendar = (int) $_POST['calendar']; $subscribe = $_POST['subscribe'] ? 1 : 0; $can_see = viewer_can_see_calendar($calendar); if ($can_see === null) { exit(json_encode(array('error' => 'invalid_parameters'))); } if (!$can_see) { exit(json_encode(array('error' => 'invalid_credentials'))); } $viewer_id = get_viewer_id(); $time = round(microtime(true) * 1000); // in milliseconds $conn->query("INSERT INTO roles(calendar, user, " . "creation_time, last_view, role, subscribed) " . "VALUES ({$calendar}, {$viewer_id}, {$time}, {$time}, " . ROLE_VIEWED . ", {$subscribe}) ON DUPLICATE KEY UPDATE " . "creation_time = LEAST(VALUES(creation_time), creation_time), " . "last_view = GREATEST(VALUES(last_view), last_view), " . "role = GREATEST(VALUES(role), role), subscribed = VALUES(subscribed)"); exit(json_encode(array('success' => true)));