public function reportComment($request, $db) { // must be logged in to report a comment if (!isset($request->user_id) || empty($request->user_id)) { throw new Exception('You must log in to report a comment', 401); } $comment_mapper = new TalkCommentMapper($db, $request); $commentId = $this->getItemId($request); $commentInfo = $comment_mapper->getCommentInfo($commentId); if (false === $commentInfo) { throw new Exception('Comment not found', 404); } $talkId = $commentInfo['talk_id']; $eventId = $commentInfo['event_id']; $comment_mapper->userReportedComment($commentId, $request->user_id); // notify event admins $comment = $comment_mapper->getCommentById($commentId, true, true); $event_mapper = new EventMapper($db, $request); $recipients = $event_mapper->getHostsEmailAddresses($eventId); $event = $event_mapper->getEventById($eventId, true, true); $emailService = new CommentReportedEmailService($this->config, $recipients, $comment, $event); $emailService->sendEmail(); // send them to the comments collection $uri = $request->base . '/' . $request->version . '/talks/' . $talkId . "/comments"; header("Location: " . $uri, true, 202); exit; }
public function getAction($request, $db) { $event_id = $this->getItemId($request); // verbosity $verbose = $this->getVerbosity($request); // pagination settings $start = $this->getStart($request); $resultsperpage = $this->getResultsPerPage($request); if (isset($request->url_elements[4])) { switch ($request->url_elements[4]) { case 'talks': $talk_mapper = new TalkMapper($db, $request); $list = $talk_mapper->getTalksByEventId($event_id, $resultsperpage, $start, $request, $verbose); break; case 'comments': $event_comment_mapper = new EventCommentMapper($db, $request); $list = $event_comment_mapper->getEventCommentsByEventId($event_id, $resultsperpage, $start, $verbose); break; case 'talk_comments': $sort = $this->getSort($request); $talk_comment_mapper = new TalkCommentMapper($db, $request); $list = $talk_comment_mapper->getCommentsByEventId($event_id, $resultsperpage, $start, $verbose, $sort); break; default: throw new InvalidArgumentException('Unknown Subrequest', 404); break; } } else { $mapper = new EventMapper($db, $request); if ($event_id) { $list = $mapper->getEventById($event_id, $verbose); } else { // check if we're filtering if (isset($request->parameters['filter'])) { switch ($request->parameters['filter']) { case "hot": $list = $mapper->getHotEventList($resultsperpage, $start, $verbose); break; case "upcoming": $list = $mapper->getUpcomingEventList($resultsperpage, $start, $verbose); break; case "past": $list = $mapper->getPastEventList($resultsperpage, $start, $verbose); break; case "cfp": $list = $mapper->getOpenCfPEventList($resultsperpage, $start, $verbose); break; default: throw new InvalidArgumentException('Unknown event filter', 404); break; } } else { $list = $mapper->getEventList($resultsperpage, $start, $verbose); } } } return $list; }
/** * Approve a pending event by POSTing to /events/{id}/approval * * The body of this request is completely irrelevant, simply POSTing to this * endpoint is all that's needed to approve an pending event * * @param Request $request * @param PDO $db * * @return void */ public function approveAction($request, $db) { if (!isset($request->user_id)) { throw new Exception("You must be logged in to create data", 400); } $event_id = $this->getItemId($request); $event_mapper = new EventMapper($db, $request); if (!$event_mapper->thisUserCanApproveEvents()) { throw new Exception("You are not allowed to approve this event", 403); } $result = $event_mapper->approve($event_id); if (!$result) { throw new Exception("This event cannot be approved", 400); } if ($result) { // Send a notification email as we have approved $event = $event_mapper->getEventById($event_id, true)['events'][0]; $recipients = $event_mapper->getHostsEmailAddresses($event_id); $emailService = new EventApprovedEmailService($this->config, $recipients, $event); $emailService->sendEmail(); } $location = $request->base . '/' . $request->version . '/events/' . $event_id; header('Location: ' . $location, null, 204); return; }
/** * Create a talk * * This method creates a new talk after being called via the URL * "/events/[eventId]/talks" * * @param Request $request * @param PDO $db * * @throws Exception * @return array|bool */ public function createTalkAction(Request $request, PDO $db) { if (!isset($request->user_id)) { throw new Exception("You must be logged in to create data", 400); } $talk['event_id'] = $this->getItemId($request); if (empty($talk['event_id'])) { throw new Exception("POST expects a talk representation sent to a specific event URL", 400); } $event_mapper = new EventMapper($db, $request); $talk_mapper = new TalkMapper($db, $request); $talk_type_mapper = new TalkTypeMapper($db, $request); $is_admin = $event_mapper->thisUserHasAdminOn($talk['event_id']); if (!$is_admin) { throw new Exception("You do not have permission to add talks to this event", 400); } // get the event so we can get the timezone info $list = $event_mapper->getEventById($talk['event_id'], true); if (count($list['events']) == 0) { throw new Exception('Event not found', 404); } $event = $list['events'][0]; $talk['title'] = filter_var($request->getParameter('talk_title'), FILTER_SANITIZE_STRING); if (empty($talk['title'])) { throw new Exception("The talk title field is required", 400); } $talk['description'] = filter_var($request->getParameter('talk_description'), FILTER_SANITIZE_STRING); if (empty($talk['description'])) { throw new Exception("The talk description field is required", 400); } $talk['type'] = filter_var($request->getParameter('type', 'Talk'), FILTER_SANITIZE_STRING); $talk_types = $talk_type_mapper->getTalkTypesLookupList(); if (!array_key_exists($talk['type'], $talk_types)) { throw new Exception("The type '{$talk['type']}' is unknown", 400); } $talk['type_id'] = $talk_types[$talk['type']]; $start_date = filter_var($request->getParameter('start_date'), FILTER_SANITIZE_STRING); if (empty($start_date)) { throw new Exception("Please give the date and time of the talk", 400); } $tz = new DateTimeZone($event['tz_continent'] . '/' . $event['tz_place']); $talk['date'] = (new DateTime($start_date, $tz))->format('U'); $talk['language'] = filter_var($request->getParameter('language'), FILTER_SANITIZE_STRING); if (empty($talk['language'])) { // default to UK English $talk['language'] = 'English - UK'; } // When the language doesn't exist, the talk will not be found $language_mapper = new LanguageMapper($db, $request); if (!$language_mapper->isLanguageValid($talk['language'])) { throw new Exception("The language '{$talk['type']}' is unknown", 400); } $talk['duration'] = filter_var($request->getParameter('duration'), FILTER_SANITIZE_NUMBER_INT); if (empty($talk['duration'])) { $talk['duration'] = 60; } $talk['slides_link'] = filter_var($request->getParameter('slides_link'), FILTER_SANITIZE_URL); $talk['speakers'] = array_map(function ($speaker) { $speaker = filter_var($speaker, FILTER_SANITIZE_STRING); $speaker = trim($speaker); return $speaker; }, (array) $request->getParameter('speakers')); $new_id = $talk_mapper->createTalk($talk); // Update the cache count for the number of talks at this event $event_mapper->cacheTalkCount($talk['event_id']); $uri = $request->base . '/' . $request->version . '/talks/' . $new_id; header("Location: " . $uri, true, 201); $new_talk = $talk_mapper->getTalkById($new_id); return $new_talk; }
public function putAction($request, $db) { if (!isset($request->user_id)) { throw new Exception('You must be logged in to edit data', 400); } $event_id = $this->getItemId($request); if (!isset($request->url_elements[4])) { // Edit an Event $event_mapper = new EventMapper($db, $request); $existing_event = $event_mapper->getEventById($event_id, true); if (!$existing_event) { throw new Exception(sprintf('There is no event with ID "%s"', $event_id)); } if (!$event_mapper->thisUserHasAdminOn($event_id)) { throw new Exception('You are not an host for this event', 403); } // initialise a new set of fields to save $event = array("event_id" => $event_id); $errors = array(); $event['name'] = filter_var($request->getParameter("name"), FILTER_SANITIZE_STRING); if (empty($event['name'])) { $errors[] = "'name' is a required field"; } $event['description'] = filter_var($request->getParameter("description"), FILTER_SANITIZE_STRING); if (empty($event['description'])) { $errors[] = "'description' is a required field"; } $event['location'] = filter_var($request->getParameter("location"), FILTER_SANITIZE_STRING); if (empty($event['location'])) { $errors[] = "'location' is a required field (for virtual events, 'online' works)"; } $start_date = strtotime($request->getParameter("start_date")); $end_date = strtotime($request->getParameter("end_date")); if (!$start_date || !$end_date) { $errors[] = "Both 'start_date' and 'end_date' must be supplied in a recognised format"; } else { // if the dates are okay, sort out timezones $event['tz_continent'] = filter_var($request->getParameter("tz_continent"), FILTER_SANITIZE_STRING); $event['tz_place'] = filter_var($request->getParameter("tz_place"), FILTER_SANITIZE_STRING); try { // make the timezone, and read in times with respect to that $tz = new DateTimeZone($event['tz_continent'] . '/' . $event['tz_place']); $start_date = new DateTime($request->getParameter("start_date"), $tz); $end_date = new DateTime($request->getParameter("end_date"), $tz); $event['start_date'] = $start_date->format('U'); $event['end_date'] = $end_date->format('U'); } catch (Exception $e) { // the time zone isn't right $errors[] = "The fields 'tz_continent' and 'tz_place' must be supplied and valid (e.g. Europe and London)"; } } // How does it look? With no errors, we can proceed if ($errors) { throw new Exception(implode(". ", $errors), 400); } // optional fields - only check if we have no errors as we may need $tz // also only update supplied fields - but DO allow saving empty ones $href = $request->getParameter("href", false); // returns false if the value was not supplied if (false !== $href) { // we got a value, filter and save it $event['href'] = filter_var($href, FILTER_VALIDATE_URL); } $cfp_url = $request->getParameter("cfp_url", false); if (false !== $cfp_url) { // we got a value, filter and save it $event['cfp_url'] = filter_var($cfp_url, FILTER_VALIDATE_URL); } $cfp_start_date = $request->getParameter("cfp_start_date", false); if (false !== $cfp_start_date && strtotime($cfp_start_date)) { $cfp_start_date = new DateTime($cfp_start_date, $tz); $event['cfp_start_date'] = $cfp_start_date->format('U'); } $cfp_end_date = $request->getParameter("cfp_end_date", false); if (false !== $cfp_end_date && strtotime($cfp_end_date)) { $cfp_end_date = new DateTime($cfp_end_date, $tz); $event['cfp_end_date'] = $cfp_end_date->format('U'); } $latitude = $request->getParameter("latitude", false); if (false !== $latitude) { $latitude = filter_var($latitude, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); if ($latitude) { $event['latitude'] = $latitude; } } $longitude = $request->getParameter("longitude", false); if (false !== $longitude) { $longitude = filter_var($longitude, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); $event['longitude'] = $longitude; } $incoming_tag_list = $request->getParameter('tags'); if (is_array($incoming_tag_list)) { $tags = array_map(function ($tag) { $tag = filter_var($tag, FILTER_SANITIZE_STRING); $tag = trim($tag); $tag = strtolower($tag); return $tag; }, $incoming_tag_list); } $event_mapper->editEvent($event, $event_id); if (isset($tags)) { $event_mapper->setTags($event_id, $tags); } header("Location: " . $request->base . $request->path_info, NULL, 204); exit; } }
/** * Read the talk fields from the request body and validate and return an * array ready for saving to the database. * * This is common for createTalk() and editTalk(). * * @param PDO $db * @param Request $request * @param int $event_id * * @return array */ protected function getTalkDataFromRequest(PDO $db, Request $request, $event_id) { // get the event so we can get the timezone info & it $event_mapper = new EventMapper($db, $request); $list = $event_mapper->getEventById($event_id, true); if (count($list['events']) == 0) { throw new Exception('Event not found', 404); } $event = $list['events'][0]; $talk['title'] = filter_var($request->getParameter('talk_title'), FILTER_SANITIZE_STRING); if (empty($talk['title'])) { throw new Exception("The talk title field is required", 400); } $talk['description'] = filter_var($request->getParameter('talk_description'), FILTER_SANITIZE_STRING); if (empty($talk['description'])) { throw new Exception("The talk description field is required", 400); } $talk['type'] = filter_var($request->getParameter('type', 'Talk'), FILTER_SANITIZE_STRING); $talk_type_mapper = new TalkTypeMapper($db, $request); $talk_types = $talk_type_mapper->getTalkTypesLookupList(); if (!array_key_exists($talk['type'], $talk_types)) { throw new Exception("The type '{$talk['type']}' is unknown", 400); } $talk['type_id'] = $talk_types[$talk['type']]; $start_date = filter_var($request->getParameter('start_date'), FILTER_SANITIZE_STRING); if (empty($start_date)) { throw new Exception("Please give the date and time of the talk", 400); } $tz = new DateTimeZone($event['tz_continent'] . '/' . $event['tz_place']); $talk['date'] = (new DateTime($start_date, $tz))->format('U'); $event_start_date = (new DateTime($event['start_date']))->format('U'); $event_end_date = (new DateTime($event['end_date']))->add(new DateInterval('P1D'))->format('U'); if ($talk['date'] < $event_start_date || $talk['date'] >= $event_end_date) { throw new Exception("The talk must be held between the start and end date of the event", 400); } $talk['language'] = filter_var($request->getParameter('language'), FILTER_SANITIZE_STRING); if (empty($talk['language'])) { // default to UK English $talk['language'] = 'English - UK'; } // When the language doesn't exist, the talk will not be found $language_mapper = new LanguageMapper($db, $request); if (!$language_mapper->isLanguageValid($talk['language'])) { throw new Exception("The language '{$talk['type']}' is unknown", 400); } $talk['duration'] = filter_var($request->getParameter('duration'), FILTER_SANITIZE_NUMBER_INT); if (empty($talk['duration'])) { $talk['duration'] = 60; } $talk['slides_link'] = filter_var($request->getParameter('slides_link'), FILTER_SANITIZE_URL); $talk['speakers'] = array_map(function ($speaker) { $speaker = filter_var($speaker, FILTER_SANITIZE_STRING); $speaker = trim($speaker); return $speaker; }, (array) $request->getParameter('speakers')); return $talk; }
/** * Create a talk * * @param Request $request * @param PDO $db * * @throws Exception * @return array|bool */ public function createTalkAction(Request $request, PDO $db) { if (!isset($request->user_id)) { throw new Exception("You must be logged in to create data", 400); } $talk['event_id'] = $this->getItemId($request); if (empty($talk['event_id'])) { throw new Exception("POST expects a talk representation sent to a specific event URL", 400); } $event_mapper = new EventMapper($db, $request); $is_admin = $event_mapper->thisUserHasAdminOn($talk['event_id']); if (!$is_admin) { throw new Exception("You do not have permission to add talks to this event", 400); } // get the event so we can get the timezone info $list = $event_mapper->getEventById($talk['event_id'], true); if (count($list['events']) == 0) { throw new Exception('Event not found', 404); } $event = $list['events'][0]; $talk['title'] = filter_var($request->getParameter('talk_title'), FILTER_SANITIZE_STRING); if (empty($talk['title'])) { throw new Exception("The talk title field is required", 400); } $talk['description'] = filter_var($request->getParameter('talk_description'), FILTER_SANITIZE_STRING); if (empty($talk['description'])) { throw new Exception("The talk description field is required", 400); } $talk_types = array("Talk", "Social event", "Keynote", "Workshop", "Event related"); if ($request->getParameter("talk_type") && in_array($request->getParameter("talk_type"), $talk_types)) { $talk['talk_type'] = $request->getParameter("talk_type"); } else { $talk['talk_type'] = "Talk"; } $talk['language'] = filter_var($request->getParameter('language'), FILTER_SANITIZE_STRING); if (empty($talk['language'])) { // default to UK English $talk['language'] = 'English - UK'; } $start_date = $request->getParameter('start_date'); if (empty($start_date)) { throw new Exception("Please give the date and time of the talk", 400); } $tz = new DateTimeZone($event['tz_continent'] . '/' . $event['tz_place']); $start_date = new DateTime($request->getParameter("start_date"), $tz); $talk['date'] = $start_date->format('U'); $speakers = $request->getParameter('speakers'); if (is_array($speakers)) { foreach ($speakers as $speaker) { $talk['speakers'][] = filter_var($speaker, FILTER_SANITIZE_STRING); } } $talk_mapper = new TalkMapper($db, $request); $new_id = $talk_mapper->save($talk); // Update the cache count for the number of talks at this event $event_mapper->cacheTalkCount($talk['event_id']); header("Location: " . $request->base . $request->path_info . '/' . $new_id, null, 201); $new_talk = $talk_mapper->getTalkById($new_id); return $new_talk; }
public function createImage($request, $db) { if (!isset($request->user_id)) { throw new Exception("You must be logged in to create data", 401); } $event_id = $this->getItemId($request); $event_mapper = new EventMapper($db, $request); // ensure event exists $existing_event = $event_mapper->getEventById($event_id, false, true); if ($existing_event['meta']['count'] == 0) { throw new Exception('There is no event with ID ' . $event_id); } if (!$event_mapper->thisUserHasAdminOn($event_id)) { throw new Exception("You don't have permission to do that", 403); } if (!isset($_FILES['image'])) { throw new Exception("Image was not supplied", 400); } if ($_FILES['image']['error'] != 0) { throw new Exception("Image upload failed (Code: " . $FILES['image']['error'] . ")", 400); } // check the file meets our expectations $uploaded_name = $_FILES['image']['tmp_name']; list($width, $height, $filetype) = getimagesize($uploaded_name); // must be gif, jpg or png if (!in_array($filetype, [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG], true)) { throw new Exception("Supplied image must be a PNG, JPG or GIF", 400); } // must be square if ($width != $height) { throw new Exception("Supplied image must be square", 400); } // 140px min, 1440px max if ($width < 140) { throw new Exception("Supplied image must be at least 140px square", 400); } if ($width > 1440) { throw new Exception("Supplied image must be no more than 1440px square", 400); } // save the file - overwrite current one if there is one $extensions[IMAGETYPE_GIF] = '.gif'; $extensions[IMAGETYPE_JPEG] = '.jpg'; $extensions[IMAGETYPE_PNG] = '.png'; $saved_filename = 'icon-' . $event_id . '-orig' . $extensions[$filetype]; $event_image_path = $request->getConfigValue('event_image_path'); $result = move_uploaded_file($uploaded_name, $event_image_path . $saved_filename); if (false === $result) { throw new Exception("The file could not be saved"); } // remove old images from database table and record that we saved the file (this is the orig size) $event_mapper->removeImages($event_id); $event_mapper->saveNewImage($event_id, $saved_filename, $width, $height, "orig"); // small is 140px square $orig_image = imagecreatefromstring(file_get_contents($event_image_path . $saved_filename)); imagealphablending($orig_image, false); imagesavealpha($orig_image, true); $small_width = 140; $small_height = 140; $small_image = imagecreatetruecolor($small_width, $small_height); imagealphablending($small_image, false); imagesavealpha($small_image, true); imagecopyresampled($small_image, $orig_image, 0, 0, 0, 0, $small_width, $small_height, $width, $height); $small_filename = str_replace('orig', 'small', $saved_filename); if ($filetype == IMG_JPG) { imagejpeg($small_image, $event_image_path . $small_filename); } elseif ($filetype == IMG_GIF) { imagegif($small_image, $event_image_path . $small_filename); } else { imagepng($small_image, $event_image_path . $small_filename); } $event_mapper->saveNewImage($event_id, $small_filename, $small_width, $small_height, "small"); $location = $request->base . '/' . $request->version . '/events/' . $event_id; header('Location: ' . $location, null, 201); }