<?php
require('common.php');
require('postcodeanywhere.php');
require('map_functions.php');
$errors = array();
function IsPost()
{
return (strtolower($_SERVER['REQUEST_METHOD']) == 'post');
}
function LoadFields()
{
global $errors;
global $num_events;
if (isset($_POST['num_events'])) {
$num_events = $_POST['num_events'];
} else {
$num_events = 1;
}
if (WasButtonPressed('add')) {
$num_events ++;
}
// Make an array of arrays with the event data in for all events.
$fieldlist = array (
'event_start_date',
'event_end_date',
'is_location_specific',
'venue_name',
'venue_address',
'venue_postcode',
'venue_telephone',
'venue_email',
'venue_url',
'has_accessibility',
'accessibility_statement',
'ticket_price',
'times'
);
global $event_data;
$has_event_error = false;
$event_data = array();
for ($i = 0; $i < $num_events; $i ++) {
$event_data[$i] = array();
$ed = & $event_data[$i];
foreach ($fieldlist as $fieldname) {
$ed[$fieldname] = @ $_POST[$fieldname . "_" . $i];
$ed['just_added'] = false;
if (WasButtonPressed('add')) {
$ed['just_added'] = true;
}
}
FixupDates($ed);
}
}
/*
* Sets a global $selected_image to either:
*
* Nothing or blank
* OR
* The image filename
*
* If the user uploads a file, it will validate the upload, save
* the file and then set the filename.
*
* If the user doesn't upload a file, it will use the previously
* selected one in selected_image
*/
function LoadImageInfo()
{
global $selected_image, $errors;
$selected_image = @ $_POST['selected_image'];
// Determine whether they've uploaded anything...
if (isset($_FILES['image_upload'])) {
$uploaded_file = $_FILES['image_upload']['tmp_name'];
if (is_uploaded_file($uploaded_file)) {
$filename = StripImageFilenamePath($_FILES['image_upload']['name']);
// Check the filename is acceptable.
if (! IsAcceptableImageFilename($filename)) {
$selected_image = null;
$errors[] = 'Unacceptable image filename. Try a jpeg with an entirely alphanumeric filename.';
return;
}
// Put the filename in lowercase now...
$filename = strtolower($filename);
$target = GetEventImageDir() . "/fullsize/" . $filename;
// Check if it exists.
if (file_exists($target)) {
$errors[] = "Image already exists - overwrite not permitted.";
// Select the old one anyway.
$selected_image = $filename;
return;
}
move_uploaded_file($uploaded_file, $target);
$selected_image = $filename;
} else {
// Nothing uploaded.
}
} else {
// $_FILES['image_upload'] not set
}
ValidateImage();
}
function ValidateImage()
{
// Set up event image...
global $selected_image;
// If image has duff filename or doesn't exist, set it null.
if (IsAcceptableImageFilename($selected_image)) {
$image_file = GetEventImageDir() . "/fullsize/" . $selected_image;
if (! file_exists($image_file)) {
$selected_image = null;
}
} else {
$selected_image = null;
}
}
function FixupDates(& $ed)
{
$start_timestamp = ParseUkDate($ed['event_start_date']);
// Only do anything at all if they've supplied a valid start time
if ($start_timestamp) {
// Fix up the formatting
$ed['event_start_date'] = FormatUkDate($start_timestamp);
// Set the end time.
$end_timestamp = ParseUkDate($ed['event_end_date']);
// If it's invalid, set to the same as the start.
if ($end_timestamp === FALSE || ($end_timestamp < $start_timestamp)) {
$end_timestamp = $start_timestamp;
}
$ed['event_end_date'] = FormatUkDate($end_timestamp);
} else {
// Invalid data.
$ed['event_start_date'] = '';
$ed['event_end_date'] = '';
}
}
function ValidateEvents()
{
global $event_data;
global $errors;
global $num_events;
$has_event_error = false;
foreach ($event_data as & $ed) {
if (! $ed['just_added']) {
$ed['errors'] = array();
ValidateEvent($ed);
if (count($ed['errors']) > 0) {
$has_event_error = true;
}
}
}
if ($has_event_error) {
$errors[] = "One or more events has an error - see below";
}
if ($num_events == 0) {
$errors[] = "At least one event must be specified.";
}
$required_fields = array('title', 'org_name');
foreach ($required_fields as $required_field)
{
$val = @ $_POST[$required_field];
if (trim($val) == '') {
$formatted_field = '"' . str_replace("_", " ", $required_field) . '"';
$errors[] = "Please supply $formatted_field.";
}
}
}
function ValidateEvent(& $ed)
{
if ($ed['is_location_specific']) {
if ($ed['venue_name'] == '') {
$ed['errors'][] = "Please specify a venue.";
}
}
if ($ed['event_start_date'] == '') {
$ed['errors'][] = "We could not understand your start date, please retype it in the format day/month/year; e.g. 28/02/2006.";
}
if (! IsValidPostcode($ed['venue_postcode'])) {
$ed['errors'][] = "The postcode appears to be invalid, please check and retype it.";
}
}
// Loads age data from the FORM, not from the db.
function LoadRelatedData()
{
global $errors, $selected_ages, $selected_categories;
$selected_ages = @ $_POST['selected_ages'];
// If it's not set, assume empty array.
if (! $selected_ages) {
$selected_ages = array();
} else {
// Convert them all to ints.
foreach ($selected_ages as & $selected_age) {
$selected_age = (int) $selected_age;
}
}
if (count($selected_ages) == 0) {
$errors[] = "Please select at least one age group.";
}
$selected_categories = @ $_POST['selected_categories'];
if (! $selected_categories) {
$selected_categories = array();
} else {
// Convert them all to ints.
foreach ($selected_categories as & $category_id) {
$category_id = (int) $category_id;
}
}
}
function ProcessDeletions()
{
global $num_events, $event_data;
// Figure out which button was pressed.
$delete_num = false;
for ($i=0; $i < $num_events; $i++) {
if (WasButtonPressed('delete_' . $i)) {
$delete_num = $i;
}
}
if (! $delete_num) {
return;
}
// Move the others down appropriately.
for ($i = $delete_num; $i < ($num_events - 1); $i ++) {
$event_data[$i] = $event_data[$i + 1];
}
error_log("1: count = ".count($event_data).", num events = ".$num_events);
// There is now one fewer event.
$num_events --;
// Remove the final element; now $num_events is decremented,
// it will hit the last element in the array
unset($event_data[$num_events]);
}
function LoadEventsFromDb($event_group_id)
{
// Load the event group stuff
$sql = "SELECT * FROM event_group WHERE id=?";
global $evdb;
$st = $evdb->prepare($sql);
$st->execute(array($event_group_id));
$results = $st->fetch(PDO::FETCH_ASSOC);
unset($st); // free result.
if ($results === FALSE) {
throw new Exception("Event group not found: $event_group_id");
}
// Load the events
$st = $evdb->prepare("SELECT * FROM event WHERE event_group_id=? ORDER BY event_order");
$st->execute(array($event_group_id));
global $event_data;
$event_data = $st->fetchAll(PDO::FETCH_ASSOC);
unset($st); // free result.
// Load age ranges.
global $selected_ages;
$st = $evdb->prepare("SELECT lower_age FROM event_age WHERE event_group_id=? ORDER BY lower_age");
$st->execute(array($event_group_id));
$selected_ages = $st->fetchAll(PDO::FETCH_COLUMN);
unset($st);// free result.
// Fix up our event data.
foreach ($event_data as & $ed) {
$ed['event_start_date'] =
FormatUkDate(DbDateTimeToTime($ed['start_date']));
$ed['event_end_date'] =
FormatUkDate(DbDateTimeToTime($ed['end_date']));
}
global $num_events;
$num_events = count($event_data);
// Load selected categories.
global $selected_categories;
$st = $evdb->prepare("SELECT category_id FROM " .
"event_group_category WHERE event_group_id=?");
$st->execute(array($event_group_id));
$selected_categories = $st->fetchAll(PDO::FETCH_COLUMN);
unset($st);// free result.
// Load image filename.
global $selected_image;
$selected_image = $results['image_filename'];
return $results;
}
function ShowForm()
{
global $num_events, $event_data, $age_data;
global $errors;
$smarty = new Smarty_Events();
$event_head = array();
if (isset($_REQUEST['id'])) {
if (! IsEventAdmin()) {
throw new Exception("Only admin can edit events");
}
$event_group_id = (int) $_REQUEST['id'];
if (! IsPost()) {
$event_head = LoadEventsFromDb($event_group_id);
}
$smarty->assign('event_group_id', $event_group_id);
$smarty->assign('page_title', "Editing event.");
} else {
$smarty->assign('page_title', "Adding an event");
}
$smarty->AssignFromRequest('title', @ $event_head['title']);
$smarty->AssignFromRequest('short_description', @ $event_head['short_description']);
$smarty->AssignFromRequest('description', @ $event_head['description']);
$smarty->AssignFromRequest('org_name', @ $event_head['org_name']);
$smarty->AssignFromRequest('org_address', @ $event_head['org_address']);
$smarty->AssignFromRequest('org_postcode', @ $event_head['org_postcode']);
$smarty->AssignFromRequest('org_email', @ $event_head['org_email']);
$smarty->AssignFromRequest('org_telephone', @ $event_head['org_telephone']);
$smarty->AssignFromRequest('org_url', @ $event_head['org_url']);
$smarty->assign('num_events', $num_events);
$smarty->assign('next_num_events', $num_events + 1);
$smarty->assign_by_ref('event_data', $event_data);
global $selected_ages, $age_groups;
$smarty->assign_by_ref('selected_ages', $selected_ages);
$smarty->assign_by_ref('age_groups', $age_groups);
if (WasButtonPressed('check_errors', true)) {
if (! $errors) {
$smarty->assign('no_errors', true);
}
}
$smarty->assign_by_ref('errors', $errors);
global $event_status_values;
$smarty->assign_by_ref('event_status_values', $event_status_values);
$smarty->assign('is_admin', IsEventAdmin());
$smarty->AssignFromRequest('status', @ $event_head['status']);
$all_categories = GetActiveCategories();
$smarty->assign('all_categories', $all_categories);
global $selected_categories;
$smarty->assign('selected_categories', $selected_categories);
global $selected_image;
$smarty->assign('selected_image', $selected_image);
$imagelist = GetEventImageList();
$smarty->assign('imagelist', $imagelist);
$smarty->assign_by_ref('regions', GetDisplayRegions());
$smarty->assign('is_event_admin',IsEventAdmin());
$smarty->display('edit.tpl');
}
function DoSubmit()
{
global $event_data, $evdb;
// Save the event group.
$status = @ (int) $_POST['status'];
if (! IsEventAdmin()) {
$status = EVENT_STATUS_NEW;
}
$st = $evdb->prepare(
"INSERT INTO event_group " .
" (org_name, org_address, org_postcode, org_email, org_telephone, org_url," .
" title, short_description, description, " .
" created_date, modified_date, created_ip_address, status, active) VALUES " .
" (?,?,?,?,?,?, ?,?,?, " .
" current_timestamp(), current_timestamp(), ?, ?, ? )");
// Set active flag IFF it's approved.
$active = ($status == EVENT_STATUS_APPROVED) ? 1 : 0;
$st->execute(
array(
$_POST['org_name'],
$_POST['org_address'],
$_POST['org_postcode'],
$_POST['org_email'],
$_POST['org_telephone'],
$_POST['org_url'],
$_POST['title'],
$_POST['short_description'],
$_POST['description'],
$_SERVER['REMOTE_ADDR'], // IP address
$status, $active));
$event_group_id = $evdb->lastInsertId();
// Now put the events in.
// echo "group ID: $event_group_id\n"; exit;
SaveRelatedData($event_group_id);
if ($status != EVENT_STATUS_NEW) {
// If loading the geo data fails, don't allow them to proceed.
if (! PopulateGeoData($event_group_id)) {
return;
}
}
DoRedirect("/events/manage.php?message=" . urlencode("Event submitted"));
exit;
}
function DoSave()
{
global $event_data, $evdb;
if (! IsEventAdmin()) {
throw new Exception("Only admin can edit events");
}
// Check it really exists...
$event_group_id = (int) $_REQUEST['id'];
$st = $evdb->prepare("SELECT COUNT(*) FROM event_group WHERE id=?");
$st->execute(array($event_group_id));
$exists = $st->fetchColumn();
if (! $exists) {
throw new Exception("Event does not exist");
}
unset($st); // clean up.
$status = (int) $_POST['status'];
// Set active flag IFF it's approved.
$active = ($status == EVENT_STATUS_APPROVED) ? 1 : 0;
$st = $evdb->prepare(
"UPDATE event_group SET " .
" org_name=?, org_address = ?, org_postcode = ?, " .
" org_email=?, org_telephone=?, org_url=?," .
" title=?, short_description=?, description=?, " .
" modified_date=current_timestamp(), status=?, active=? " .
" WHERE id=?");
$st->execute(
array(
$_POST['org_name'],
$_POST['org_address'],
$_POST['org_postcode'],
$_POST['org_email'],
$_POST['org_telephone'],
$_POST['org_url'],
$_POST['title'],
$_POST['short_description'],
$_POST['description'],
$status,
$active,
$event_group_id
));
// Now put the events in.
SaveRelatedData($event_group_id);
// If loading the geo data fails, don't allow them to proceed.
if (! PopulateGeoData($event_group_id)) {
return;
}
// Give a nice message
DoRedirect("/events/manage.php?message=" . urlencode("Event updated"));
}
function SaveRelatedData($event_group_id)
{
global $event_data, $evdb;
// Delete previous event data.
$st = $evdb->prepare("DELETE FROM event WHERE event_group_id = ?");
$st->execute(array($event_group_id));
// Add the new event data.
$st = $evdb->prepare(
"INSERT INTO event " .
" (event_group_id, start_date, end_date, venue_name, " .
" venue_url, venue_address, venue_postcode, venue_telephone, " .
" venue_email, has_accessibility, accessibility_statement, " .
" is_location_specific, event_order, ticket_price, times) VALUES " .
" (?, ?, ?, ?, ?,?,?,?, ?,?,?, ?,?,?,?)");
$order = 1;
foreach ($event_data as $ed) {
// Convert the date/time into a format for the DB.
$start_db_time = TimeToDbDateTime(ParseUkDate($ed['event_start_date']));
$end_db_time = TimeToDbDateTime(ParseUkDate($ed['event_end_date']));
$st->execute(
array($event_group_id,
$start_db_time,
$end_db_time,
$ed['venue_name'],
$ed['venue_url'],
$ed['venue_address'],
CleanPostcode($ed['venue_postcode']),
$ed['venue_telephone'],
$ed['venue_email'],
$ed['has_accessibility'] ? 1 : 0,
$ed['accessibility_statement'],
$ed['is_location_specific'] ? 1 : 0,
$order,
$ed['ticket_price'],
$ed['times']
)
);
$order ++;
}
// Delete previous age groups.
$st = $evdb->prepare("DELETE FROM event_age WHERE event_group_id = ?");
$st->execute(array($event_group_id));
// Put the age groups in.
$st = $evdb->prepare("INSERT INTO event_age (event_group_id, lower_age) VALUES (?,?)");
global $selected_ages;
foreach ($selected_ages as $lower_age) {
$st->execute(
array($event_group_id, $lower_age));
}
// Delete previous cats.
$st = $evdb->prepare("DELETE FROM event_group_category WHERE event_group_id = ?");
$st->execute(array($event_group_id));
// Put categories.
$st = $evdb->prepare("INSERT INTO event_group_category " .
"(event_group_id, category_id) VALUES (?,?)");
global $selected_categories;
foreach ($selected_categories as $category_id)
{
$st->execute(
array($event_group_id, $category_id));
}
// Set up event image...
global $selected_image;
ValidateImage(); // If image has duff filename or doesn't exist, set it null.
$st = $evdb->prepare("UPDATE event_group SET image_filename=? WHERE id=?");
$st->execute(array($selected_image, $event_group_id));
}
LoadFields();
LoadImageInfo();
// If we're doing a post, load the age data etc.
if (IsPost()) {
LoadRelatedData();
ProcessDeletions();
ValidateEvents();
}
// Otherwise, don't.
if (WasButtonPressed('submit', true)) {
if (count($errors) == 0) {
DoSubmit();
}
}
// Update an existing event.
if (WasButtonPressed('save', true)) {
assert(IsEventAdmin());
if (count($errors) == 0) {
DoSave();
}
}
ShowForm();
?>