Changeset - 5d94cc8ac7cd
[Not reviewed]
default
1 10 2
Nathan Brink (binki) - 15 years ago 2010-12-31 23:46:17
ohnobinki@ohnopublishing.net
Rename class Classes to Course, fixes bug 30.
12 files changed with 147 insertions and 76 deletions:
0 comments (0 inline, 0 general)
admin/rehash.php
Show inline comments
 
@@ -359,68 +359,68 @@ function usage($progname)
 
	  . "              data. Cached data from schools not listed is preserved\n"
 
	  . " -v, --verbosity Set the verbosity level. Valid range is from 0\n"
 
	  . "              through 10.",
 
	  $progname);
 
}
 

	
 
/**
 
 * \brief
 
 *   A small testsuite to help developers.
 
 *
 
 * \return
 
 *   Number of failures.
 
 */
 
function test()
 
{
 
  $ideal = array('department' => 'CS',
 
		 'course' => '262',
 
		 'section' => 'A');
 
  $ideal_c = $ideal;
 
  unset($ideal_c['section']);
 
  $n = 0;
 

	
 
  $t1 = 'CS-262-A';
 
  $n += assert_equal($t1, Section::parse($t1), $ideal);
 
  $n += assert_equal($t1 . '_class', Classes::parse($t1), $ideal_c);
 
  $n += assert_equal($t1 . '_class', Course::parse($t1), $ideal_c);
 
  $t2 = 'cs262 a';
 
  $n += assert_equal($t2, Section::parse($t2), $ideal);
 
  $n += assert_equal($t2 . '_class', Classes::parse($t2), $ideal_c);
 
  $n += assert_equal($t2 . '_class', Course::parse($t2), $ideal_c);
 
  $t3 = 'cs 262 a';
 
  $n += assert_equal($t3, Section::parse($t2), $ideal);
 
  $n += assert_equal($t3 . '_class', Classes::parse($t3), $ideal_c);
 
  $n += assert_equal($t3 . '_class', Course::parse($t3), $ideal_c);
 

	
 
  $ideal['course'] .= 'L';
 
  $ideal_c['course'] = $ideal['course'];
 

	
 
  $t1 = 'CS-262L-A';
 
  $n += assert_equal($t1, Section::parse($t1), $ideal);
 
  $n += assert_equal($t1 . '_class', Classes::parse($t1), $ideal_c);
 
  $n += assert_equal($t1 . '_class', Course::parse($t1), $ideal_c);
 
  $t2 = 'cs262l a';
 
  $n += assert_equal($t2, Section::parse($t2), $ideal);
 
  $n += assert_equal($t2 . '_class', Classes::parse($t2), $ideal_c);
 
  $n += assert_equal($t2 . '_class', Course::parse($t2), $ideal_c);
 
  $t3 = 'cs 262l a';
 
  $n += assert_equal($t3, Section::parse($t2), $ideal);
 
  $n += assert_equal($t3 . '_class', Classes::parse($t3), $ideal_c);
 
  $n += assert_equal($t3 . '_class', Course::parse($t3), $ideal_c);
 

	
 
  return $n;
 
}
 

	
 
/**
 
 * \brief
 
 *   A reimplementation of a standard testsuite utility.
 
 *
 
 * \return
 
 *   TRUE if the test failed.
 
 */
 
function assert_equal($name, $a, $b)
 
{
 
  if (is_array($a))
 
    {
 
      $bad = FALSE;
 
      if (!is_array($b))
 
	{
 
	  fprintf(STDERR, "Test ``%s'' failed: \$a is an array while \$b isn't.\n",
 
		  $name);
 
	  return TRUE;
 
	}
 

	
 
      foreach ($a as $key => $val)
auto.php
Show inline comments
 
@@ -12,70 +12,70 @@
 
 * 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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * \file
 
 *   This file's purpose is to autocomplete class names for supporting
 
 *   the autocomplete JS based off of crawling schools' registration
 
 *   websites. This shall only perform the autocompletion of class
 
 *   names.
 
 *
 
 *   Since we output JSON, no special Page classes and stuff
 
 *   :-p. Except we still call the Page class's session_start()
 
 *   function because we apparently need sessions.... oh yeah, for
 
 *   school profile supports ;-).
 
 */
 

	
 
require_once('inc/school.inc');
 
require_once('inc/class.page.php');
 
require_once('class.class.php');
 
require_once('inc/class.course.inc');
 

	
 
Page::session_start();
 

	
 
if (isset($_REQUEST['txt'])) {
 
  header('Content-Type: text/plain; encoding=utf-8');
 
}
 
else {
 
  header('Content-Type: application/json; encoding=utf-8');
 
}
 

	
 
if (!isset($_REQUEST['term'])) {
 
  clean_empty_exit();
 
}
 

	
 
$getsections = FALSE;
 
if (isset($_REQUEST['getsections'])) {
 
  $getsections = TRUE;
 
}
 

	
 
$term = $_REQUEST['term'];
 
$term_parts = Classes::parse($term);
 
$term_parts = Course::parse($term);
 
if (!count($term_parts)) {
 
  clean_empty_exit();
 
}
 

	
 
$school = school_load_guess();
 
if (!$school['crawled']) {
 
  clean_empty_exit();
 
}
 

	
 
$cache_dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'auto' . DIRECTORY_SEPARATOR . $school['id'] . DIRECTORY_SEPARATOR;
 

	
 
/*
 
 * autocomplete the list of departments. If the user has already
 
 * entered a valid department name _and_ delimitted it, however, go on
 
 * to the next autocompletion step.
 
 */
 
$term_strlen = strlen($term);
 
$dept_strlen = strlen($term_parts['department']);
 
$dept = $term_parts['department'];
 
if (!$getsections && count($term_parts) == 1 && $term_strlen == strlen($dept))
 
  {
 
    $dept_file = $cache_dir . '-depts';
 
    if (!file_exists($dept_file)) {
 
      clean_empty_exit();
class.schedule.php
Show inline comments
 
@@ -5,213 +5,219 @@
 
 * This file is part of SlatePermutate.
 
 *
 
 * SlatePermutate 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.
 
 *
 
 * SlatePermutate 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 SlatePermutate.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
//**************************************************
 
// 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 'class.class.php';
 
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
 
{
 
  private $classStorage;			// Classes array of classes
 
  /*
 
   * 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->classStorage = array();
 
    $this->nclasses = 0;
 
    $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 addClass($n)
 
  function addCourse($n)
 
  {
 
    $this->classStorage[$this->nclasses] = new Classes($n);
 
    $this->nclasses++;
 
    $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;
 
      
 
    while(!$found && ($counter < $this->nclasses))
 
      {
 
	$temp = $this->classStorage[$counter]->getName();
 
			
 
	if(strcmp($temp,$course_name) == 0)
 
	  {
 
	    $found = true;
 
	  } else {
 
	  $counter++;
 

	
 
    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;
 
	}
 
      }
 
		
 
    if($counter == $this->nclasses)
 
      {
 
	echo 'Could not find class: ' . $course_name . "<br />\n";
 
      } else {
 
      $section = $this->classStorage[$counter]->section_get($letter);
 
      if (!$section)
 
	{
 
	  $section = new Section($letter, array(), $synonym, $faculty);
 
	  $this->classStorage[$counter]->section_add($section);
 
	}
 
      $section->meeting_add(new SectionMeeting($days, $time_start, $time_end, $location, $type));
 
    }
 

	
 
    echo 'Could not find class: ' . $course_name . "<br />\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 (!$this->nclasses)
 
		if (!count($this->courses))
 
		{
 
			/* have an empty schedule */
 
			$this->classStorage[0] = array();
 
			$this->nPermutations = 1;
 
			return;
 
		}
 

	
 
		$position = 0;
 
		$counter = 0;
 

	
 
		for($i = 0; $i < $this->nclasses; $i++)
 
		$i = 0;
 
		foreach ($this->courses as $course)
 
		{
 
			$this->possiblePermutations = $this->possiblePermutations * $this->classStorage[$i]->getnsections();
 
			$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 < $this->nclasses && !$conflict; $upCounter ++)
 
			for ($upCounter = 0; $upCounter < count($this->courses) && !$conflict; $upCounter ++)
 
			{
 
	    
 
				for ($downCounter = $this->nclasses - 1; $downCounter > $upCounter && !$conflict; $downCounter --)
 
			  for ($downCounter = count($this->courses) - 1; $downCounter > $upCounter && !$conflict; $downCounter --)
 
				{
 
				  if ($this->classStorage[$upCounter]->getSection($cs[$upCounter])
 
				      ->conflictsWith($this->classStorage[$downCounter]->getSection($cs[$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 < $this->nclasses; $i++)
 
	    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->classStorage[$position]->getnsections())
 
	    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 == $this->nclasses)
 
		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 */
 
@@ -334,51 +340,51 @@ class Schedule
 
				
 
	    // Header row
 
	    echo "          <tr>\n"
 
	      . '            <td class="none permuteNum">' . ($i + 1) . "</td>\n"
 
	      . "            <td class=\"day\">Monday</td>\n"
 
	      . "            <td class=\"day\">Tuesday</td>\n"
 
	      . "            <td class=\"day\">Wednesday</td>\n"
 
	      . "            <td class=\"day\">Thursday</td>\n"
 
	      . "            <td class=\"day\">Friday</td>\n"
 
	      . "          </tr>\n";
 

	
 
	    $last_meeting = array();
 
	    $rowspan = array(0, 0, 0, 0, 0);
 
	    for($r = 0; $r < (count($time)-1); $r++)
 
	      {
 

	
 
		echo "          <tr>\n"
 
		  . "            <td class=\"time\">" . $this->prettyTime($time[$r]) . "</td>\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 < $this->nclasses; $j++)
 
		      for($j = 0; $j < count($this->courses); $j++)
 
			{
 
			  $class = $this->classStorage[$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;
 

	
 
@@ -452,58 +458,58 @@ class Schedule
 
  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 $this->nclasses;
 
    return count($this->courses);
 
  }
 

	
 
  /*
 
  /**
 
   * \brief
 
   *   fetch a specified class by its key
 
   */
 
  function class_get($class_key)
 
  {
 
    return $this->classStorage[$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
 
@@ -516,25 +522,44 @@ class Schedule
 
   * \param $page
 
   *   The page of the schedule to link to. Defaults to 0.
 
   */
 
  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 . '&amp;';
 

	
 
    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;
 
  }
 
}
inc/class.classes_convert.inc
Show inline comments
 
new file 100644
 
<?php
 
/*
 
 * Copyright 2010 Nathan Gelderloos, Ethan Zonca, Nathan Phillip Brink
 
 *
 
 * This file is part of SlatePermutate.
 
 *
 
 * SlatePermutate 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.
 
 *
 
 * SlatePermutate 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 SlatePermutate.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
require_once('class.course.inc');
 

	
 
/**
 
 * \brief
 
 *   Class whose purpose is to upgrade deprecated saved_schedules in
 
 *   the Classes form into Course objects.
 
 */
 
class Classes
 
{
 
  private $name;	// String
 
  private $sections;	// Array of sections
 
  private $nsections;	// int
 

	
 
  public function to_course()
 
  {
 
    $course = new Course($this->name);
 

	
 
    foreach ($this->sections as $section)
 
      $course->section_add($section);
 

	
 
    return $course;
 
  }
 
}
inc/class.course.inc
Show inline comments
 
file renamed from class.class.php to inc/class.course.inc
 
@@ -5,49 +5,49 @@
 
 * This file is part of SlatePermutate.
 
 *
 
 * SlatePermutate 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.
 
 *
 
 * SlatePermutate 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 SlatePermutate.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
/**
 
 * \file
 
 *    This file represents a course (formerly class). It stores
 
 *    the section associated with the course.
 
 */
 

	
 
include_once 'class.section.php';
 

	
 
class Classes
 
class Course
 
{
 
  private $name;	// String
 
  private $sections;	// Array of sections
 
  private $nsections;	// int
 
    
 
  /**
 
   * \brief
 
   *    Creates a class with the given name.
 
   * \param $n
 
   *    The name of the class.
 
   */
 
  function __construct($n)
 
  {
 
    $this->sections = array();
 
    $this->name = $n;
 
    $this->nsections = 0;
 
  }
 
	
 
  /**
 
   * \brief
 
   *   Adds an already-instantiated section to this class.
 
   */
 
  public function section_add(Section $section)
 
  {
inc/class.semester.inc
Show inline comments
 
<?php
 
/*
 
 * Copyright 2010 Nathan Phillip Brink <ohnobinki@ohnopublishing.net>
 
 *
 
 * 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 <http://www.gnu.org/licenses/>.
 
 */
 

	
 
$root_dir = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR;
 
require_once($root_dir . 'class.class.php');
 
$inc_dir = $root_dir . 'inc' . DIRECTORY_SEPARATOR;
 
require_once($inc_dir . 'class.course.inc');
 
require_once($root_dir . 'class.section.php');
 

	
 
/**
 
 * \brief
 
 *   Identifies a school semester and acts as a container for courses
 
 *   offered in a semester.
 
 */
 
class Semester
 
{
 
  /**
 
   * \brief
 
   *   The Fall season.
 
   */
 
  const SEASON_FALL = 'fall';
 

	
 
  /**
 
   * \brief
 
   *   The Spring season.
 
   */
 
  const SEASON_SPRING = 'spring';
 

	
 
  /**
 
   * \brief
 
   *   Instantiate an empty Semester.
 
@@ -50,71 +51,71 @@ class Semester
 
   * \param $season
 
   *   The season of this semester. Currently, only
 
   *   Semester::SEASON_SPRING and Semester::SEASON_FALL are valid.
 
   */
 
  function __construct($year, $season)
 
  {
 
    if (!in_array($season, array(self::SEASON_SPRING, self::SEASON_FALL)))
 
      throw new ErrorException('Attempt to construct a Semester with a $season which is neither Semester::SEASON_SPRING nor Semester::SEASON_FALL. `' . $season . '\' was given.');
 
    $this->season = $season;
 

	
 
    if (strlen($year) != 4)
 
      throw new ErrorException('Attempt to construct a Semester with an invalid year. The given year is `' . $year . '\'');
 
    $this->year = $year;
 

	
 
    $this->departments = array();
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Add a class to this Semester.
 
   *
 
   * \param $class
 
   *   The class/course to add.
 
   */
 
  public function class_add(Classes $class)
 
  public function class_add(Course $class)
 
  {
 
    $class_parts = Classes::parse($class->getName());
 
    $class_parts = Course::parse($class->getName());
 
    if (!isset($class_parts['course']))
 
      throw ErrorException('I was given a class with an invalid name: `' . $class->getName() . '\'');
 

	
 
    if (!isset($this->departments[$class_parts['department']]))
 
      $this->departments[$class_parts['department']] = array();
 
    $department =& $this->departments[$class_parts['department']];
 

	
 
    $department[$class_parts['course']] = $class;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Retrieve a class.
 
   *
 
   * \param $dept
 
   *   The class's department. 'CS' for 'CS-262'.
 
   * \param $class
 
   *   The course/class number. '262' for 'cs-262'.
 
   * \return
 
   *   A Classes or NULL if not found.
 
   *   A Course or NULL if not found.
 
   */
 
  public function class_get($dept, $class)
 
  {
 
    if (!isset($this->departments[$dept][$class]))
 
      return NULL;
 

	
 
    return $this->departments[$dept][$class];
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Gets a list of departments available in this semester.
 
   */
 
  public function departments_get()
 
  {
 
    return array_keys($this->departments);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Gets a list of class/course numbers available for a particular
 
   *   department.
 
   */
 
  public function department_classes_get($dept)
 
@@ -124,49 +125,49 @@ class Semester
 

	
 
    return array_keys($this->departments[$dept]);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Utility function to add a section to the semester,
 
   *   automatically creating classes as necessary.
 
   *
 
   * \param $dept
 
   *   The department this section belongs to.
 
   * \param $class
 
   *   The class this section belongs to.
 
   * \param $section
 
   *   The section itself.
 
   */
 
  public function section_add($dept, $class, Section $section)
 
  {
 
    $dept = strtoupper($dept);
 
    $class = strtoupper($class);
 

	
 
    if (!isset($this->departments[$dept])
 
	|| !isset($this->departments[$dept][$class]))
 
      {
 
	$classobj = new Classes($dept . '-' . $class);
 
	$classobj = new Course($dept . '-' . $class);
 
	$this->class_add($classobj);
 
      }
 
    else
 
      {
 
	$classobj = $this->departments[$dept][$class];
 
      }
 

	
 
    $classobj->section_add($section);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Get a semester's year.
 
   */
 
  public function year_get()
 
  {
 
    return $this->year;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Get a semester's season.
 
   */
 
  public function season_get()
inc/schedule_store.inc
Show inline comments
 
@@ -121,41 +121,43 @@ function schedule_store_retrieve($schedu
 
 *
 
 * \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.
 
 * \return
 
 *   TRUE on success, FALSE on failure. (see flock()).
 
 */
 
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']);
 
}
inc/school.inc
Show inline comments
 
@@ -241,49 +241,49 @@ function school_list_html($highlight = N
 
 *   handle is invalid.
 
 */
 
function school_instructions_html($school)
 
{
 
  if (!$school || !$school['id']
 
      || !function_exists($school['id'] . '_instructions_html'))
 
    return NULL;
 

	
 
  $school_instructions_html = $school['id'] . '_instructions_html';
 
  return $school_instructions_html();
 
}
 

	
 
/**
 
 * \brief
 
 *   Return an array of default classes for a particular school.
 
 *
 
 * \param $school
 
 *   The school's handle.
 
 */
 
function school_default_classes($school)
 
{
 
  $school_default_classes = $school['id'] . '_default_classes';
 
  if (function_exists($school_default_classes))
 
    {
 
      require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'class.class.php');
 
      require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'class.course.inc');
 
      return $school_default_classes();
 
    }
 

	
 
  return array();
 
}
 

	
 
/**
 
 * \brief
 
 *   Used to load the school cache.
 
 *
 
 * \return
 
 *   The cache array or NULL if the cache couldn't be loaded.
 
 */
 
function _school_cache_load()
 
{
 
  static $cache = NULL;
 

	
 
  if ($cache != NULL)
 
    return $cache;
 

	
 
  $cache_file_name = dirname(__FILE__) . DIRECTORY_SEPARATOR . '..'
 
    . DIRECTORY_SEPARATOR . 'cache' . DIRECTORY_SEPARATOR . 'schools';
 
  $cache_serialized = @file_get_contents($cache_file_name);
 
  if (!empty($cache_serialized))
input.php
Show inline comments
 
<?php 
 
/*
 
 * Copyright 2010 Nathan Gelderloos, Ethan Zonca, Nathan Phillip Brink
 
 *
 
 * This file is part of SlatePermutate.
 
 *
 
 * SlatePermutate 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.
 
 *
 
 * SlatePermutate 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 SlatePermutate.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
include_once 'class.schedule.php';
 
include_once 'class.class.php';
 
include_once 'inc' . DIRECTORY_SEPARATOR . 'class.course.inc';
 
include_once 'class.section.php';
 
include_once 'inc/class.page.php';
 
require_once('inc/schedule_store.inc');
 

	
 
$scripts = array('jQuery', 'jQueryUI', 'jValidate','qTip','schedInput');
 
$inputPage = new page('Scheduler', $scripts, FALSE);
 

	
 

	
 

	
 
$schedule_store = FALSE;
 
$sch = FALSE;
 
$school = $inputPage->get_school();
 

	
 
if (isset($_REQUEST['s']))
 
  {
 
    $schedule_store = schedule_store_init();
 
    $schedule_id = (int)$_REQUEST['s'];
 
    $sch = schedule_store_retrieve($schedule_store, $schedule_id);
 
  }
 

	
 
$my_hc = 'jQuery(document).ready(
 
  function()
 
  {
 
    var class_last = 0;
 
@@ -130,47 +130,47 @@ if (!empty($_REQUEST['selectschool'])
 
          <td class="center"></td>
 
        </tr>
 
      </table>
 
    </td>
 
  </tr>
 
  <tr>
 
    <td><span class="gray" style="padding: 0 3.5em 0 3.5em;" id="addclass">Add Class</span></td>
 
  </tr>
 
</table>
 

	
 
<div class="paddingtop">
 
  <input class="green" style="margin:0;padding:0;" type="submit" value="Find a schedule" />
 
</div>
 

	
 
</form>
 

	
 
<p>&nbsp;<br /><br /><br /></p>
 
<?php 
 

	
 
/* Show/hide Advanced Options: <p><span id="showadvanced" style="margin-left: 1em;"><a href="#">Advanced</a></span></p> */ 
 

	
 
$inputPage->showSchoolInstructions();
 
$inputPage->foot();
 

	
 
function input_class_js(Classes $class, $whitespace = '  ')
 
function input_class_js(Course $class, $whitespace = '  ')
 
{
 
  $js = $whitespace . 'class_last = add_class_n(\'' . htmlentities($class->getName(), ENT_QUOTES) . "');\n";
 

	
 
  $nsections  = $class->getnsections();
 
  for ($section_key = $nsections - 1; $section_key >= 0; $section_key --)
 
    {
 
      $section = $class->getSection($section_key);
 
      $meetings = $section->getMeetings();
 
      foreach ($meetings as $meeting)
 
	{
 
	  $js .= $whitespace . 'add_section_n(class_last, \'' . htmlentities($section->getLetter(), ENT_QUOTES) . '\', \''
 
	    . htmlentities($section->getSynonym(), ENT_QUOTES) . '\', \''
 
	    . $meeting->getStartTime() . '\', \''
 
	    . $meeting->getEndTime() . '\', '
 
	    . json_encode(array('m' => $meeting->getDay(0), 't' => $meeting->getDay(1), 'w' => $meeting->getDay(2), 'h' => $meeting->getDay(3), 'f' => $meeting->getDay(4))) . ', \''
 
	    . htmlentities($section->getProf(), ENT_QUOTES) . '\', \''
 
	    . htmlentities($meeting->getLocation(), ENT_QUOTES) . "');\n";
 
	}
 
    }
 

	
 
  return $js;
 
}
process.php
Show inline comments
 
<?php
 
/*
 
 * Copyright 2010 Nathan Gelderloos, Ethan Zonca, Nathan Phillip Brink
 
 *
 
 * This file is part of SlatePermutate.
 
 *
 
 * SlatePermutate 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.
 
 *
 
 * SlatePermutate 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 SlatePermutate.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
require_once('inc/schedule_store.inc');
 
require_once('inc/class.page.php');
 
include_once 'class.schedule.php';
 
include_once 'class.class.php';
 
include_once('inc/class.course.inc');
 
include_once 'class.section.php';
 

	
 
// Converts a 5-element day array into a string.
 
// Supports multiple modes, prettiness, and searching for different indicators
 
function arrayToDays($array, $mode = 'num', $pretty = false, $key = 1) {
 
	$outString = '';
 
	switch($mode)
 
	  {
 
		case 'short':
 
			$days = array('Mon','Tue','Wed','Thur','Fri');
 
			break;
 
		case 'long':
 
			$days = array('Monday','Tuesday','Wednesday','Thursday','Friday');
 
			break;
 
		case 'num':
 
			$days = array('1','2','3','4','5');
 
			break;
 
	  case 'alpha':
 
	    $days = array('m', 't', 'w', 'h', 'f');
 
	    break;
 
		default:
 
			$outString = 'Invalid mode passed to arrayToDays()!';
 
			return $outString;
 
	}
 
@@ -112,49 +112,49 @@ if(!$DEBUG)
 
    elseif (!isset($_POST['postData']))
 
      {
 
	page::redirect('input.php');
 
	exit;
 
      }
 
    else
 
      {
 
	/*
 
	 * we probably have input from the user and should interpret
 
	 * it as a schedule to permutate. Then we should redirect the
 
	 * user to the canonical URL for that schedule.
 
	 */
 
		$allClasses = new Schedule($_POST['postData']['name']);
 
	
 
		foreach($_POST['postData'] as $class)
 
		{
 
		  /*
 
		   * Only add classes if the user added at least one
 
		   * section to the class. We know that $class['name']
 
		   * is not a section, so count() needs to be > 1 and
 
		   * we need to skip over 'name' in our loop.
 
		   */
 
			if(is_array($class) && count($class) > 1)
 
			{
 
				$allClasses->addClass($class['name']);
 
				$allClasses->addCourse($class['name']);
 
		
 
				foreach($class as $section)
 
				  /* Skip the section name, which isn't a section */
 
					if(is_array($section))
 
					{
 
					  $allClasses->addSection($class['name'], $section['letter'], $section['start'], $section['end'], arrayToDays($section['days'], 'alpha'), $section['synonym'], $section['professor'], $section['location'], $section['type']);
 
					}
 
			}
 
		}
 
		$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();
 

	
 
		$process_php_s = '';
 
		if (!$clean_urls)
 
		  $process_php_s = 'process.php?s=';
 
		page::redirect($process_php_s . $schedule_id);
 
		exit;
 
      }
 
  }
 
else
schedulecreator.php
Show inline comments
 
<?php
 
/*
 
 * Copyright 2010 Nathan Gelderloos, Ethan Zonca, Nathan Phillip Brink
 
 *
 
 * This file is part of SlatePermutate.
 
 *
 
 * SlatePermutate 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.
 
 *
 
 * SlatePermutate 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 SlatePermutate.  If not, see <http://www.gnu.org/licenses/>.
 
 */
 

	
 
include_once 'class.schedule.php';
 
include_once 'class.class.php';
 
include_once 'inc/class.course.inc';
 
include_once 'class.section.php';
 

	
 
//**************************************************
 
// ScheduleCreator.java	Author: Nathan Gelderloos
 
// 
 
// Creates a list of classes.
 
//**************************************************
 

	
 
   
 
         $allClasses = new Schedule("Fall 2010");
 
  	
 
         $allClasses->addClass("CS 104");
 
         $allClasses->addCourse("CS 104");
 
         $allClasses->addSection("CS 104", "A", 1030, 1120, 'th');
 
      	
 
         $allClasses->addClass("Engr 209");
 
         $allClasses->addCourse("Engr 209");
 
         $allClasses->addSection("Engr 209", "A", 1330, 1420, 'mtwf');
 
         $allClasses->addSection("Engr 209", "B", 1430, 1520, 'mtwf');
 
      	
 
         $allClasses->addClass("Engr 209L");
 
         $allClasses->addCourse("Engr 209L");
 
         $allClasses->addSection("Engr 209L", "A", 1830, 2120, 'h');
 
         $allClasses->addSection("Engr 209L", "B", 1830, 2120, 'w');
 
      	
 
         $allClasses->addClass("Math 231");
 
         $allClasses->addCourse("Math 231");
 
         $allClasses->addSection("Math 231", "A", 800, 850, 'mtwf');
 
      	
 
         $allClasses->addClass("Phys 235");
 
         $allClasses->addCourse("Phys 235");
 
         $allClasses->addSection("Phys 235", "A", 900, 950, 'mwf');
 
         $allClasses->addSection("Phys 235", "B", 1130, 1220, 'mwf');
 
         $allClasses->addSection("Phys 235", "C", 1230, 1320, 'mwf');
 
      	
 
         $allClasses->addClass("Phys 235L");
 
         $allClasses->addCourse("Phys 235L");
 
         $allClasses->addSection("Phys 235L", "A", 1430, 1720, 'm');
 
         $allClasses->addSection("Phys 235L", "B", 1430, 1720, 'w');
 
         $allClasses->addSection("Phys 235L", "C", 830, 1120, 'h');
 
         $allClasses->addSection("Phys 235L", "D", 1230, 1520, 'h');
 
      	
 
         $allClasses->addClass("Rel 131");
 
         $allClasses->addCourse("Rel 131");
 
         $allClasses->addSection("Rel 131", "A", 800, 850, 'mwf');
 
         $allClasses->addSection("Rel 131", "B", 900, 950, 'mwf');
 
         $allClasses->addSection("Rel 131", "C", 1330, 1420, 'mwf');
 
         $allClasses->addSection("Rel 131", "D", 1430, 1520, 'mwf');
 
         $allClasses->addSection("Rel 131", "E", 835, 950, 'th');
 
         $allClasses->addSection("Rel 131", "F", 1030, 1145, 'th');
 
         $allClasses->addSection("Rel 131", "G", 1205, 1320, 'th');
 
         $allClasses->addSection("Rel 131", "H", 1330, 1445, 'th');
 
      	       
 
         $allClasses->findPossibilities();
 
         $allClasses->writeoutTables();
school.d/cedarville.inc
Show inline comments
 
@@ -31,53 +31,53 @@ function cedarville_info()
 

	
 
function cedarville_instructions_html()
 
{
 
  return <<<EOF
 
<h2>Instructions</h2>
 
<p>
 
  SlatePermutate can be a useful tool for scheduling your next semester at <a href="http://cedarville.edu/" rel="external">Cedarville University</a>.
 
</p>
 
<ol>
 
  <li>Enter the course ID, such as PHYS-1020, in the Class ID blank. You will see a list of auto-suggestions.</li>
 
  <li><strong>You must click on the auto-suggested item</strong> to automatically add all sections of the class.</li>
 
  <li>Submit your schedule and view all of the different permutations of your schedule.</li>
 
  <li><strong>Schedule a meeting with your advisor to review your schedule.</strong></li>
 
  <li>When it's time to register, check the "Show Synonyms" box on your schedule and enter your course synonyms into the registration interface.</li>
 
</ol> <!--'-->
 
EOF;
 
}
 

	
 
/**
 
 * \brief
 
 *   Get a list of default classes (with sections (with meeting
 
 *   times)) for Cedarville students.
 
 *
 
 * \return
 
 *   An array of Classes objects.
 
 *   An array of Course objects.
 
 */
 
function cedarville_default_classes()
 
{
 
  $chapel = new Classes('Chapel');
 
  $chapel = new Course('Chapel');
 
  $chapel->section_add(new Section('_', array(new SectionMeeting('mtwhf', '1000', '1045', '', 'chapel')),
 
				   '', '_'));
 

	
 
  return array($chapel);
 
}
 

	
 
/**
 
 * \brief
 
 *   Parse given html into an array, first row is row headers
 
 *
 
 * \param $html
 
 *   HTML that PHP's DOM would willingly would eat.
 
 */
 
function table_parse($html)
 
{
 
  libxml_use_internal_errors(true); // Suppress warnings
 
  $arr = array();
 
  $dom = new DOMDocument;
 
  if(!$html)
 
    return NULL;
 

	
 
  $dom->loadHTML($html);
 
  $dom->preserveWhiteSpace = FALSE;
 
  $tables = $dom->getElementsByTagName('table');
0 comments (0 inline, 0 general)