diff --git a/class.schedule.php b/class.schedule.php
deleted file mode 100755
--- a/class.schedule.php
+++ /dev/null
@@ -1,569 +0,0 @@
-.
- */
-
-//**************************************************
-// class.schedule.php Author: Nathan Gelderloos
-//
-// Represents a schedule of a week. Stores the
-// classes that are part of that week and calculates
-// all the possible permutations.
-//**************************************************
-
-include_once('inc/class.course.inc');
-include_once 'class.section.php';
-include_once 'inc/class.page.php';
-
-/*
- * Load a Classes -> Course converter class for the sake of the
- * Schedule::__wakeup() magic function.
- */
-require_once('inc/class.classes_convert.inc');
-
-class Schedule
-{
- /*
- * Variables for upgrading from saved schedules created when there
- * was a class called Classes.
- */
- private $classStorage; // array of courses
- private $nclasses; // Integer number of classes
-
- /* My member variables. */
- private $courses;
- private $nPermutations = 0; // Integer number of real permutations
- private $possiblePermutations; // Integer number of possible permutations
- private $scheduleName; // String name of schedule
- private $storage; // Integer array of valid schedules
- private $title;
-
- /**
- * \brief
- * My global identification number. Not defined until the schedule
- * is processed and first saved.
- */
- private $id;
- /**
- * The input format of the sections. Only used for the UI. Valid
- * values are 'numerous' for custom, 'numbered' for numeric, and 'lettered' for
- * alphabetical.
- */
- public $section_format;
-
- /**
- * \brief
- * Create a schedule with the given name.
- */
- function __construct($name)
- {
- $this->courses = array();
- $this->scheduleName = $name;
- $this->storage = array();
- $this->title = "SlatePermutate - Scheduler";
- $this->section_format = 'numerous';
-
- /* mark this as an upgraded Schedule class. See __wakeup() */
- $this->nclasses = -1;
- }
-
- //--------------------------------------------------
- // Mutators and Accessors
- //--------------------------------------------------
- public function getName()
- {
- return $this->scheduleName;
- }
-
- //--------------------------------------------------
- // Adds a new class to the schedule.
- //--------------------------------------------------
- function addCourse($n)
- {
- $this->courses[] = new Course($n);
- }
-
- //--------------------------------------------------
- // Adds a section to the desired class.
- //--------------------------------------------------
- function addSection($course_name, $letter, $time_start, $time_end, $days, $synonym = NULL, $faculty = NULL, $location = NULL, $type = 'lecture')
- {
- $found = false;
- $counter = 0;
-
- foreach ($this->courses as $course)
- if (!strcmp($course_name, $course->getName()))
- {
- $section = $course->section_get($letter);
- if (!$section)
- {
- $section = new Section($letter, array(), $synonym, $faculty);
- $course->section_add($section);
- }
- $section->meeting_add(new SectionMeeting($days, $time_start, $time_end, $location, $type));
-
- return;
- }
-
- echo 'Could not find class: ' . $course_name . "
\n";
- }
-
- //--------------------------------------------------
- // Finds all of the possible permutations and stores
- // the results in the storage array.
- //--------------------------------------------------
- function findPossibilities()
- {
- $this->possiblePermutations = 1;
- /* special case: there is nothing entered into the schedule and thus there is one, NULL permutation */
- if (!count($this->courses))
- {
- /* have an empty schedule */
- $this->nPermutations = 1;
- return;
- }
-
- $position = 0;
- $counter = 0;
-
- $i = 0;
- foreach ($this->courses as $course)
- {
- $this->possiblePermutations = $this->possiblePermutations * $course->getnsections();
- $cs[$i] = 0; // Sets the counter array to all zeroes.
- $i ++;
- }
-
- // Checks for conflicts in given classes, stores if none found
- do
- {
- $conflict = false;
-
- // Get first class to compare
- for ($upCounter = 0; $upCounter < count($this->courses) && !$conflict; $upCounter ++)
- {
-
- for ($downCounter = count($this->courses) - 1; $downCounter > $upCounter && !$conflict; $downCounter --)
- {
- if ($this->courses[$upCounter]->getSection($cs[$upCounter])
- ->conflictsWith($this->courses[$downCounter]->getSection($cs[$downCounter])))
- {
- $conflict = TRUE;
- break;
- }
- }
- }
-
- // Store to storage if no conflict is found.
- if(!$conflict)
- {
- for($i = 0; $i < count($this->courses); $i++)
- {
- $this->storage[$this->nPermutations][$i] = $cs[$i];
- }
- $this->nPermutations++;
- }
-
- // Increase the counter by one to get the next combination of class sections.
- $cs[$position] = $cs[$position] + 1;
-
- // Check to make sure the counter is still valid.
- $valid = false;
- while(!$valid)
- {
- if($cs[$position] == $this->courses[$position]->getnsections())
- {
- $cs[$position] = 0;
-
- $position++;
-
- // This is for the very last permutation. Even
- // though the combination is not actually true
- // the larger while loop will end before any
- // new combinations are performed.
- if($position == count($this->courses))
- {
- $valid = true;
- } else {
- $cs[$position]++;
- }
- } else {
- $valid = true;
- $position = 0;
- }
- }
-
- $counter++;
- } while($counter < $this->possiblePermutations);
- }
-
- //--------------------------------------------------
- // Prints out the possible permutations in tables.
- //--------------------------------------------------
- function writeoutTables()
- {
- $filled = false;
- $time = array(700,730,800,830,900,930,1000,1030,1100,1130,1200,1230,1300,1330,1400,1430,1500,1530,1600,1630,1700,1730,1800,1830,1900,1930,2000,2030,2100,2130, 2200);
-
- define('SP_PERMUTATIONS_PER_PAGE', 256); /** @TODO: Define this in config.inc */
-
- $npages = ceil($this->nPermutations / SP_PERMUTATIONS_PER_PAGE);
- $page = 0;
- if (isset($_REQUEST['page']))
- $page = $_REQUEST['page'];
- /*
- * only display the ``this page doesn't exist'' 404 if there is at
- * least one permutation. Otherwise, we give an irrelevant 404 for
- * users with no permutations.
- */
- if ($this->nPermutations && $page >= $npages)
- Page::show_404('Unable to find page ' . $page . ', there are only ' . $this->nPermutations . ' non-conflicting permutations, for a total of ' . $npages . ' pages.');
- /* zero-based */
- $first_permutation = $page * SP_PERMUTATIONS_PER_PAGE;
- $last_permutation = min($this->nPermutations, $first_permutation + SP_PERMUTATIONS_PER_PAGE);
-
- $footcloser = '';
-
- if(isset($_REQUEST['print']) && $_REQUEST['print'] != ''){
- $headcode = array('jQuery', 'jQueryUI', 'uiTabsKeyboard', 'outputStyle', 'outputPrintStyle', 'displayTables');
- }
- else {
- $headcode = array('outputStyle', 'jQuery', 'jQueryUI', 'uiTabsKeyboard', 'displayTables');
- }
- $outputPage = new Page(htmlentities($this->getName()), $headcode);
-
-
-
- if(isset($_REQUEST['print'])) {
-
- echo '';
-
- echo '
Having problems? Let us know.
'; - echo 'Keyboard Shortcut: Left and right arrow keys switch between schedules
'; - } - - echo "\n"; - - if($this->nPermutations > 0) - { - - echo 'Enter these codes into your school\'s online course registration system to register for classes:
| ' . ($i + 1) . " | \n" - . "Monday | \n" - . "Tuesday | \n" - . "Wednesday | \n" - . "Thursday | \n" - . "Friday | \n" - . "
| " . $this->prettyTime($time[$r]) . " | \n"; - - for($dayLoop = 0; $dayLoop < 5; $dayLoop++) - { - /* Makes sure there is not a class already in progress */ - if($rowspan[$dayLoop] <= 0) - { - for($j = 0; $j < count($this->courses); $j++) - { - $class = $this->courses[$j]; - $section_index = $this->storage[$i][$j]; - $section = $class->getSection($section_index); - /* iterate through all of a class's meeting times */ - $meetings = $section->getMeetings(); - - /* find any meeting which are going on at this time */ - $current_meeting = NULL; - foreach ($meetings as $meeting) - { - if ($meeting->getDay($dayLoop) - && $meeting->getStartTime() >= $time[$r] - && $meeting->getStartTime() < $time[$r+1]) - { - $current_meeting = $meeting; - } - } - - if ($current_meeting) - { - /* calculate how many rows this section should span */ - for ($my_r = $r; $current_meeting->getEndTime() > $time[$my_r]; $my_r ++) - ; - $rowspan[$dayLoop] = $my_r - $r; - - $single_multi = 'single'; - if ($rowspan[$dayLoop] > 1) - $single_multi = 'multi'; - - echo '' - . htmlentities($class->getName(), ENT_QUOTES) . '-' - . htmlentities($section->getLetter(), ENT_QUOTES) . "\n" - . '' . htmlentities($section->getProf(), ENT_QUOTES) . "\n" - . '' . htmlentities($current_meeting->getLocation(), ENT_QUOTES) . "\n" - . '' . htmlentities($section->getSynonym(), ENT_QUOTES) . "\n" - . " | \n"; - $syns[$section->getSynonym()] = $section->getSynonym(); - $filled = TRUE; - } - } - } - - if ($rowspan[$dayLoop] > 0) - { - $filled = TRUE; - $rowspan[$dayLoop] --; - } - - /* If the cell was not filled, fill it with an empty cell. */ - if(!$filled) - { - echo "\n"; - } - $filled = FALSE; - } - - // End of row - echo " |
There are no possible schedules. Please try again.
'; - } - - /* edit button */ - if ($id = $this->id_get()) - echo ''; - - echo "There were a total of " . $this->possiblePermutations . " possible permutations. Only " . $this->nPermutations . " permutations had no class conflicts.
"; - - $outputPage->foot(); - } - - //-------------------------------------------------- - // Changes the title of the page. - //-------------------------------------------------- - function changeTitle($t) - { - $this->title = $t; - } - - //-------------------------------------------------- - // Make the time "pretty" - //-------------------------------------------------- - function prettyTime($t){ - if($t > 1259) - { - $t = ($t-1200); - return substr($t, 0, strlen($t)-2) . ":" . substr($t, strlen($t)-2, strlen($t)) . " PM"; - } else { - return substr($t, 0, strlen($t)-2) . ":" . substr($t, strlen($t)-2, strlen($t)) . " AM"; - } - } - - /** - * \brief - * fetch the number of classes - */ - function nclasses_get() - { - return count($this->courses); - } - - /** - * \brief - * fetch a specified class by its key - */ - function class_get($class_key) - { - return $this->courses[$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; - } - - /** - * \brief - * Write out a relative URL for a particular schedule. - * - * Takes into account the $clean_urls setting. - * - * \param $id - * The ID of the schedule to link to. Defaults to the current schedule object. - * \param $page - * The page of the schedule to link to. Defaults to 0. - * \return - * A string, the URL used to access this schedule. Remember that - * if this string is inserted into an XHTML document, - * htmlentities() must be called on it. - */ - function url($id = NULL, $page = 0) - { - global $clean_urls; - - $url = ''; - if (!$clean_urls) - $url .= 'process.php?s='; - - if (!$id) - $id = $this->id; - $url .= (int)$id; - if ($clean_urls) - $url .= '?'; - else - $url .= '&'; - - if ($page) - $url .= 'page=' . (int)$page . '&'; - - return $url; - } - - /** - * \brief - * A magic function which tries to upgrade old serialized sections - * to the new format. - */ - function __wakeup() - { - if ($this->nclasses == -1) - /* this Schedule doesn't need to be upgraded from Classes to Course */ - return; - - $this->courses = array(); - foreach ($this->classStorage as $classes) - { - $this->courses[] = $classes->to_course(); - } - $this->nclasses = -1; - } -} diff --git a/class.section.php b/class.section.php deleted file mode 100755 --- a/class.section.php +++ /dev/null @@ -1,262 +0,0 @@ -. - */ - -//-------------------------------------------------- -// class.section.php Author:Nathan Gelderloos -// -// Represents a section of a class. -//-------------------------------------------------- - -require_once('inc/class.section_meeting.inc'); - -class Section -{ - - private $letter; // Section letter - private $prof; // Professor - - /* meeting times, array of SectionMeeting */ - private $meetings; - - /* the section synonym which uniquely identifies this section/course combination */ - private $synonym; - - /** - * \brief - * Construct a Section. - * - * \param $letter - * The identifier (often a letter or numeral) of this section. For - * CS-262-A, this would be 'a'. - * \param $section_meetings - * An array of SectionMeeting objects which describe all the - * different types of meetings this particular section has. It - * will be very uncommon for a course to have more than one such - * meeting time for a section. For example, Calvin doesn't have - * this. Another example, Cedarville lists different meeting times - * inside of a single section. Cedarville also lists all lectures - * and lab meeting times directly in a section's listing. - * \param $synonym - * Some schools have a unique number for each section. This field - * is for that number. - * \param $prof - * The faculty person(s) who teaches this section. - */ - function __construct ($letter, array $section_meetings = array(), $synonym = NULL, $prof = NULL) - { - $this->letter = $letter; - - $this->meetings = $section_meetings; - - $this->synonym = $synonym; - - $this->prof = $prof; - } - - public function getLetter() - { - return $this->letter; - } - - public function getProf() - { - return $this->prof; - } - - /** - * \return - * This section's synonym -- a unique numeric identifier for this - * course. NULL if undefined. - */ - public function getSynonym() - { - return $this->synonym; - } - - /** - * \brief - * Get an array of section meetings for this section. - * - * \return - * An array of SectionMeeting objects. - */ - public function getMeetings() - { - return $this->meetings; - } - - /** - * \brief - * Check if this section conflicts with the given section. - * - * \param $that - * The other section for which I should check for conflicts. - * \return - * TRUE if there is a conflict, FALSE otherwise. - */ - public function conflictsWith(Section $that) - { - foreach ($this->meetings as $this_meeting) - foreach ($that->meetings as $that_meeting) - if ($this_meeting->conflictsWith($that_meeting)) - return TRUE; - - return FALSE; - } - - /** - * \brief - * Add another section meeting time to this section. - * - * Useful for process.php when it's calling - * Schedule::addSectionMeeting() multiple times. - */ - public function meeting_add(SectionMeeting $meeting) - { - $this->meetings[] = $meeting; - } - - /** - * \brief - * Splits up a section specifier into dept, course number, and - * section. - * - * For example, will return array('CS', '262', 'A') for 'CS-262-A' - * or 'CS262 A' or 'cs-262,a'. This function is not for dealing with - * course synonyms. - * - * Note: Section specifiers where the section numeral/letter is - * directly adjacent to the course number is not valid. Calvin - * College distinguishes between normal courses and their labs by - * appending an `L' to the course number. Thus, 'CS262A' is not a - * valid specifier for 'CS-262-A' because there may exist another - * course called 'CS-262L-A' (which is likely the lab for the - * 'CS-262-A' class ;-)). - * - * \param $section_spec - * A string starting with a section specifier. If only the - * department is found, an array of size one is returned. If the - * course number is also found, both department and course id are - * returned. If all three are found, the array has three elements. - * - * This array is keyed, so the found items may be referred to as - * 'deptartment', 'course', and 'section'. - * - * \return - * An array with the department, course number, and section - * identifier. This array may be empty or have from one through - * three elements depending on the validity and precision of the - * $section_spec. - */ - public static function parse($section_spec) - { - $ret = array(); - - $section_spec = trim($section_spec); - if (!preg_match(';([a-zA-Z]+)[^0-9]*;', $section_spec, $dept_matches)) - return $ret; - - /* - * remove away the already-parsed stuff, including gunk between the - * dept and the course num. - */ - $section_spec = trim(substr($section_spec, strlen($dept_matches[0]))); - $ret['department'] = strtoupper($dept_matches[1]); - - if (!preg_match(';([0-9a-zA-Z]+)[^a-zA-Z0-9]*;', $section_spec, $course_matches)) - return $ret; - - /* skip gunk */ - $section_spec = trim(substr($section_spec, strlen($course_matches[0]))); - $ret['course'] = strtoupper($course_matches[1]); - - /* - * we accept _either_ alphabetic section _or_ numeric section (the - * latter is for cedarville, particulaly) - */ - if (!preg_match(';([0-9]+|[a-zA-Z]+);', $section_spec, $section_matches)) - return $ret; - - $ret['section'] = strtoupper($section_matches[1]); - - return $ret; - } - - /** - * \brief - * Get arrays of information needed by the AJAX stuff. - * - * \return - * An array of arrays that should be merged with the return value - * of other Section::to_json_array() calls. - */ - public function to_json_arrays() - { - $json_arrays = array(); - - foreach ($this->meetings as $meeting) - { - $json_array = array('section' => $this->letter, - 'prof' => $this->prof, - 'synonym' => $this->synonym, - ); - - $json_array += $meeting->to_json_array(); - $json_arrays[] = $json_array; - } - - return $json_arrays; - } - - - /* for legacy unserialization */ - private $start; - private $tend; - private $bdays; - - /** - * \brief - * A magic function which tries to upgrade old serialized sections - * to the new format. - */ - public function __wakeup() - { - /* upgrade to SectionMeeting stuffage */ - if (!empty($this->start)) - { - $days = ''; - $daymap = array(0 => 'm', 1 => 't', 2 => 'w', 3 => 'h', 4 => 'f'); - foreach ($this->bdays as $day => $have_day) - if ($have_day) - $days .= $daymap[$day]; - - /* the old format had a ->prof but initialied it to ``unknown prof'' */ - $this->prof = ''; - - $this->meetings = array(); - $this->meeting_add(new SectionMeeting($days, $this->start, $this->tend, '', 'lecture')); - - /* - * if we're reserialized in the future, make sure we don't do this same upgrade procedure again ;-). - */ - unset($this->start); - } - } -} diff --git a/inc/class.schedule.php b/inc/class.schedule.php new file mode 100755 --- /dev/null +++ b/inc/class.schedule.php @@ -0,0 +1,569 @@ +. + */ + +//************************************************** +// class.schedule.php Author: Nathan Gelderloos +// +// Represents a schedule of a week. Stores the +// classes that are part of that week and calculates +// all the possible permutations. +//************************************************** + +include_once('inc/class.course.inc'); +include_once 'class.section.php'; +include_once 'inc/class.page.php'; + +/* + * Load a Classes -> Course converter class for the sake of the + * Schedule::__wakeup() magic function. + */ +require_once('inc/class.classes_convert.inc'); + +class Schedule +{ + /* + * Variables for upgrading from saved schedules created when there + * was a class called Classes. + */ + private $classStorage; // array of courses + private $nclasses; // Integer number of classes + + /* My member variables. */ + private $courses; + private $nPermutations = 0; // Integer number of real permutations + private $possiblePermutations; // Integer number of possible permutations + private $scheduleName; // String name of schedule + private $storage; // Integer array of valid schedules + private $title; + + /** + * \brief + * My global identification number. Not defined until the schedule + * is processed and first saved. + */ + private $id; + /** + * The input format of the sections. Only used for the UI. Valid + * values are 'numerous' for custom, 'numbered' for numeric, and 'lettered' for + * alphabetical. + */ + public $section_format; + + /** + * \brief + * Create a schedule with the given name. + */ + function __construct($name) + { + $this->courses = array(); + $this->scheduleName = $name; + $this->storage = array(); + $this->title = "SlatePermutate - Scheduler"; + $this->section_format = 'numerous'; + + /* mark this as an upgraded Schedule class. See __wakeup() */ + $this->nclasses = -1; + } + + //-------------------------------------------------- + // Mutators and Accessors + //-------------------------------------------------- + public function getName() + { + return $this->scheduleName; + } + + //-------------------------------------------------- + // Adds a new class to the schedule. + //-------------------------------------------------- + function addCourse($n) + { + $this->courses[] = new Course($n); + } + + //-------------------------------------------------- + // Adds a section to the desired class. + //-------------------------------------------------- + function addSection($course_name, $letter, $time_start, $time_end, $days, $synonym = NULL, $faculty = NULL, $location = NULL, $type = 'lecture') + { + $found = false; + $counter = 0; + + foreach ($this->courses as $course) + if (!strcmp($course_name, $course->getName())) + { + $section = $course->section_get($letter); + if (!$section) + { + $section = new Section($letter, array(), $synonym, $faculty); + $course->section_add($section); + } + $section->meeting_add(new SectionMeeting($days, $time_start, $time_end, $location, $type)); + + return; + } + + echo 'Could not find class: ' . $course_name . "Having problems? Let us know.
'; + echo 'Keyboard Shortcut: Left and right arrow keys switch between schedules
'; + } + + echo "\n"; + + if($this->nPermutations > 0) + { + + echo 'Enter these codes into your school\'s online course registration system to register for classes:
| ' . ($i + 1) . " | \n" + . "Monday | \n" + . "Tuesday | \n" + . "Wednesday | \n" + . "Thursday | \n" + . "Friday | \n" + . "
| " . $this->prettyTime($time[$r]) . " | \n"; + + for($dayLoop = 0; $dayLoop < 5; $dayLoop++) + { + /* Makes sure there is not a class already in progress */ + if($rowspan[$dayLoop] <= 0) + { + for($j = 0; $j < count($this->courses); $j++) + { + $class = $this->courses[$j]; + $section_index = $this->storage[$i][$j]; + $section = $class->getSection($section_index); + /* iterate through all of a class's meeting times */ + $meetings = $section->getMeetings(); + + /* find any meeting which are going on at this time */ + $current_meeting = NULL; + foreach ($meetings as $meeting) + { + if ($meeting->getDay($dayLoop) + && $meeting->getStartTime() >= $time[$r] + && $meeting->getStartTime() < $time[$r+1]) + { + $current_meeting = $meeting; + } + } + + if ($current_meeting) + { + /* calculate how many rows this section should span */ + for ($my_r = $r; $current_meeting->getEndTime() > $time[$my_r]; $my_r ++) + ; + $rowspan[$dayLoop] = $my_r - $r; + + $single_multi = 'single'; + if ($rowspan[$dayLoop] > 1) + $single_multi = 'multi'; + + echo '' + . htmlentities($class->getName(), ENT_QUOTES) . '-' + . htmlentities($section->getLetter(), ENT_QUOTES) . "\n" + . '' . htmlentities($section->getProf(), ENT_QUOTES) . "\n" + . '' . htmlentities($current_meeting->getLocation(), ENT_QUOTES) . "\n" + . '' . htmlentities($section->getSynonym(), ENT_QUOTES) . "\n" + . " | \n"; + $syns[$section->getSynonym()] = $section->getSynonym(); + $filled = TRUE; + } + } + } + + if ($rowspan[$dayLoop] > 0) + { + $filled = TRUE; + $rowspan[$dayLoop] --; + } + + /* If the cell was not filled, fill it with an empty cell. */ + if(!$filled) + { + echo "\n"; + } + $filled = FALSE; + } + + // End of row + echo " |
There are no possible schedules. Please try again.
'; + } + + /* edit button */ + if ($id = $this->id_get()) + echo ''; + + echo "There were a total of " . $this->possiblePermutations . " possible permutations. Only " . $this->nPermutations . " permutations had no class conflicts.
"; + + $outputPage->foot(); + } + + //-------------------------------------------------- + // Changes the title of the page. + //-------------------------------------------------- + function changeTitle($t) + { + $this->title = $t; + } + + //-------------------------------------------------- + // Make the time "pretty" + //-------------------------------------------------- + function prettyTime($t){ + if($t > 1259) + { + $t = ($t-1200); + return substr($t, 0, strlen($t)-2) . ":" . substr($t, strlen($t)-2, strlen($t)) . " PM"; + } else { + return substr($t, 0, strlen($t)-2) . ":" . substr($t, strlen($t)-2, strlen($t)) . " AM"; + } + } + + /** + * \brief + * fetch the number of classes + */ + function nclasses_get() + { + return count($this->courses); + } + + /** + * \brief + * fetch a specified class by its key + */ + function class_get($class_key) + { + return $this->courses[$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; + } + + /** + * \brief + * Write out a relative URL for a particular schedule. + * + * Takes into account the $clean_urls setting. + * + * \param $id + * The ID of the schedule to link to. Defaults to the current schedule object. + * \param $page + * The page of the schedule to link to. Defaults to 0. + * \return + * A string, the URL used to access this schedule. Remember that + * if this string is inserted into an XHTML document, + * htmlentities() must be called on it. + */ + function url($id = NULL, $page = 0) + { + global $clean_urls; + + $url = ''; + if (!$clean_urls) + $url .= 'process.php?s='; + + if (!$id) + $id = $this->id; + $url .= (int)$id; + if ($clean_urls) + $url .= '?'; + else + $url .= '&'; + + if ($page) + $url .= 'page=' . (int)$page . '&'; + + return $url; + } + + /** + * \brief + * A magic function which tries to upgrade old serialized sections + * to the new format. + */ + function __wakeup() + { + if ($this->nclasses == -1) + /* this Schedule doesn't need to be upgraded from Classes to Course */ + return; + + $this->courses = array(); + foreach ($this->classStorage as $classes) + { + $this->courses[] = $classes->to_course(); + } + $this->nclasses = -1; + } +} diff --git a/inc/class.section.php b/inc/class.section.php new file mode 100755 --- /dev/null +++ b/inc/class.section.php @@ -0,0 +1,262 @@ +. + */ + +//-------------------------------------------------- +// class.section.php Author:Nathan Gelderloos +// +// Represents a section of a class. +//-------------------------------------------------- + +require_once('inc/class.section_meeting.inc'); + +class Section +{ + + private $letter; // Section letter + private $prof; // Professor + + /* meeting times, array of SectionMeeting */ + private $meetings; + + /* the section synonym which uniquely identifies this section/course combination */ + private $synonym; + + /** + * \brief + * Construct a Section. + * + * \param $letter + * The identifier (often a letter or numeral) of this section. For + * CS-262-A, this would be 'a'. + * \param $section_meetings + * An array of SectionMeeting objects which describe all the + * different types of meetings this particular section has. It + * will be very uncommon for a course to have more than one such + * meeting time for a section. For example, Calvin doesn't have + * this. Another example, Cedarville lists different meeting times + * inside of a single section. Cedarville also lists all lectures + * and lab meeting times directly in a section's listing. + * \param $synonym + * Some schools have a unique number for each section. This field + * is for that number. + * \param $prof + * The faculty person(s) who teaches this section. + */ + function __construct ($letter, array $section_meetings = array(), $synonym = NULL, $prof = NULL) + { + $this->letter = $letter; + + $this->meetings = $section_meetings; + + $this->synonym = $synonym; + + $this->prof = $prof; + } + + public function getLetter() + { + return $this->letter; + } + + public function getProf() + { + return $this->prof; + } + + /** + * \return + * This section's synonym -- a unique numeric identifier for this + * course. NULL if undefined. + */ + public function getSynonym() + { + return $this->synonym; + } + + /** + * \brief + * Get an array of section meetings for this section. + * + * \return + * An array of SectionMeeting objects. + */ + public function getMeetings() + { + return $this->meetings; + } + + /** + * \brief + * Check if this section conflicts with the given section. + * + * \param $that + * The other section for which I should check for conflicts. + * \return + * TRUE if there is a conflict, FALSE otherwise. + */ + public function conflictsWith(Section $that) + { + foreach ($this->meetings as $this_meeting) + foreach ($that->meetings as $that_meeting) + if ($this_meeting->conflictsWith($that_meeting)) + return TRUE; + + return FALSE; + } + + /** + * \brief + * Add another section meeting time to this section. + * + * Useful for process.php when it's calling + * Schedule::addSectionMeeting() multiple times. + */ + public function meeting_add(SectionMeeting $meeting) + { + $this->meetings[] = $meeting; + } + + /** + * \brief + * Splits up a section specifier into dept, course number, and + * section. + * + * For example, will return array('CS', '262', 'A') for 'CS-262-A' + * or 'CS262 A' or 'cs-262,a'. This function is not for dealing with + * course synonyms. + * + * Note: Section specifiers where the section numeral/letter is + * directly adjacent to the course number is not valid. Calvin + * College distinguishes between normal courses and their labs by + * appending an `L' to the course number. Thus, 'CS262A' is not a + * valid specifier for 'CS-262-A' because there may exist another + * course called 'CS-262L-A' (which is likely the lab for the + * 'CS-262-A' class ;-)). + * + * \param $section_spec + * A string starting with a section specifier. If only the + * department is found, an array of size one is returned. If the + * course number is also found, both department and course id are + * returned. If all three are found, the array has three elements. + * + * This array is keyed, so the found items may be referred to as + * 'deptartment', 'course', and 'section'. + * + * \return + * An array with the department, course number, and section + * identifier. This array may be empty or have from one through + * three elements depending on the validity and precision of the + * $section_spec. + */ + public static function parse($section_spec) + { + $ret = array(); + + $section_spec = trim($section_spec); + if (!preg_match(';([a-zA-Z]+)[^0-9]*;', $section_spec, $dept_matches)) + return $ret; + + /* + * remove away the already-parsed stuff, including gunk between the + * dept and the course num. + */ + $section_spec = trim(substr($section_spec, strlen($dept_matches[0]))); + $ret['department'] = strtoupper($dept_matches[1]); + + if (!preg_match(';([0-9a-zA-Z]+)[^a-zA-Z0-9]*;', $section_spec, $course_matches)) + return $ret; + + /* skip gunk */ + $section_spec = trim(substr($section_spec, strlen($course_matches[0]))); + $ret['course'] = strtoupper($course_matches[1]); + + /* + * we accept _either_ alphabetic section _or_ numeric section (the + * latter is for cedarville, particulaly) + */ + if (!preg_match(';([0-9]+|[a-zA-Z]+);', $section_spec, $section_matches)) + return $ret; + + $ret['section'] = strtoupper($section_matches[1]); + + return $ret; + } + + /** + * \brief + * Get arrays of information needed by the AJAX stuff. + * + * \return + * An array of arrays that should be merged with the return value + * of other Section::to_json_array() calls. + */ + public function to_json_arrays() + { + $json_arrays = array(); + + foreach ($this->meetings as $meeting) + { + $json_array = array('section' => $this->letter, + 'prof' => $this->prof, + 'synonym' => $this->synonym, + ); + + $json_array += $meeting->to_json_array(); + $json_arrays[] = $json_array; + } + + return $json_arrays; + } + + + /* for legacy unserialization */ + private $start; + private $tend; + private $bdays; + + /** + * \brief + * A magic function which tries to upgrade old serialized sections + * to the new format. + */ + public function __wakeup() + { + /* upgrade to SectionMeeting stuffage */ + if (!empty($this->start)) + { + $days = ''; + $daymap = array(0 => 'm', 1 => 't', 2 => 'w', 3 => 'h', 4 => 'f'); + foreach ($this->bdays as $day => $have_day) + if ($have_day) + $days .= $daymap[$day]; + + /* the old format had a ->prof but initialied it to ``unknown prof'' */ + $this->prof = ''; + + $this->meetings = array(); + $this->meeting_add(new SectionMeeting($days, $this->start, $this->tend, '', 'lecture')); + + /* + * if we're reserialized in the future, make sure we don't do this same upgrade procedure again ;-). + */ + unset($this->start); + } + } +} diff --git a/input.php b/input.php --- a/input.php +++ b/input.php @@ -18,9 +18,9 @@ * along with SlatePermutate. If not, see