Changeset - cebfe2251d8c
[Not reviewed]
default
0 8 0
Nathan Brink (binki) - 15 years ago 2010-09-25 00:55:45
ohnobinki@ohnopublishing.net
Support editing saved schedules.
8 files changed with 269 insertions and 29 deletions:
0 comments (0 inline, 0 general)
class.class.php
Show inline comments
 
@@ -56,13 +56,34 @@ class Classes
 

	
 
        $result = $this->sections[$i];
 
        return $result;
 
    }
 
    
 
	//--------------------------------------------------
 
	// Returns the name of the class.
 
	//--------------------------------------------------
 
    function getName()
 
    {
 
        return $this->name;
 
    }
 

	
 
    /**
 
     * \brief
 
     *   Renders this Classes into something suitable for input.php.
 
     */
 
    function input_form_render($class_key)
 
    {
 
      $n = "\n";
 
      $out = '<tr title="' . $class_key . '" class="class class' . $class_key . '">' . $n
 
	. '  <td><input type="text" class="required defText" title="Class Name" name="postData[' . $class_key . '][name]" value="' . str_replace('"', '&quot;', $this->getName()) . '"/></td>' . $n
 
	. '  <td colspan="8"></td>' . $n
 
	. '  <td class="tdInput"><div class="addSection"><input type="button" value="Add section" /></div></td>' . $n
 
	. '  <td class="tdInput"><div class="deleteClass"><input type="button" value="Remove" /></div></td>' . $n
 
	. "</tr>\n";
 

	
 
      foreach ($this->sections as $key => $section)
 
	$out .= $section->input_form_render($class_key, $key);
 

	
 
      return $out;
 
    }
 

	
 
}
class.schedule.php
Show inline comments
 
@@ -12,33 +12,42 @@ include_once 'errors.php';
 
include_once 'class.class.php';
 
include_once 'class.section.php';
 
include_once 'inc/class.page.php';
 

	
 
class Schedule
 
{
 
    private $classStorage;			// Classes array of classes
 
    private $nclasses;				// Integer number of classes
 
    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 = "SlatePermutate - Scheduler";
 
    private $title;
 
    /**
 
     * 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;
 

	
 
	//--------------------------------------------------
 
	// Creates a schedule with the given name.
 
	//--------------------------------------------------
 
	function __construct($n)
 
	{
 
        $this->nclasses = 0;
 
        $this->scheduleName = $n; 
 
    /**
 
     * \brief
 
     *   Create a schedule with the given name.
 
     */
 
    function __construct($name)
 
    {
 
      $this->nclasses = 0;
 
      $this->scheduleName = $name;
 
      $this->title = "SlatePermutate - Scheduler";
 
      $this->section_format = 'numerous';
 
    }
 

	
 
	//--------------------------------------------------
 
	// Mutators and Accessors
 
	//--------------------------------------------------
 
	public function getName()
 
	{
 
		return $this->scheduleName;
 
	}    
 

	
 
	//--------------------------------------------------
 
	// Adds a new class to the schedule.
 
@@ -519,37 +528,87 @@ class Schedule
 
					// End of row
 
					$table .= "\n\t</tr>";
 
				}
 

	
 
				// End of table
 
				$table .= "</table></div>";
 
			}
 

	
 
			echo $table . $footcloser;   
 
		} else {
 
			echo '<html><body><p>There are no possible schedules. Please try again.</p></body></html>';
 
		}
 

	
 
		/* edit button */
 
		if (!isset($savedkey))
 
		  {
 
		    if (isset($_REQUEST['savedkey']))
 
		      $savedkey = (int)$_REQUEST['savedkey'];
 
		    else
 
		      /*
 
		       * if this is a new saved schedule, it'll be the
 
		       * next item added to $_SESSION['saved']
 
		       */
 
		      $savedkey = max(array_keys($_SESSION['saved'])) + 1;
 
		  }
 
		echo '<form method="get" action="input.php"><input type="hidden" name="savedkey" value="' . $savedkey . '" /><input type="submit" value="edit" /></form>';
 

	
 
		$outputPage->foot();
 
	}
 

	
 
	/**
 
	 * \brief
 
	 *   Render the input table form for editing a saved schedule in input.php.
 
	 *
 
	 * This function's output must be synchronized with the
 
	 * associated javascript in scripts/scheduleInput.js.
 
	 */
 
	function input_form_render()
 
	{
 
	  $out = '';
 
	  static $n = "\n";
 

	
 
	  foreach ($this->classStorage as $class_key => $class)
 
	    $out .= $class->input_form_render($class_key);
 

	
 
	  return $out;
 
	}
 

	
 
	//--------------------------------------------------
 
	// 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 $this->nclasses;
 
  }
 

	
 
  /*
 
   * \brief
 
   *   fetch a specified class by its key
 
   */
 
  function class_get($class_key)
 
  {
 
    return $this->classStorage[$class_key];
 
  }
 
}
class.section.php
Show inline comments
 
@@ -137,13 +137,104 @@ function getW()
 
}
 

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

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

	
 
  /**
 
   * \brief
 
   *   Create output suitable for editing on input.php.
 
   *
 
   * \see Classes::input_form_render()
 
   *
 
   * \param $class_key
 
   *   The same $class_key passed to Classes::input_form_render().
 
   * \param $section_key
 
   *   The index of this section.
 
   * \param $section_format
 
   *   The type of input method used for this section. Valid values
 
   *   are 'numerous', 'numbered', and 'lettered'
 
   */
 
  function input_form_render($class_key, $section_key, $section_format = 'numerous')
 
  {
 
    static $n = "\n";
 
    $out = '<tr class="section class' . $class_key . '">' . $n
 
      . '  <td class="none"></td>' . $n;
 
    switch ($section_format)
 
      {
 
      case 'numerous':
 
      default:
 
	/* see customIds() in scheduleInput.js */
 
	$out .= '  <td class="sectionIdentifier center">' . $n
 
	. '    <input type="text" size="1" class="required" title="Section Name"' . $n
 
	. '           name="postData[' . $class_key . '][' . $section_key . '][letter]"' . $n
 
	. '           value="' . $this->letter . '" />' . $n
 
	. "  </td>\n";
 
	break;
 
      }
 

	
 
    $out .= "  <td>\n"
 
      . '    <select class="selectRequired" name="postData[' . $class_key . '][' . $section_key . '][start]">' . $n;
 
    for ($h = 7; $h <= 21; $h ++)
 
      {
 
	$val = $h . '00';
 
	$nm = 'p';
 
	$hr = $h;
 
	if ($h < 12)
 
	  $nm = 'a';
 
	elseif ($h > 12)
 
	  $hr -= 12;
 

	
 
	foreach (array('00', '30') as $m)
 
	  {
 
	    $label = $hr . ':' . $m . $nm . 'm';
 
	    $out .= '      <option value="' . $val . '">' . $label . '</option>' . $n;
 
	  }
 
      }
 
    $out .= "    </select>\n"
 
      . "  </td>\n";
 

	
 
    /* ugh, code duplication :-(  --binki commenting on his own code*/
 
    $out .= "  <td>\n"
 
      . '    <select class="selectRequired" name="postData[' . $class_key . '][' . $section_key . '][end]">' . $n;
 
    for ($h = 7; $h <= 21; $h ++)
 
      {
 
	$val = $h . '00';
 
	$nm = 'p';
 
	$hr = $h;
 
	if ($h < 12)
 
	  $nm = 'a';
 
	elseif ($h > 12)
 
	  $hr -= 12;
 

	
 
	foreach (array('20', '50') as $m)
 
	  {
 
	    $label = $hr . ':' . $m . $nm . 'm';
 
	    $out .= '      <option value="' . $val . '">' . $label . '</option>' . $n;
 
	  }
 
      }
 
    $out .= "    </select>\n"
 
      . "  </td>\n";
 

	
 
    foreach ($this->bdays as $day_key => $day_enabled)
 
      {
 
	if ($day_enabled)
 
	  $day_enabled = 'checked="checked"';
 
	else
 
	  $day_enabled = '';
 
	$out .= "  <td>\n"
 
	  . '    <input type="checkbox" class="daysRequired"'
 
	  . '           name="postData[' . $class_key . '][' . $section_key . '][days][' . $day_key . ']" ' . $day_enabled . ' />' . $n
 
	  . "  </td>\n";
 
      }
 

	
 
    $out .= "</tr>\n";
 

	
 
    return $out;
 
  }
 
}
inc/class.page.php
Show inline comments
 
@@ -21,51 +21,71 @@ class page {
 

	
 
			  <script type="text/javascript">
 
				var nathangPageTracker = _gat._getTracker("UA-17441156-1");
 
				nathangPageTracker._trackPageview();
 
				
 
				var ethanzPageTracker = _gat._getTracker("UA-2800455-1");
 
				ethanzPageTracker._trackPageview();
 
			</script>'; // Google analytics ga.js tracking code
 

	
 
  private $pagetitle = ''; // Title of page
 
  private $scripts = array(); // Scripts to include on page
 

	
 
  public function __construct($ntitle, $nscripts = array() ){
 
  public function __construct($ntitle, $nscripts = array(), $immediate = TRUE)
 
  {
 
    // Scripts and styles available to include
 
    $this->headCode['jQuery'] = '<script src="http://www.google.com/jsapi"></script><script type="text/javascript" charset="utf-8"> google.load("jquery", "1.3.2"); google.load("jqueryui", "1.7.2");</script>';
 
    $this->headCode['jValidate'] = '<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery.validate/1.7/jquery.validate.pack.js"></script>';
 
    $this->headCode['schedInput'] = '<script type="text/javascript" src="scripts/scheduleInput.js"></script>';
 
    $this->headCode['outputPrintStyle'] = '<link rel="stylesheet" href="styles/print.css" type="text/css" media="screen" charset="utf-8">';
 
    $this->headCode['outputStyle'] = '<link rel="stylesheet" href="styles/output.css" type="text/css" media="screen" charset="utf-8">'; 
 
    $this->headCode['gliderHeadcode'] = '<link rel="stylesheet" href="styles/glider.css" type="text/css" media="screen" charset="utf-8"><script src="scripts/prototype.js" type="text/javascript" charset="utf-8"></script><script src="scripts/effects.js" type="text/javascript" charset="utf-8"></script><script src="scripts/glider.js" type="text/javascript" charset="utf-8"></script>'; 
 

	
 
   $this->pagetitle = $ntitle;
 
    $this->scripts = $nscripts;
 
    if($ntitle != "NOHEAD")
 
    if($immediate
 
       && $ntitle != "NOHEAD")
 
      $this->head();
 

	
 
    session_start();
 
 }
 

	
 
  /**
 
   * \brief
 
   *   Adds some headcode to this page.
 
   *
 
   * \param $key
 
   *   The key to register this headcode under.
 
   * \param $code
 
   *   The actuall code, such as a <script/>.
 
   * \param $enable
 
   *   Whether or not to enable this code while adding it.
 
   */
 
  function headcode_add($key, $code, $enable = FALSE)
 
  {
 
    $this->headCode[$key] = $code;
 
    if ($enable)
 
      $this->scripts[] = $key;
 
  }
 

	
 
  private function top(){
 
    echo '<div id="header">
 
          <h1><em>SlatePermutate</em> - '.$this->pagetitle.'</h1>
 
          </div>
 
          <div id="content">';
 
  }
 

	
 
// Public functions/vars
 

	
 
  private function head(){
 
    session_start();
 
  function head(){
 
    $this->pageGenTime = round(microtime(), 3);
 

	
 
    echo '<!DOCTYPE ' . $this->doctype . '>
 
	  <html ' . $this->htmlargs . '>
 
	  <head>
 
	    <title>' . $this->pagetitle . ' :: ' . $this->base_title . '</title>
 
           <link rel="stylesheet" href="styles/general.css" type="text/css" media="screen" charset="utf-8">';
 

	
 
    // Write out all passed scripts
 
    foreach ($this->scripts as $i){
 
    	echo $this->headCode["$i"];
 
    }
 
@@ -91,20 +111,23 @@ class page {
 
      $ret .= "$minutes:";
 
      $seconds = bcmod(intval($seconds),60);
 
      $ret .= "$seconds";
 
      return $ret;
 
  }
 

	
 
  public function showSavedScheds($session) {
 
       echo '<p>';
 
	if(isset($session['saved']) && count($session['saved']) > 0){
 
		echo '<div id="savedBox" ><h3>Saved Schedules:</h3>';
 
		foreach($session['saved'] as $key => $schedule){
 
			$sch = unserialize($schedule);
 
			echo "<a href=\"process.php?savedkey=$key\">#" . ($key + 1) . " - " . $sch->getName() . "</a> <em><a href=\"process.php?delsaved=$key\"><img src=\"images/close.png\" style=\"border:0;\" /></a></em><br />";
 
			echo "<a href=\"process.php?savedkey=$key\">#" . ($key + 1) . " - " . $sch->getName()
 
			  . '</a> <form style="display: inline" method="get" action="input.php"><input type="hidden" name="savedkey" value="' . $key . '" /><input type="submit" value="edit"/></form>'
 
			  . "<em><a href=\"process.php?delsaved=$key\"><img src=\"images/close.png\" style=\"border:0;\" alt=\"[del]\"/></a></em>"
 
			  . "<br />\n";
 
		}
 
		echo '</div>';
 
	}
 
       echo '</p>';
 
}
 

	
 
}
input.php
Show inline comments
 
<?php 
 

	
 
include_once 'errors.php';
 
include_once 'class.schedule.php';
 
include_once 'class.class.php';
 
include_once 'class.section.php';
 
include_once 'inc/class.page.php';
 

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

	
 
$sch = FALSE;
 
if (isset($_REQUEST['savedkey']) && isset($_SESSION['saved']))
 
  {
 
    $savedkey = (int)$_REQUEST['savedkey'];
 
    if (isset($_SESSION['saved'][$savedkey]))
 
      {
 
	$sch = unserialize($_SESSION['saved'][$savedkey]);
 
      }
 
  }
 

	
 
if ($sch)
 
{
 
  $nclasses = $sch->nclasses_get();
 
  $my_hc = '<script type="text/javascript">
 
var classNum = ' . $nclasses . ';
 
/* holds number of sections for each class */
 
var sectionsOfClass = new Array();
 
';
 
  for ($class_key = 0; $class_key < $nclasses; $class_key ++)
 
    $my_hc .= 'sectionsOfClass[' . $class_key . '] = ' . $sch->class_get($class_key)->getnsections() . ";\n";
 
  $my_hc .= '// </script>';
 
  $inputPage->headcode_add('scheduleInput', $my_hc, TRUE);
 
}
 
else
 
  $inputPage->headcode_add('schduleInput', '<script type="text/javascript">
 
var classNum = 0;
 
/* holds number of sections for each class */
 
var sectionsOfClass = Array();
 
// </script>', TRUE);
 

	
 
$inputPage->head();
 
$inputPage->showSavedScheds($_SESSION);
 

	
 
?>
 

	
 
<form method="post" action="process.php" id="scheduleForm">
 
<table>
 
  <tr>
 
    <table id="jsrows">
 
	<tr>
 
		<td colspan="11" style="padding-bottom:2em;"><input id="scheduleName" class="defText" type="text" class="required" title="Schedule Name" name="postData[name]" />
 
			<em>(For example: Fall <?php echo Date("Y"); ?>)</em>
 
		</td>
 
	</tr>
 
	<tr>
 
		<td colspan="11" style="padding-bottom: 2em;"><select id="isNumeric" type="text" class="required" name="isnumbered" ><option value="numerous">Custom Section Labels</option><option value="numbered">Numbered Section Labels</option><option value="lettered">Lettered Section Labels</option></select>
 
      <tr>
 
	<td colspan="11" style="padding-bottom:2em;">
 
	  <input id="scheduleName" class="defText" type="text" class="required" title="Schedule Name" name="postData[name]"
 
		 <?php if ($sch) echo 'value="' . str_replace('"', '&quot;', $sch->getName()) . '"'; /*"*/ ?>
 
		 />
 
	  <em>(For example: Fall <?php echo Date("Y"); ?>)</em>
 
	</td>
 
      </tr>
 
      <tr>
 
	<td colspan="11" style="padding-bottom: 2em;">
 
	  <select id="isNumeric" type="text" class="required" name="isnumbered" value="<?php if ($sch) echo $sch->section_format; else echo 'numerous'; ?>" >
 
	    <option value="numerous">Custom Section Labels</option>
 
	    <option value="numbered">Numbered Section Labels</option>
 
	    <option value="lettered">Lettered Section Labels</option>
 
	  </select>
 

	
 
	<!-- Header -->
 
	<tr>
 
		<td>Class</td>
 
		<td class="center" id="letterNumber">Section</td>
 
		<td class="center">Start Time</td>
 
		<td class="center">End Time</td>
 
		<td class="center">M</td>
 
		<td class="center">Tu</td>
 
		<td class="center">W</td>
 
		<td class="center">Th</td>
 
		<td class="center">F</td>
 
		<td class="center"></td>
 
		<td class="center"></td>
 
	</tr>
 
	<?php if ($sch) echo $sch->input_form_render(); ?>
 
    </table>
 
  </tr>
 
  <tr><td> <span class="gray" style="padding: 0 3.5em 0 3.5em;" id="addclass">Add Class - This row should be just as wide as the one above someday</span></td></tr>
 
</table>
 

	
 
<!-- <div class="paddingtop" id="classage"><input type="button" value="Add class" /></div> -->
 
<div class="paddingtop"><input style="float:left;" type="submit" value="Find me a schedule!" /></div>
 

	
 
</form>
 

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

	
process.php
Show inline comments
 
@@ -69,42 +69,48 @@ if(!$DEBUG){
 
	}
 
	else if(isset($_GET['delsaved'])){
 
		$_SESSION['saved'][$_GET['delsaved']] = '';
 
		$_SESSION['saved'] = array_filter($_SESSION['saved']); // Remove null entries
 
              header( 'Location: input.php' ) ;
 

	
 
	}
 
	else{
 
		$allClasses = new Schedule($_POST['postData']['name']);
 
	
 
		foreach(sortInputs($_POST) as $class)
 
		{
 
			if(is_array($class)) // Skip the schedule name
 
		  /*
 
		   * 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']);
 
		
 
				foreach($class as $section)
 
					if(is_array($section)) // Skip the section name, which isn't a 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->findPossibilities();
 
		$allClasses->writeoutTables();
 
		if(!isset($_SESSION['saved']))
 
			$_SESSION['saved'] = array();
 
		array_push ( $_SESSION['saved'], serialize($allClasses));
 
	}
 

	
 
} else {
 

	
 

	
 
	echo '<pre>DEBUG OUTPUT: <br /><br />';
 
	foreach(sortInputs($_POST) as $class) {
 
		echo 'Class: ' . $class['name'] . '<br />';
 
		foreach($class as $section)
 
			if(is_array($section))
 
			{
 
				echo '---- Section that starts at ' . prettyTime($section['start']) . ' and ends at ' . prettyTime($section['end']) . '. This class meets on ';
 
				echo arrayToDays($section['days'],'long',true) . '.<br />';
 
			}
schedulecreator.php
Show inline comments
 
@@ -5,25 +5,25 @@ include_once 'class.schedule.php';
 
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->changeTitle("Demonstration :: SlatePermutate - Scheduler");
 
	  $allClasses->title = "Demonstration :: SlatePermutate - Scheduler";
 
      	
 
         $allClasses->addClass("CS 104");
 
         $allClasses->addSection("CS 104", "A", 1030, 1120, 24);
 
      	
 
         $allClasses->addClass("Engr 209");
 
         $allClasses->addSection("Engr 209", "A", 1330, 1420, 1235);
 
         $allClasses->addSection("Engr 209", "B", 1430, 1520, 1235);
 
      	
 
         $allClasses->addClass("Engr 209L");
 
         $allClasses->addSection("Engr 209L", "A", 1830, 2120, 4);
 
         $allClasses->addSection("Engr 209L", "B", 1830, 2120, 3);
 
      	
scripts/scheduleInput.js
Show inline comments
 
@@ -45,43 +45,43 @@
 
		daysRequired: true
 
	});
 

	
 
    jQuery(document).ready(function() {
 
	//--------------------------------------------------
 
	// Validates the form (pre-submission check)
 
	//--------------------------------------------------
 
		jQuery('#scheduleForm').validate({
 
			debug: false,
 
		}); 
 

	
 

	
 
	var classNum = 0;
 
	var sectionsOfClass = new Array(); // holds number of sections for each class
 
	/* classNum is declared in the <head/> to enable loading of saved classes */
 
	/* sectionsOfClass is declared in the <head/> to enable loading of saved sections */
 

	
 
        function numberedIds(name){
 
		return '<td class="sectionIdentifier">\
 
                                <select name="'+name+'"><option value="-">-</option><option value="1">1</option><option value="2">2</option>\
 
                                <option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option>\
 
                                <option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option></select></td>\
 
                                </select></td>';
 
        }
 
	function letteredIds(name){
 
		return '<td class="sectionIdentifier">\
 
                                <select name="'+name+'"><option value="-">-</option><option value="A">A</option><option value="B">B</option>\
 
                                <option value="C">C</option><option value="D">D</option><option value="E">E</option><option value="F">F</option><option value="G">G</option>\
 
                                <option value="H">H</option><option value="I">I</option><option value="J">J</option><option value="K">K</option></select></td>\
 
                                </select></td>';
 
	}
 
	function customIds(name){
 
		return '<td class="sectionIdentifier center"><input type="text" size="1" class="required" title="Schedule Name" name="' + name + '" /></td>';
 
		return '<td class="sectionIdentifier center"><input type="text" size="1" class="required" title="Section Name" name="' + name + '" /></td>';
 
	}
 

	
 
	//--------------------------------------------------
 
	// Returns the common inputs for each new section.
 
	//--------------------------------------------------
 
	function getCommonInputs(cnum) {
 
		var snum = sectionsOfClass[cnum];
 

	
 
		var result = '';
 
		if(jQuery('#isNumeric').val() == "lettered"){
 
			result = result + letteredIds('postData[' + cnum + '][' + snum + '][letter]');
 
		}
0 comments (0 inline, 0 general)