Changeset - 12553a2740cb
[Not reviewed]
default
0 9 1
Nathan Brink (binki) - 15 years ago 2010-10-19 00:40:13
ohnobinki@ohnopublishing.net
Split out the Section class into Section and SectionMeeting. This allows the flexibility of Cedarville's system where a single section may have multiple meeting times -- most commonly for labs, but sometimes classes have multiple lectures.
10 files changed with 436 insertions and 268 deletions:
0 comments (0 inline, 0 general)
class.class.php
Show inline comments
 
@@ -10,24 +10,25 @@ include_once 'class.section.php';
 

	
 
class Classes
 
{
 
  private $name;		// String
 
  private $sections;	// Array of sections
 
  private $nsections;	// int
 
    
 
  //--------------------------------------------------
 
  // Creates a class with the given name.
 
  //--------------------------------------------------
 
  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)
 
  {
 
    $this->sections[$this->nsections] = $section;
 
    $this->nsections ++;
 
@@ -48,25 +49,46 @@ class Classes
 
  {
 
    // Checks to make sure the desired section is part of the set.
 
    if(isset($this->sections[$i]))
 
      {
 
	//echo "Object sections[$i] was set<br />";
 
      } else {
 
      echo "Object sections[$i] was NOT set <br />";
 
    }
 

	
 
    $result = $this->sections[$i];
 
    return $result;
 
  }
 
    
 

	
 
  /**
 
   * \brief
 
   *   Retrieve a section of this class based on its letter.
 
   *
 
   * \todo Make this function replace completely the getSection()
 
   * function, have $this->sections be keyed by letter, and have a
 
   * __wakup() convert the old $this->sections format to the new one.
 
   *
 
   * \return
 
   *   The requested section or NULL if that section does not yet
 
   *   exist for this class.
 
   */
 
  public function section_get($letter)
 
  {
 
    foreach ($this->sections as $section)
 
      if ($section->getLetter() == $letter)
 
	return $section;
 

	
 
    return NULL;
 
  }
 

	
 
  //--------------------------------------------------
 
  // Returns the name of the class.
 
  //--------------------------------------------------
 
  public function getName()
 
  {
 
    return $this->name;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Split up a user-friendly course specification into components.
 
   *
 
@@ -102,18 +124,20 @@ class Classes
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Represent this class as an array of sections ready to be JSONized.
 
   */
 
  public function to_json_array()
 
  {
 
    $json_array = array('class' => $this->getName(),
 
			'sections' => array());
 
    foreach ($this->sections as $section)
 
      {
 
	$json_array['sections'][] = $section->to_json_array();
 
	$section_json_arrays = $section->to_json_arrays();
 
	foreach ($section_json_arrays as $section_json_array)
 
	  $json_array['sections'][] = $section_json_array;
 
      }
 

	
 
    return $json_array;
 
  }
 
}
class.schedule.php
Show inline comments
 
@@ -62,46 +62,52 @@ class Schedule
 
  //--------------------------------------------------
 
  // Adds a new class to the schedule.
 
  //--------------------------------------------------
 
  function addClass($n)
 
  {
 
    $this->classStorage[$this->nclasses] = new Classes($n);
 
    $this->nclasses++;
 
  }
 

	
 
  //--------------------------------------------------
 
  // Adds a section to the desired class.
 
  //--------------------------------------------------
 
  function addSection($n, $l, $s, $e, $d, $synonym = NULL, $faculty = NULL, $room = NULL)
 
  function addSection($course_name, $letter, $time_start, $time_end, $days, $synonym = NULL, $faculty = NULL, $room = NULL)
 
  {
 
    $found = false;
 
    $counter = 0;
 
      
 
    while(!$found && ($counter < $this->nclasses))
 
      {
 
	$temp = $this->classStorage[$counter]->getName();
 
			
 
	if((strcmp($temp,$n)) == 0)
 
	if((strcmp($temp,$course_name)) == 0)
 
	  {
 
	    $found = true;
 
	  } else {
 
	  $counter++;
 
	}
 
      }
 
		
 
    if($counter == $this->nclasses)
 
      {
 
	echo "Could not find class: " . $n . "<br />";
 
	echo 'Could not find class: ' . $course_name . "<br />\n";
 
      } else {
 
      $this->classStorage[$counter]->section_add(new Section($l, $s, $e, $d, $synonym, $faculty, $room));
 
      $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, $room));
 
    }
 
  }
 

	
 
  //--------------------------------------------------
 
  // 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)
 
@@ -267,63 +273,87 @@ class Schedule
 
	    $table .= "<table style=\"empty-cells:show;\" border=\"1\" cellspacing=\"0\">";
 
				
 
	    // Header row
 
	    $table .= "\n\t<tr>\n\t\t<td class=\"none permuteNum\">" . ($i+1) . "</td>\n\t\t<td class=\"day\">Monday</td>\n\t\t<td class=\"day\">Tuesday</td>\n\t\t<td class=\"day\">Wednesday</td>\n\t\t<td class=\"day\">Thursday</td>\n\t\t<td class=\"day\">Friday</td>\n\t</tr>";
 

	
 
	    for($r = 0; $r < (count($time)-1); $r++)
 
	      {
 

	
 
		$table .= "\n\t<tr>\n\t\t<td class=\"time\">" . $this->prettyTime($time[$r]) . "</td>";
 

	
 
		for($dayLoop = 0; $dayLoop < 5; $dayLoop++)
 
		{
 
		  $last_meeting = NULL;
 
			for($j = 0; $j < $this->nclasses; $j++)
 
			{
 
			  $class = $this->classStorage[$j];
 
			  $section_index = $this->storage[$i][$j];
 
			  $section = $class->getSection($section_index);
 
				// Makes sure there is not a class already in progress
 
				if($this->getClassCont($dayLoop) == -1)
 
				{
 
					// Checks if the class meets on the given day
 
					if(($this->classStorage[$j]->getSection($this->storage[$i][$j])->getDay($dayLoop)))
 
				  /* 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;
 
					  /* $last_meeting has meaning for a longer time than $current_meeting does. */
 
					  $last_meeting = $meeting;
 
					}
 
				    }
 
				  
 
				  if ($current_meeting)
 
				    {
 
				      // Checks if the class continues after the given time
 
				      if($current_meeting->getEndTime() > $time[$r+1])
 
					{
 
						// Checks if the class meets at the given time
 
						if(($this->classStorage[$j]->getSection($this->storage[$i][$j])->getStartTime() >= $time[$r]) && ($this->classStorage[$j]->getSection($this->storage[$i][$j])->getStartTime() < $time[$r+1]))
 
						{
 
							// Checks if the class continues after the given time
 
							if($this->classStorage[$j]->getSection($this->storage[$i][$j])->getEndTime() > $time[$r+1])
 
							{
 
								$table .= "\n\t\t<td class=\"top class{$j}\">" . htmlentities($this->classStorage[$j]->getName()) . " " . htmlentities($this->classStorage[$j]->getSection($this->storage[$i][$j])->getLetter()) . "</td>";
 
								$this->setClassCont($dayLoop, $j);
 
								$filled = true;
 
							}else{
 
								$table .= "\n\n\t<td class=\"single class{$j}\">" . htmlentities($this->classStorage[$j]->getName()) . " " . htmlentities($this->classStorage[$j]->getSection($this->storage[$i][$j])->getLetter()) . "</td>";
 
								$filled = true;
 
							}
 
						}
 
					  $table .= "\n\t\t<td class=\"top class{$j}\">" . htmlentities($class->getName()) . " " . htmlentities($section->getLetter()) . "</td>";
 
					  $this->setClassCont($dayLoop, $j);
 
					  $filled = TRUE;
 
					}
 
				      else
 
					{
 
					  $table .= "\n\n\t<td class=\"single class{$j}\">" . htmlentities($class->getName()) . " " . htmlentities($section->getLetter()) . "</td>";
 
					  $filled = TRUE;
 
					}
 
				}else{
 
					if($j == $this->getClassCont($dayLoop))
 
					{
 
						if($this->classStorage[$j]->getSection($this->storage[$i][$j])->getEndTime() > $time[$r+1])
 
						{
 
							$table .= "\n\t\t<td class=\"mid class{$j}\">&nbsp;</td>";
 
							$filled = true;
 
						}else{
 
							$table .= "\n\t\t<td class=\"end class{$j}\">&nbsp;</td>";
 
							$this->setClassCont($dayLoop, -1);
 
							$filled = true;
 
						}
 
					}
 
				    }
 
				}
 
			}
 
			
 
				
 
				else
 
				  {
 
				    if($j == $this->getClassCont($dayLoop))
 
				      {
 
					if($last_meeting
 
					   && $last_meeting->getEndTime() > $time[$r+1])
 
					  {
 
					    $table .= "\n\t\t<td class=\"mid class{$j}\">&nbsp;</td>";
 
					    $filled = TRUE;
 
					  }
 
					else
 
					  {
 
					    $table .= "\n\t\t<td class=\"end class{$j}\">&nbsp;</td>";
 
					    $this->setClassCont($dayLoop, -1);
 
					    $filled = TRUE;
 
					  }
 
				      }
 
			  }
 
		}
 

	
 
			// If the cell was not filled, fill it with an empty cell.
 
			if(!$filled)
 
			{
 
				$table .= "\n\t\t<td class=\"none\">&nbsp;</td>";
 
			}
 
			$filled = false;
 
		}
 
		
 
		// End of row
 
		$table .= "\n\t</tr>";
 
	      }
 

	
class.section.php
Show inline comments
 
<?php
 

	
 
//--------------------------------------------------
 
// 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
 
  private $start;	// Start time
 
  private $tend;	// End time
 
  private $idays;	// Integer version of meeting days
 
  private $bdays;	// Boolean array of meeting days
 

	
 
  /* 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 $time_start
 
   *   The time of day when this section meets. Formatted as a string,
 
   *   with the 24-hr representation of the hour taking the first two
 
   *   characters and a two-digit representation of minutes taking the
 
   *   next two characters.
 
   * \param $time_end
 
   *   The time of day when this section's meeting is over.
 
   * \param $days
 
   *   A string representing the days that this section meets. The
 
   *   format of this string is an ordered series of numerals less
 
   *   than or equal to 5. Each numeral from 1 through 5 represents
 
   *   one of Monday, Tuesday, Wednesday, Thursday, and Friday. For
 
   *   example, '135' would be for a course which meets on Monday,
 
   *   Wednesday, and Friday.
 
   * \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.
 
   * \param $room
 
   *   An identifier of the room within which the section is taught.
 
   */
 
  function __construct ($letter, $time_start, $time_end, $days,
 
			$synonym = NULL, $prof = NULL, $room = NULL)
 
  function __construct ($letter, array $section_meetings = array(), $synonym = NULL, $prof = NULL)
 
  {
 
    $this->letter = $letter;
 
    $this->start = $time_start;
 
    $this->tend = $time_end;
 

	
 
    $this->idays = $days;
 
    $this->bdays = $this->setbdays();
 

	
 
    $this->synonym = $synonym;
 
    $this->prof = $prof;
 
    $this->room = $room;
 
  }
 

	
 
  private function setbdays()
 
  {
 
    $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;}
 

	
 
    if($this->idays == 1234)
 
      {$result[0] = true; $result[1] = true; $result[2] = true; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 1235)
 
      {$result[0] = true; $result[1] = true; $result[2] = true; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 1245)
 
      {$result[0] = true; $result[1] = true; $result[2] = false; $result[3] = true; $result[4] = true;}
 
    if($this->idays == 1345)
 
      {$result[0] = true; $result[1] = false; $result[2] = true; $result[3] = true; $result[4] = true;}
 
    if($this->idays == 2345)
 
      {$result[0] = false; $result[1] = true; $result[2] = true; $result[3] = true; $result[4] = true;}
 

	
 
    if($this->idays == 123)
 
      {$result[0] = true; $result[1] = true; $result[2] = true; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 124)
 
      {$result[0] = true; $result[1] = true; $result[2] = false; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 125)
 
      {$result[0] = true; $result[1] = true; $result[2] = false; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 134)
 
      {$result[0] = true; $result[1] = false; $result[2] = true; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 135)
 
      {$result[0] = true; $result[1] = false; $result[2] = true; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 145)
 
      {$result[0] = true; $result[1] = false; $result[2] = false; $result[3] = true; $result[4] = true;}
 
    if($this->idays == 234)
 
      {$result[0] = false; $result[1] = true; $result[2] = true; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 235)
 
      {$result[0] = false; $result[1] = true; $result[2] = true; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 245)
 
      {$result[0] = false; $result[1] = true; $result[2] = false; $result[3] = true; $result[4] = true;}
 
    if($this->idays == 345)
 
      {$result[0] = false; $result[1] = false; $result[2] = true; $result[3] = true; $result[4] = true;}
 
    $this->meetings = $section_meetings;
 

	
 
    if($this->idays == 12)
 
      {$result[0] = true; $result[1] = true; $result[2] = false; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 13)
 
      {$result[0] = true; $result[1] = false; $result[2] = true; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 14)
 
      {$result[0] = true; $result[1] = false; $result[2] = false; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 15)
 
      {$result[0] = true; $result[1] = false; $result[2] = false; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 23)
 
      {$result[0] = false; $result[1] = true; $result[2] = true; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 24)
 
      {$result[0] = false; $result[1] = true; $result[2] = false; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 25)
 
      {$result[0] = false; $result[1] = true; $result[2] = false; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 34)
 
      {$result[0] = false; $result[1] = false; $result[2] = true; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 35)
 
      {$result[0] = false; $result[1] = false; $result[2] = true; $result[3] = false; $result[4] = true;}
 
    if($this->idays == 45)
 
      {$result[0] = false; $result[1] = false; $result[2] = false; $result[3] = true; $result[4] = true;}
 
      
 
    if($this->idays == 1)
 
      {$result[0] = true; $result[1] = false; $result[2] = false; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 2)
 
      {$result[0] = false; $result[1] = true; $result[2] = false; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 3)
 
      {$result[0] = false; $result[1] = false; $result[2] = true; $result[3] = false; $result[4] = false;}
 
    if($this->idays == 4)
 
      {$result[0] = false; $result[1] = false; $result[2] = false; $result[3] = true; $result[4] = false;}
 
    if($this->idays == 5)
 
      {$result[0] = false; $result[1] = false; $result[2] = false; $result[3] = false; $result[4] = true;}
 
         
 
    return $result;
 
    $this->prof = $prof;
 
  }
 

	
 
  public function getLetter()
 
  {
 
    return $this->letter;
 
  }
 

	
 
  public function getProf()
 
  {
 
    return $this->prof;
 
  }
 

	
 
  /**
 
   * \return
 
   *   This Section's room or NULL if none is defined.
 
   */
 
  public function getRoom()
 
  {
 
    return $this->room;
 
  }
 

	
 
  /**
 
   * \return
 
   *   This section's synonym -- a unique numeric identifier for this
 
   *   course. NULL if undefined.
 
   */
 
  public function getSynonym()
 
  {
 
    return $this->synonym;
 
  }
 

	
 
  public function getStartTime()
 
  {
 
    return $this->start;
 
  }
 

	
 
  public function getEndTime()
 
  {
 
    return $this->tend;
 
  }
 

	
 
  public function getM()
 
  {
 
    return $this->bdays[0];
 
  }
 

	
 
  public function getTu()
 
  /**
 
   * \brief
 
   *   Get an array of section meetings for this section.
 
   *
 
   * \return
 
   *   An array of SectionMeeting objects.
 
   */
 
  public function getMeetings()
 
  {
 
    return $this->bdays[1];
 
  }
 

	
 
  public function getW()
 
  {
 
    return $this->bdays[2];
 
  }
 

	
 
  public function getTh()
 
  {
 
    return $this->bdays[3];
 
  }
 

	
 
  public function getF()
 
  {
 
    return $this->bdays[4];
 
  }
 

	
 
  public function getDay($i)
 
  {
 
    return $this->bdays[$i];
 
    return $this->meetings;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Check if this section conflicts withthe given section.
 
   *   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)
 
  {
 
    /*
 
     * The two sections can't conflict if the start/end times don't
 
     * overlap. Also, use >= or <= here so that one can say ``I have
 
     * gym from 10 through 11 and then latin from 11 though 12''.
 
     */	
 
    if ($this->getStartTime() >= $that->getEndTime()
 
	|| $this->getEndTime() <= $that->getStartTime())
 
      {
 
	return FALSE;
 
      }
 
    foreach ($this->meetings as $this_meeting)
 
      foreach ($that->meetings as $that_meeting)
 
      if ($this_meeting->conflictsWith($that_meeting))
 
	return TRUE;
 

	
 
    return FALSE;
 
  }
 

	
 
    /*
 
     * Now we know that the sections overlap in start/end times. But
 
     * if they don't both meet on the same day at least once, they
 
     * don't conflict.
 
     */
 
    for ($day = 0; $day < 5; $day ++)
 
      {
 
	if ($this->getDay($day) && $that->getDay($day))
 
	  return TRUE;
 
      }
 

	
 
    /*
 
     * The sections don't both share a day of the week.
 
     */
 
    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
 
@@ -298,32 +172,68 @@ class Section
 
     * 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 an array of information needed by the AJAX stuff.
 
   *   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_array()
 
  public function to_json_arrays()
 
  {
 
    static $daymap = array(0 => 'm', 1 => 't', 2 => 'w', 3 => 'h', 4 => 'f');
 
    $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;
 
  }
 

	
 

	
 
    $json_array = array('section' => $this->letter,
 
			'prof' => $this->prof,
 
			'time_start' => $this->start,
 
			'time_end' => $this->tend,
 
			'days' => array(),
 
			'synonym' => $this->synonym,
 
			'room' => $this->room,
 
			);
 
    for ($day = 0; $day < 5; $day ++)
 
      $json_array['days'][$daymap[$day]] = $this->getDay($day);
 
  /* for legacy unserialization */
 
  private $start;
 
  private $tend;
 
  private $bdays;
 

	
 
    return $json_array;
 
  /**
 
   * \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];
 

	
 
	$this->meetings = array();
 
	$this->meeting_add(new SectionMeeting($days, $this->start, $this->tend, '<location unknown>', 'lecture'));
 

	
 
	/*
 
	 * if we're reserialized in the future, make sure we don't do this same upgrade procedure again ;-).
 
	 */
 
	unset($this->start);
 
      }
 
  }
 
}
inc/class.section_meeting.inc
Show inline comments
 
new file 100644
 
<?php
 

	
 
/**
 
 * \brief
 
 *   Represent a time/location that a Section meets during/at.
 
 *
 
 * A Calvin student might ask ``Why is there a need for a
 
 * SectionMeeting class? Doesn't every Section have a unique
 
 * prof/time/location?'' A Cedarville student would retort ``Huh?
 
 * Don't some of your classes have labs in addition to lecture? How do
 
 * you know that you have to go to both a lecture and lab -- and how
 
 * do you handle that some classes have different lecture times for
 
 * different days of the week?''. A Calvin section _is_ a unique
 
 * prof/time/location. At Cedarville, a Section refers to a prof and a
 
 * _set_ of time/location pairs. The generalization is to make each
 
 * Section support a list of meeting times/locations.
 
 */
 
class SectionMeeting
 
{
 
  private $time_start;
 
  private $time_end;
 

	
 
  private $days;
 

	
 
  private $location;
 

	
 
  /**
 
   * \brief
 
   *   Construct a SectionMeeting.
 
   *
 
   * \param $days
 
   *   A string of single-char day upon which a section meets. Monday
 
   *   is represented with 'm', Tuesday with 't', Wednesday with 'w',
 
   *   Thursday with 'h', and Friday with 'f'.
 
   * \param $time_start
 
   *   The time of day when the section meeting starts.
 
   * \param $time_end
 
   *   The time of day when the section meeting ends.
 
   * \param $location
 
   *   Where the meeting occurs. Often a room number of some sort.
 
   * \param $type
 
   *   The type of meeting this is. For lectures, please use
 
   *   'lecture'. For labs, please use 'lab'. For others, use the
 
   *   school's notation.
 
   */
 
  public function __construct($days, $time_start, $time_end, $location = NULL, $type = 'lecture')
 
  {
 
    $this->days_set($days);
 

	
 
    $this->time_start = $time_start;
 
    $this->time_end = $time_end;
 

	
 
    $this->location = $location;
 

	
 
    $this->type = $type;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Take a days of week string and store it into our $days of week array.
 
   *
 
   * \param $days_str
 
   *   The days of the week in a string format. One char per
 
   *   day. Mon-Fri is represented with 'm', 't', 'w', 'h', 'f'.
 
   */
 
  private function days_set($days_str)
 
  {
 
    $this->days = array(0 => FALSE, 1 => FALSE, 2 => FALSE, 3 => FALSE, 4 => FALSE);
 

	
 
    $days_str_strlen = strlen($days_str);
 
    for ($i = 0; $i < $days_str_strlen; $i ++)
 
      $this->days[self::day_atoi($days_str[$i])] = TRUE;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Convert a day letter to a day numeral.
 
   *
 
   * Works fine if you give the numeral as well.
 
   */
 
  private static function day_atoi($day_c)
 
  {
 
    static $day_atoi = array('m' => 0, 't' => 1, 'w' => 2, 'h' => 3, 'f' => 4,
 
			     'M' => 0, 'T' => 1, 'W' => 2, 'H' => 3, 'F' => 4,
 
			       0 => 0,   1 => 1,   2 => 2,   3 => 3,   4 => 4);
 

	
 
    return $day_atoi[$day_c];
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Determine whether or not this class meeting time meets on a
 
   *   specified day of the week or not.
 
   *
 
   * \param $day
 
   *   The letter or numeral of the day to retrieve.
 
   * \return
 
   *   TRUE if this section meeting meets on that day. FALSE
 
   *   otherwise.
 
   */
 
  public function getDay($day)
 
  {
 
    return $this->days[self::day_atoi($day)];
 
  }
 

	
 
  /**
 
   * \return
 
   *   This SectionMeeting's location or NULL if none is defined.
 
   */
 
  public function getLocation()
 
  {
 
    return $this->location;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Get the start_time of this meeting in slate_permutate's internal format.
 
   */
 
  public function getStartTime()
 
  {
 
    return $this->time_start;
 
  }
 

	
 
  public function getEndTime()
 
  {
 
    return $this->time_end;
 
  }
 

	
 
  /**
 
   * \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(SectionMeeting $that)
 
  {
 
    /*
 
     * The two sections meetings can't conflict if the start/end times
 
     * don't overlap. Also, use >= or <= here so that one can say ``I
 
     * have gym from 10 through 11 and then latin from 11 though 12''.
 
     */	
 
    if ($this->getStartTime() >= $that->getEndTime()
 
	|| $this->getEndTime() <= $that->getStartTime())
 
      {
 
	return FALSE;
 
      }
 

	
 
    /*
 
     * Now we know that the sections meetings overlap in start/end
 
     * times. But if they don't both meet on the same day at least
 
     * once, they don't conflict.
 
     */
 
    for ($day = 0; $day < 5; $day ++)
 
      {
 
	if ($this->getDay($day) && $that->getDay($day))
 
	  return TRUE;
 
      }
 

	
 
    /*
 
     * The sections meetings don't both share a day of the week.
 
     */
 
    return FALSE;
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Return an array of JSON keys specific to this section meeting
 
   *   time.
 
   *
 
   * Currently, the AJAX UI doesn't recognize that a given section may
 
   * have multiple meeting times. Thus, we simulate this by having
 
   * multiple instances of the same section but just with different
 
   * times in the UI.
 
   */
 
  public function to_json_array()
 
  {
 
    static $daymap = array(0 => 'm', 1 => 't', 2 => 'w', 3 => 'h', 4 => 'f');
 

	
 
    $json_array = array(
 
			'time_start' => $this->time_start,
 
			'time_end' => $this->time_end,
 
			'days' => array(),
 
			'location' => $this->location,
 
			);
 

	
 
    for ($day = 0; $day < 5; $day ++)
 
      $json_array['days'][$daymap[$day]] = $this->getDay($day);
 

	
 
    return $json_array;
 
  }
 
}
inc/school.crawl.inc
Show inline comments
 
@@ -53,25 +53,25 @@ function school_crawl_time_format($time)
 
 * \param $days
 
 *   An array of day names. These may be common abbreviations or
 
 *   truncations (any truncations must be two chars long for
 
 *   simplicity. One-char representations are supported, however, but
 
 *   use 'm', 't', 'w', 'h', 'f' to distinguish Thursday and
 
 *   Tuesday. 'r' may also be used for Thursday.). Case does not
 
 *   matter.
 
 * \return
 
 *   slate_permutate's strange internal days representation.
 
 */
 
function school_crawl_days_format($days)
 
{
 
  static $daymap_1 = array('m' => 1, 't' => 2, 'w' => 3, 'h' => 4, 'r' => 4, 'f' => 5);
 
  static $daymap_1 = array('m' => 'm', 't' => 't', 'w' => 'w', 'h' => 'h', 'r' => 'h', 'f' => 'f');
 
  static $daymap_2 = array('th' => 'h');
 

	
 
  $my_days = array();
 
  foreach ($days as $day)
 
    {
 
      $day_orig = $day;
 
      $day = strtolower(substr(trim($day), 0, 2));
 

	
 
      /*
 
       * convert from two-char representation to one-char
 
       * representation.n
 
       */
input.php
Show inline comments
 
@@ -27,30 +27,34 @@ if ($sch)
 
    var class_last = 0;
 

	
 
';
 
  for ($class_key = 0; $class_key < $nclasses; $class_key ++)
 
    {
 
      $class = $sch->class_get($class_key);
 
      $my_hc .= '    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);
 
	  $my_hc .= '    add_section_n(class_last, \'' . htmlentities($section->getLetter(), ENT_QUOTES) . '\', \''
 
	    . htmlentities($section->getSynonym(), ENT_QUOTES) . '\', \''
 
	    . $section->getStartTime() . '\', \''
 
	    . $section->getEndTime() . '\', '
 
	    . json_encode(array('m' => $section->getDay(0), 't' => $section->getDay(1), 'w' => $section->getDay(2), 'h' => $section->getDay(3), 'f' => $section->getDay(4))) . ', \''
 
	    . htmlentities($section->getProf(), ENT_QUOTES) . "');\n";
 
	  $meetings = $section->getMeetings();
 
	  foreach ($meetings as $meeting)
 
	    {
 
	      $my_hc .= '    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) . "');\n";
 
	    }
 
	}
 
    }
 
  $my_hc .= '  });
 
';
 
  $inputPage->headcode_add('scheduleInput', $inputPage->script_wrap($my_hc), TRUE);
 
}
 
else
 
  $inputPage->headcode_add('schduleInput', $inputPage->script_wrap('jQuery(document).ready( function() { add_class(); } );'), TRUE);
 

	
 
$inputPage->head();
 

	
 
/*
process.php
Show inline comments
 
<?php
 

	
 
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';
 

	
 
// Converts a 5-element array into a nice string.
 
// Supports multiple modes, prettiness, and searching for different indicators
 
function arrayToDays($array, $mode = 'num', $pretty = false, $key = 1) {
 
	$outString = '';
 
	switch($mode){
 
	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;
 
	}
 
	if(count($array) > 1){
 
		for($i=0; $i<=4; $i++)	{
 
			if(isset($array[$i]) && $array[$i] == $key){
 
				$outString .= $days[$i];
 
				if($pretty)
 
					$outString .= ', ';
 
			}
 
		}
 
@@ -108,25 +112,25 @@ if(!$DEBUG)
 
		   * 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']);
 
		
 
				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']));
 
					  $allClasses->addSection($class['name'], $section['letter'], $section['start'], $section['end'], arrayToDays($section['days'], 'alpha'), NULL, $section['professor']);
 
					}
 
			}
 
		}
 
		$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)
schedulecreator.php
Show inline comments
 
@@ -5,48 +5,48 @@ include_once 'class.class.php';
 
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->addSection("CS 104", "A", 1030, 1120, 24);
 
         $allClasses->addSection("CS 104", "A", 1030, 1120, 'th');
 
      	
 
         $allClasses->addClass("Engr 209");
 
         $allClasses->addSection("Engr 209", "A", 1330, 1420, 1235);
 
         $allClasses->addSection("Engr 209", "B", 1430, 1520, 1235);
 
         $allClasses->addSection("Engr 209", "A", 1330, 1420, 'mtwf');
 
         $allClasses->addSection("Engr 209", "B", 1430, 1520, 'mtwf');
 
      	
 
         $allClasses->addClass("Engr 209L");
 
         $allClasses->addSection("Engr 209L", "A", 1830, 2120, 4);
 
         $allClasses->addSection("Engr 209L", "B", 1830, 2120, 3);
 
         $allClasses->addSection("Engr 209L", "A", 1830, 2120, 'h');
 
         $allClasses->addSection("Engr 209L", "B", 1830, 2120, 'w');
 
      	
 
         $allClasses->addClass("Math 231");
 
         $allClasses->addSection("Math 231", "A", 800, 850, 1235);
 
         $allClasses->addSection("Math 231", "A", 800, 850, 'mtwf');
 
      	
 
         $allClasses->addClass("Phys 235");
 
         $allClasses->addSection("Phys 235", "A", 900, 950, 135);
 
         $allClasses->addSection("Phys 235", "B", 1130, 1220, 135);
 
         $allClasses->addSection("Phys 235", "C", 1230, 1320, 135);
 
         $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->addSection("Phys 235L", "A", 1430, 1720, 1);
 
         $allClasses->addSection("Phys 235L", "B", 1430, 1720, 3);
 
         $allClasses->addSection("Phys 235L", "C", 830, 1120, 4);
 
         $allClasses->addSection("Phys 235L", "D", 1230, 1520, 4);
 
         $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->addSection("Rel 131", "A", 800, 850, 135);
 
         $allClasses->addSection("Rel 131", "B", 900, 950, 135);
 
         $allClasses->addSection("Rel 131", "C", 1330, 1420, 135);
 
         $allClasses->addSection("Rel 131", "D", 1430, 1520, 135);
 
         $allClasses->addSection("Rel 131", "E", 835, 950, 24);
 
         $allClasses->addSection("Rel 131", "F", 1030, 1145, 24);
 
         $allClasses->addSection("Rel 131", "G", 1205, 1320, 24);
 
         $allClasses->addSection("Rel 131", "H", 1330, 1445, 24);
 
         $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/calvin.crawl.inc
Show inline comments
 
@@ -320,25 +320,25 @@ function calvin_crawl(Semester $semester
 
	  $date_end = $meeting_info_matches[2];
 
	  /* e.g., 'Lecture', 'Practicum' */
 
	  $meeting_type = $meeting_info_matches[3];
 
	  $days = school_crawl_days_format(explode(', ', $meeting_info_matches[5]));
 
	  $time_start = school_crawl_time_format(strptime($meeting_info_matches[6], '%I:%M%p'));
 
	  $time_end = school_crawl_time_format(strptime($meeting_info_matches[7], '%I:%M%p'));
 
	  $meeting_place = $meeting_info_matches[8];
 

	
 
	  if ($verbosity > 5)
 
	    foreach (array('date_start', 'date_end', 'meeting_type', 'days', 'time_start', 'time_end', 'meeting_place') as $var)
 
	      echo $var . ':' . ${$var} . "\n";
 

	
 
	  $section = new Section($section_id['section'], $time_start, $time_end, $days, $synonym, $faculty_name, $meeting_place);
 
	  $section = new Section($section_id['section'], array(new SectionMeeting($days, $time_start, $time_end, $meeting_place)), $synonym, $faculty_name);
 
	  $semester->section_add($section_id['department'], $section_id['course'], $section);
 
	}
 

	
 
      if (!preg_match(';Page ([0-9]+) of ([0-9]+)\</td\>$;m', $html, $pages))
 
	{
 
	  error_log('Unable to determine the number of pages in this Calvin resultset');
 
	  break;
 
	}
 

	
 
      if ($verbosity > 0)
 
	{
 
	  echo 'calvin_crawl(): finished page ' . $pages[1] . ' of ' . $pages[2] . ' with ' . ($list_row - 1) . " courses.\n";
school.d/cedarville.inc
Show inline comments
 
@@ -65,24 +65,26 @@ function cedarville_crawl($semester, $ve
 
  $basepath = "http://cedarville.edu/courses/schedule/";
 

	
 
  $season = strtolower($season);
 
  $tables = array();
 
  foreach($departments as $department)
 
    {
 
      $html = file_get_contents($basepath . $year . $season . '_' . $department . '_' . 'all.htm');
 
      if (!$html)
 
	continue;
 
      $tables[$department] = table_parse(cedarville_html_fix($html));
 
    }
 

	
 
  $meeting_type_maps = array('LAB' => 'lab', 'LECT' => 'lecture');
 

	
 
  foreach ($tables as $dept_table)
 
    {
 
      /*
 
       * Discard the first row, which has the contents of the <th />
 
       * elements.
 
       */
 
      unset($dept_table[0]);
 

	
 
      foreach($dept_table as $course_table)
 
	{
 
	  /*
 
	   * format:
 
@@ -183,38 +185,38 @@ function cedarville_crawl($semester, $ve
 
		  continue;
 
		}
 

	
 
	      $meetings[$meeting_matches[1]]
 
		= array('room' => $meeting_matches[2],
 
			'days' => school_crawl_days_str_format($meeting_matches[3]),
 
			'time_start' => school_crawl_time_format(strptime($meeting_matches[4] . 'M', '%I:%M%p')),
 
			'time_end' => school_crawl_time_format(strptime($meeting_matches[5] . 'M', '%I:%M%p')),
 
			'type' => $meeting_matches[1], 
 
			);
 
	    }
 

	
 
	  $section_meetings = array();
 
	  foreach ($meetings as $meeting)
 
	    {
 
	      $section_letter = $section_parts['section'];
 
	      if ($meeting['type'] == 'LECT')
 
		/**
 
		 * \todo this might not make much sense.		 
 
		 */
 
		$section_letter = 'L' . $section_letter;
 
	      $semester->section_add($section_parts['department'], $section_parts['course'],
 
				     new Section($section_letter,
 
						 $meeting['time_start'], $meeting['time_end'],
 
						 $meeting['days'], $synonym, $instructor,
 
						 $meeting['room']));
 
	      $meeting_type = $meeting['type'];
 
	      if (isset($meeting_type_maps[$meeting_type]))
 
		$meeting_type = $meeting_type_maps[$meeting_type];
 

	
 
	      $section_meetings[] = new SectionMeeting($meeting['days'], $meeting['time_start'],
 
						       $meeting['time_end'], $meeting['room'],
 
						       $meeting_type);
 
	    }
 
	  $semester->section_add($section_parts['department'], $section_parts['course'],
 
				 new Section($section_parts['section'], $section_meetings,
 
					     $synonym, $instructor));
 
	}
 
    }
 

	
 
  return 0;
 
}
 

	
 
/**
 
 * \brief
 
 *   Fix some incorrect usage of the HTML entity delimiter, the ampersand.
 
 */
 
function cedarville_html_fix($html)
 
{
0 comments (0 inline, 0 general)