Changeset - 2afaa65abd5e
[Not reviewed]
default
0 3 0
Nathan Brink (binki) - 15 years ago 2011-03-21 23:30:34
ohnobinki@ohnopublishing.net
Provide a mechanism for validating users' inputs in PHP and letting users mend their collectively sinful ways.
3 files changed with 126 insertions and 5 deletions:
0 comments (0 inline, 0 general)
inc/class.schedule.php
Show inline comments
 
@@ -108,15 +108,28 @@ class Schedule
 
    $this->courses[] = new Course($n);
 
  }
 

	
 
  //--------------------------------------------------
 
  // Adds a section to the desired class.
 
  //--------------------------------------------------
 
  /**
 
   * \brief
 
   *   Adds a section to this semester after finding the class.
 
   *
 
   * \return
 
   *   NULL on success, a string on error which is a message for the
 
   *   user and a valid XHTML fragment.
 
   */
 
  function addSection($course_name, $letter, $time_start, $time_end, $days, $synonym = NULL, $faculty = NULL, $location = NULL, $type = 'lecture')
 
  {
 
    if (empty($letter) && (empty($time_start) || !strcmp($time_start, 'none')) && (empty($time_end) || !strcmp($time_end, 'none')) && empty($days)
 
	&& empty($synonym) && empty($faculty) && empty($location) && (empty($type) || !strcmp($type, 'lecture')))
 
      return;
 

	
 
    /* reject invalid times */
 
    if (!strcmp($time_start, 'none') || !strcmp($time_end, 'none')
 
	|| $time_start > $time_end)
 
      {
 
	return 'Invalid time specifications for ' . htmlentities($course_name) . '-' . htmlentities($letter)
 
	  . '. Start time: <tt>' . htmlentities($time_start) . '</tt>. End time: <tt>' . htmlentities($time_end) . '</tt>.';
 
      }
 

	
 
    foreach ($this->courses as $course)
 
      if (!strcmp($course_name, $course->getName()))
 
	{
input.php
Show inline comments
 
@@ -29,6 +29,7 @@ require_once('inc' . DIRECTORY_SEPARATOR
 

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

	
 
$parent_schedule_id = NULL;
 
@@ -38,6 +39,16 @@ if (isset($_REQUEST['s']))
 
    $parent_schedule_id = (int)$_REQUEST['s'];
 
    $sch = schedule_store_retrieve($schedule_store, $parent_schedule_id);
 
  }
 
elseif (!empty($_REQUEST['e']))
 
  {
 
    /*
 
     * Read an errorful schedule out of $_POST, this $_POST is created
 
     * by process.php when the originally sinful user produces bad
 
     * data.
 
     */
 
    $errors_fix = TRUE;
 
    $parent_schedule_id = (int)$_POST['postData']['parent_schedule_id'];
 
  }
 

	
 
$my_hc = 'var slate_permutate_example_course_id = \'' . str_replace('\'', '\\\'', school_example_course_id($inputPage->get_school())) . '\';
 

	
 
@@ -55,6 +66,29 @@ if ($sch)
 
      $my_hc .= input_class_js($sch->class_get($class_key), '    ');
 
    }
 
}
 
elseif ($errors_fix)
 
  {
 
    foreach ($_POST['postData'] as $course)
 
      if (is_array($course))
 
	{
 
	  if (empty($course['name']))
 
	    $my_hc .= '    class_last = add_class();' . PHP_EOL;
 
	  else
 
	    $my_hc .= '    class_last = add_class_n(\'' . htmlentities($course['name'], ENT_QUOTES) . '\');' . PHP_EOL;
 
	  foreach ($course as $section)
 
	    if (is_array($section))
 
	      $my_hc .= '    add_section_n(class_last, \'' . htmlentities($section['letter'], ENT_QUOTES) . '\', \''
 
		. htmlentities($section['synonym'], ENT_QUOTES) . '\', \'' . htmlentities($section['start'], ENT_QUOTES) . '\', \''
 
		. htmlentities($section['end'], ENT_QUOTES) . '\', '
 
		. json_encode(array('m' => !empty($section['days'][0]), 't' => !empty($section['days'][1]), 'w' => !empty($section['days'][2]),
 
				    'h' => !empty($section['days'][3]), 'f' => !empty($section['days'][4]),
 
				    's' => !empty($section['days'][5])))
 
		. ', \'' . htmlentities($section['professor'], ENT_QUOTES) . '\', \''
 
		. htmlentities($section['location'], ENT_QUOTES) . '\', \''
 
		. htmlentities($section['type'], ENT_QUOTES) . '\');' . PHP_EOL;
 
	  $my_hc .= PHP_EOL;
 
	}
 
  }
 
else
 
  {
 
    $default_courses = school_default_courses($school);
 
@@ -135,7 +169,20 @@ if (!empty($_REQUEST['selectsemester']))
 

	
 
<form method="post" action="process.php" id="scheduleForm">
 
<p class="nospace" style="border-left: 5px solid #999; padding-left: 5px!important; padding-top: 5px!important;"><label>Schedule Name</label><br />
 
  <input id="scheduleName" style="margin-bottom: 1em;" class="defText required" type="text" size="25" title="<?php echo $inputPage->semester['name'] ?>" name="postData[name]" <?php if ($sch) echo 'value="' . htmlentities($sch->getName(), ENT_QUOTES) . '"'; ?> />
 
<input
 
    id="scheduleName"
 
    style="margin-bottom: 1em;"
 
    class="defText required"
 
    type="text"
 
    size="25"
 
    title="<?php echo $inputPage->semester['name'] ?>"
 
    name="postData[name]"
 
    <?php
 
      if ($sch)
 
        echo 'value="' . htmlentities($sch->getName(), ENT_QUOTES) . '"';
 
      elseif ($errors_fix)
 
        echo 'value="' . htmlentities($_POST['postData']['name'], ENT_QUOTES) . '"';
 
    ?> />
 
  <?php if (!empty($parent_schedule_id)): ?>
 
  <input type="hidden" name="postData[parent_schedule_id]" value="<?php echo htmlentities($parent_schedule_id); ?>" />
 
  <?php endif; ?>
process.php
Show inline comments
 
@@ -72,6 +72,29 @@ function prettyTime($time){
 
	return substr($time,0,strlen($time)-2) . ":" . substr($time,strlen($time)-2, strlen($time));
 
}
 

	
 
/**
 
 * \brief
 
 *   Convert a multidimensional array to a set of <input />s.
 
 *
 
 * Currently just echos out the <input />s as they are created.
 
 *
 
 * \param $array
 
 *   The array to make into a set of <input />s.
 
 * \param $base
 
 *   The string to prefix. Normally the name of the array variable.
 
 * \param $blankness
 
 *   A string to insert at the beginning of each line before an <input
 
 *   /> for indentation's sake.
 
 */
 
function array_to_form($array, $base = '',  $blankness = '        ')
 
{
 
  foreach ($array as $key => $val)
 
    if (is_array($val))
 
      array_to_form($val, $base . '[' . $key . ']', $blankness);
 
    else
 
      echo $blankness . '<input name="' . htmlentities($base . '[' . $key . ']') . '" value="' . htmlentities($val) . '" type="hidden" />' . PHP_EOL;
 
}
 

	
 
/*
 
 * The below code relies on sessions being started already.
 
 */
 
@@ -138,6 +161,7 @@ if(!$DEBUG)
 

	
 
	$allClasses = new Schedule($name, $parent_schedule_id);
 

	
 
	$errors = array();
 
		foreach($_POST['postData'] as $class)
 
		{
 
		  /*
 
@@ -154,10 +178,47 @@ if(!$DEBUG)
 
				  /* 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']);
 
					    $error_string = $allClasses->addSection($class['name'], $section['letter'], $section['start'], $section['end'], arrayToDays($section['days'], 'alpha'), $section['synonym'], $section['professor'], $section['location'], $section['type']);
 
					    if ($error_string !== NULL)
 
					      $errors[] = $error_string;
 
					  }
 
			}
 
		}
 

	
 
		/*
 
		 * Tell the user that his input is erroneous and
 
		 * require him to fix it.
 
		 */
 
		if (count($errors))
 
		  {
 
		    $error_page = new Page('Process Schedule — Errors');
 

	
 
		    echo '        <p>' . PHP_EOL
 
		      . '          You have the following errors in your input:' . PHP_EOL
 
		      . '        </p>' . PHP_EOL
 
		      . '        <ul>' . PHP_EOL;
 
		    foreach ($errors as $error)
 
		      echo '          <li>' . $error . '</li>' . PHP_EOL;
 
		    echo '        </ul>' . PHP_EOL
 
		      . '        <h3>Solving Errors</h3>' . PHP_EOL
 
		      . '        <ul>' . PHP_EOL
 
		      . '          <li>Most importantly, click the <em>Fix</em> button below to return to the schedule editing page to resolve these errors. Hitting your browser\'s <em>Back</em> button will cause your input to be lost.</li>' . PHP_EOL
 
		      . '          <li>Ensure that no section\'s start or end times are left blank. Any blank start or end times are shown as <tt>none</tt> in the above error output.</li>' . PHP_EOL
 
		      . '          <li>Ensure that a section\'s end time is later in the day than its start time.</li>' . PHP_EOL
 
		      . '          <li>If you are having trouble resolving these issues, please feel free to <a href="feedback.php">leave us feedback</a>. Be sure to describe your problem with as much detail as possible; otherwise we may only be able to make conjectures about the errors instead of finding and fixing any bugs. Thanks! <em>(To provide us with the most reliable data, save this webpage onto disk and paste the entire (X)HTML source into the feedback form.)</em></li>' . PHP_EOL
 
		      . '        </ul>' . PHP_EOL;
 

	
 
		    /* Regurgitate the postData into a <form /> */
 
		    echo '        <form action="input.php" method="post">' . PHP_EOL
 
		      . '          <input name="e" value="1" type="hidden" />' . PHP_EOL;
 
		    array_to_form($_POST['postData'], 'postData', '          ');
 
		    echo '          <button type="submit" class="gray">Fix Errors!</button>' . PHP_EOL
 
		      . '        </form>' . PHP_EOL;
 

	
 
		    $error_page->foot();
 
		    exit;
 
		  }
 

	
 
		$allClasses->findPossibilities();
 
		if (!isset($_SESSION['saved']))
 
		  $_SESSION['saved'] = array();
0 comments (0 inline, 0 general)