';
}
if($this->nPermutations > 0)
@@ -575,18 +590,7 @@ class Schedule
}
/* edit button */
- if (!isset($savedkey))
- {
- if (isset($_REQUEST['savedkey']))
- $savedkey = (int)$_REQUEST['savedkey'];
- else
- /*
- * if this is a new saved schedule, it'll be the
- * next item added to $_SESSION['saved']
- */
- $savedkey = max(array_keys($_SESSION['saved'])) + 1;
- }
- echo '';
+ echo '';
echo "
There were a total of " . $this->possiblePermutations . " possible permutations. Only " . $this->nPermutations . " permutations had no class conflicts.
";
@@ -649,4 +653,24 @@ class Schedule
{
return $this->classStorage[$class_key];
}
+
+ /**
+ * \brief
+ * Set my global ID.
+ *
+ * Only to be called by schedule_store_store().
+ */
+ function id_set($id)
+ {
+ $this->id = $id;
+ }
+
+ /*
+ * \brief
+ * Get my global ID.
+ */
+ function id_get()
+ {
+ return $this->id;
+ }
}
diff --git a/class.section.php b/class.section.php
--- a/class.section.php
+++ b/class.section.php
@@ -28,7 +28,7 @@ class Section
function setbdays()
{
- $result;
+ $result = array(FALSE, FALSE, FALSE, FALSE, FALSE);
if($this->idays == 12345)
{$result[0] = true; $result[1] = true; $result[2] = true; $result[3] = true; $result[4] = true;}
@@ -181,7 +181,6 @@ class Section
. ' \n"
@@ -203,7 +208,6 @@ class Section
. ' \n"
@@ -228,7 +238,7 @@ class Section
$day_enabled = '';
$out .= "
';
+ }
+ echo '';
+ }
+
+ /**
+ * \brief
+ * Display a 404 page and halt the PHP interpreter.
+ *
+ * This function does not return. It handles the creation of a Page
+ * class with 404-ish stuff and then calls exit() after flushing the
+ * page out to the user.
+ *
+ * \param $message
+ * A message consisting of valid XHTML to display to the user in
+ * the 404 page.
+ */
+ public static function show_404($message = 'I couldn\'t find what you were looking for :-/.')
+ {
+ $page_404 = new Page('404: Content Not Found');
+
+ echo "
404: Content Not Found
\n"
+ . "
\n"
+ . ' ' . $message . "\n"
+ . "
\n";
+
+ $page_404->foot();
+
+ exit();
+ }
}
-
-}
diff --git a/inc/schedule_store.inc b/inc/schedule_store.inc
new file mode 100644
--- /dev/null
+++ b/inc/schedule_store.inc
@@ -0,0 +1,157 @@
+
+ *
+ * This file is a part of slate_permutate.
+ *
+ * slate_permutate is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * slate_permutate is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with slate_permutate. If not, see .
+ */
+
+require_once('class.schedule.php');
+
+/**
+ * \brief
+ * Initialize a schedule_store.
+ *
+ * \param $dir
+ * Directory to use as the schedule storage.
+ * \return
+ * A schedule_store handle or NULL on failure.
+ */
+function schedule_store_init($dir = 'saved_schedules')
+{
+ $schedule_store = array();
+
+ if (!is_dir($dir) || !is_writable($dir))
+ {
+ error_log('I can\'t write to ' . $dir . ' or it is not a directory!');
+ return NULL;
+ }
+
+ $schedule_store['dir'] = realpath($dir);
+
+ return $schedule_store;
+}
+
+/**
+ * \brief
+ * Store a saved schedule into the schedule storage.
+ *
+ * \param $schedule_store
+ * The schedule_store handle from schedule_store_init().
+ * \param $schedule
+ * The schedule object of type Schedule.
+ * \return
+ * The newly-saved schedules global ID (numeric) or NULL on error.
+ */
+function schedule_store_store($schedule_store, $schedule)
+{
+ $tempfile_name = tempnam($schedule_store['dir'], 'sch');
+
+ $new_schedule_id_name = tempnam($schedule_store['dir'], 'id');
+ $new_schedule_id_file = fopen($new_schedule_id_name, 'wb');
+
+ _schedule_store_flock_grab($schedule_store, LOCK_EX);
+ /* if the file doesn't exist, we'll end up with a value of 1 for our first entry. */
+ $schedule_id = (int)file_get_contents($schedule_store['dir'] . DIRECTORY_SEPARATOR . 'lastid');
+ $new_schedule_id = $schedule_id + 1;
+ fwrite($new_schedule_id_file, $new_schedule_id);
+ fclose($new_schedule_id_file);
+ rename($new_schedule_id_name, $schedule_store['dir'] . DIRECTORY_SEPARATOR . 'lastid');
+ _schedule_store_flock_release($schedule_store);
+
+ /* we need to serialize the schedule _after_ giving it an ID */
+ $schedule->id_set($new_schedule_id);
+ file_put_contents($tempfile_name, serialize($schedule));
+
+ rename($tempfile_name, $schedule_store['dir'] . DIRECTORY_SEPARATOR . $new_schedule_id);
+
+ return $new_schedule_id;
+}
+
+/**
+ * \brief
+ * Retrieve a stored saved schedule from the schedule storage.
+ *
+ * \param $schedule_store
+ * The schedule_store handle from which to retrieve the saved
+ * schedule.
+ * \param $schedule_id
+ * The saved schedule's globally-accessible ID. This value must have
+ * been returned from schedule_store_store() at one point.
+ * \return
+ * A Schedule object whose ID was $schedule_id or NULL if
+ * $schedule_id is an invalid or not-yet-allocated schedule
+ * identifier.
+ */
+function schedule_store_retrieve($schedule_store, $schedule_id)
+{
+ if (strcmp($schedule_id, (int)$schedule_id))
+ return NULL;
+ $schedule_id = (int)$schedule_id;
+
+ $schedule_serialized = file_get_contents($schedule_store['dir'] . DIRECTORY_SEPARATOR . $schedule_id);
+ if ($schedule_serialized === FALSE)
+ return NULL;
+
+ $schedule = unserialize($schedule_serialized);
+ if ($schedule === FALSE)
+ return NULL;
+ return $schedule;
+}
+
+/**
+ * \brief
+ * Delete a saved schedule.
+ *
+ * \param $schedule_store
+ * The store from which to delete the schedule.
+ * \param $schedule_id
+ * The identifier of the schedule to delete.
+ */
+function schedule_store_delete($schedule_store, $schedule_id)
+{
+ $remove_filename = $schedule_store['dir'] . DIRECTORY_SEPARATOR . $schedule_id;
+ /* avoid an E_WARNING if the file doesn't exist */
+ if (file_exists($remove_filename))
+ unlink($remove_filename);
+}
+
+/**
+ * \brief
+ * Obtains a lock on the /lastid file in the schedule_store.
+ *
+ * \see _schedule_store_flock_release().
+ *
+ * \param $schedule_store
+ * The schedule_store instance we're working with.
+ * \param $operation
+ * Which flock() operation to perform: valid are LOCK_SH and LOCK_EX.
+ */
+function _schedule_store_flock_grab(&$schedule_store, $operation)
+{
+ $schedule_store['lastid_flock_file'] = fopen($schedule_store['dir'] . DIRECTORY_SEPARATOR . 'lastid.flock', 'c');
+ return flock($schedule_store['lastid_flock_file'], $operation);
+}
+
+/**
+ * \brief
+ * Release a lock grabbed with _schedule_store_flock_grab().
+ */
+function _schedule_store_flock_release(&$schedule_store)
+{
+ flock($schedule_store['lastid_flock_file'], LOCK_UN);
+ fclose($schedule_store['lastid_flock_file']);
+ unset($schedule_store['lastid_flock_file']);
+}
diff --git a/input.php b/input.php
--- a/input.php
+++ b/input.php
@@ -4,18 +4,18 @@ include_once 'class.schedule.php';
include_once 'class.class.php';
include_once 'class.section.php';
include_once 'inc/class.page.php';
+require_once('inc/schedule_store.inc');
$scripts = array('jQuery', 'jQueryUI', 'jValidate','schedInput');
$inputPage = new page('Scheduler', $scripts, FALSE);
+$schedule_store = FALSE;
$sch = FALSE;
-if (isset($_REQUEST['savedkey']) && isset($_SESSION['saved']))
+if (isset($_REQUEST['s']))
{
- $savedkey = (int)$_REQUEST['savedkey'];
- if (isset($_SESSION['saved'][$savedkey]))
- {
- $sch = unserialize($_SESSION['saved'][$savedkey]);
- }
+ $schedule_store = schedule_store_init();
+ $schedule_id = (int)$_REQUEST['s'];
+ $sch = schedule_store_retrieve($schedule_store, $schedule_id);
}
if ($sch)
diff --git a/process.php b/process.php
--- a/process.php
+++ b/process.php
@@ -2,6 +2,8 @@
session_start();
+require_once('inc/schedule_store.inc');
+require_once('inc/class.page.php');
include_once 'class.schedule.php';
include_once 'class.class.php';
include_once 'class.section.php';
@@ -55,23 +57,36 @@ function prettyTime($time){
return substr($time,0,strlen($time)-2) . ":" . substr($time,strlen($time)-2, strlen($time));
}
-$DEBUG = false;
-if(isset($_GET['debug']))
- $DEBUG = $_GET['debug'];
+$DEBUG = FALSE;
+if (isset($_GET['debug']))
+ $DEBUG = $_GET['debug'];
-if(!$DEBUG){
+$schedule_store = schedule_store_init();
- if(isset($_GET['savedkey'])){
- $savedSched = unserialize($_SESSION['saved'][$_GET['savedkey']]);
- $savedSched->writeoutTables();
- }
- else if(isset($_GET['delsaved'])){
- $_SESSION['saved'][$_GET['delsaved']] = '';
- $_SESSION['saved'] = array_filter($_SESSION['saved']); // Remove null entries
- header( 'Location: input.php' ) ;
+if(!$DEBUG)
+ {
+ if(isset($_GET['s']))
+ {
+ $savedSched = schedule_store_retrieve($schedule_store, $_GET['s']);
+ if ($savedSched)
+ $savedSched->writeoutTables();
+ else
+ Page::show_404('Unable to find a saved schedule with an ID of ' . $_GET['s'] . '.');
+ }
+ elseif(isset($_GET['del']))
+ {
+ /* Allow the user to delete schedules that he has stored in his session */
+ if ($_SESSION['saved'][(int)$_GET['del']])
+ {
+ /* user owns this schedule ID */
+ schedule_store_delete($schedule_store, (int)$_GET['del']);
+ unset($_SESSION['saved'][(int)$_GET['del']]);
+ }
- }
- else{
+ header('Location: input.php');
+ }
+ else
+ {
$allClasses = new Schedule($_POST['postData']['name']);
foreach(sortInputs($_POST) as $class)
@@ -95,14 +110,22 @@ if(!$DEBUG){
}
}
$allClasses->findPossibilities();
+ if (!isset($_SESSION['saved']))
+ $_SESSION['saved'] = array();
+ $schedule_id = schedule_store_store($schedule_store, $allClasses);
+ if ($schedule_id != NULL)
+ $_SESSION['saved'][$schedule_id] = $allClasses->getName();
+
+ /*
+ * writeoutTables() needs to know $schedule_id, so it
+ * has to be called after we save the schedule. See
+ * schedule_store_store().
+ */
$allClasses->writeoutTables();
- if(!isset($_SESSION['saved']))
- $_SESSION['saved'] = array();
- array_push ( $_SESSION['saved'], serialize($allClasses));
- }
-} else {
-
-
+ }
+ }
+else
+ {
echo '
DEBUG OUTPUT:
';
foreach(sortInputs($_POST) as $class) {
echo 'Class: ' . $class['name'] . ' ';
diff --git a/saved_schedules/.keep b/saved_schedules/.keep
new file mode 100644
diff --git a/somejavacode.php b/somejavacode.php
deleted file mode 100644
--- a/somejavacode.php
+++ /dev/null
@@ -1,77 +0,0 @@
-//**************************************************
-// Classes.java Author: Nathan Gelderloos
-//
-// Represents a class.
-//**************************************************
-
- public class Classes
- {
- private String name;
- private Section[] sections;
- private int nsections;
-
- private boolean DEBUG = false;
-
- public Classes(String n)
- {
- name = n;
- sections = new Section[1];
- nsections = 0;
- }
-
- // Adds a new section to the class.
- public void addSection(String l, int s, int e, int d)
- {
- checkSections();
- sections[nsections] = new Section(l, s, e, d);
- nsections++;
- }
-
- // Makes sure there is still room in the array.
- // This method should be called before
- // anything is added to the array.
- private void checkSections()
- {
- if(sections.length == nsections)
- {
- Section[] result = new Section[nsections+1];
- for(int i = 0; i < sections.length; i++)
- {
- result[i] = sections[i];
- }
- sections = result;
- }
- }
-
- // Returns the number of sections in the class.
- public int getnsections()
- {
- return nsections;
- }
-
- // Returns the desired section for analysis.
- public Section getSection(int i)
- {
- Section result = sections[i];
- return result;
- }
-
- public int getStartTime(int i)
- {
- Section temp = sections[i];
- return sections[i].getStartTime();
- }
-
- // Sets the DEBUG variable to the desired setting.
- public void setDEBUG(boolean debugger)
- {
- DEBUG = debugger;
- }
-
- // Returns the name of the class.
- public String getName()
- {
- return name;
- }
-
- }