Changeset - d7044a583ccc
[Not reviewed]
default
0 2 0
Nathan Brink (binki) - 14 years ago 2012-02-11 19:57:37
ohnobinki@ohnopublishing.net
Add the name of the chosen university/school to <title/> for SEO.
2 files changed with 9 insertions and 6 deletions:
0 comments (0 inline, 0 general)
inc/class.page.php
Show inline comments
 
@@ -24,97 +24,97 @@
 
define('SP_PACKAGE_NAME', 'slate_permutate');
 
define('SP_PACKAGE_VERSION', '0.1_pre');
 
define('SP_PACKAGE_STRING', SP_PACKAGE_NAME . '-' . SP_PACKAGE_VERSION);
 

	
 
/*
 
 * Set up include() path for user-supplied libs (in case if his system
 
 * doesn't have libs, such as phpcaptcha
 
 * (securimage/securimage.php)). Users would store such libs in /libs.
 
 *
 
 * Coding note: dirname(dirname('a/b/c')) returns 'a'. This is a
 
 * similar effect to dirname('a/b/c') . DIRECTORY_SEPARATOR . '..'.
 
 */
 
set_include_path(get_include_path() . PATH_SEPARATOR . dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'libs');
 

	
 
/**
 
 * Not sure if there's a better place for this... it'd be a pita to
 
 * make a new include file like doconfig.inc but maybe that'll make
 
 * sense soon.
 
 */
 
/* defaults */
 
$clean_urls = FALSE;
 
$ga_trackers = array();
 
$ga_conversions = array();
 
$feedback_emails = array('ez@ethanzonca.com, ngelderloos7@gmail.com, ohnobinki@ohnopublishing.net');
 
$use_captcha = FALSE;
 
$admin_enable_purge = FALSE;
 
$qtips_always = FALSE;
 
$input_warning_banner = FALSE;
 
$feedback_disk_log = FALSE;
 

	
 
$config_inc = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.inc';
 
if (file_exists($config_inc)) {
 
  require_once($config_inc);
 
}
 

	
 

	
 
/**
 
 * \brief
 
 *   Produces XHTML output for the user and helps with other browser
 
 *   interaction.
 
 *
 
 * Supports styled XHTML pages, modular script inclusion, and other
 
 * various features.
 
 */
 
class page
 
{
 

	
 
  /* Site-wide configuration options */
 
  private $base_title = 'SlatePermutate - Find the schedule that works for you!';
 
  private $base_title = array('SlatePermutate', 'Find the schedule that works for you!');
 
  private $doctype = 'html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"';
 
  private $htmlargs = 'xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"';
 

	
 
  private $pageGenTime = 0;
 

	
 
  private $xhtml = FALSE;
 

	
 
  /* Scripts and styles */
 
  private $headCode = array();
 

	
 
  private $trackingcode = ''; // Tracking code
 
  private $ga_conversions_code = ''; // Conversion tracking code
 
  private $pagetitle = ''; // Title of page
 
  private $scripts = array(); // Scripts to include on page
 
  private $meta;
 

	
 
  /* the current school. See get_school(). */
 
  private $school;
 

	
 
  private $semester;
 

	
 
  /*
 
   * Whether or not the user should be presented with the option to
 
   * change the school profile or semester.
 
   */
 
  private $school_semester_constant;
 

	
 
  /**
 
   * \brief
 
   *   Construct a new page.
 
   *
 
   * Only to be called by page::page_construct(). Use that function
 
   * instead of the new keyword.
 
   *
 
   * \see page::page_construct()
 
   *
 
   * \param $ntitle
 
   *   Must be a valid HTML string (i.e., escaped with htmlentities()).
 
   * \param $nscripts
 
   *   An array of strings identifying the scripts to include for this page.
 
   * \param $options
 
   *   An array containing any of the following keys:
 
   *     - 'school': The school to use instead of the autodetected one.
 
   *     - 'semester': The semester to use instead of the autodetected one.
 
   */
 
  protected function __construct($ntitle, $nscripts = array(), $immediate = TRUE, array $options = array())
 
  {
 
    /* Begin tracking generation time */
 
@@ -138,96 +138,99 @@ class page
 
    $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" />'; 
 
    $this->headCode['uiTabsKeyboard'] = '<script type="text/javascript" src="scripts/uiTabsKeyboard.js"></script>';
 
    $this->headCode['displayTables'] = '<script type="text/javascript" src="scripts/displayTables.js"></script>';
 

	
 
    $this->pagetitle = $ntitle;
 
    $this->scripts = $nscripts;
 
    $this->meta = array(
 
      'msapplication-starturl' => self::uri_resolve(''),
 
      'msapplication-task' => 'name=Create Schedule; action-uri=' . self::uri_resolve('input.php') . '; icon-uri=' . self::uri_resolve('images/favicon_96.png'),
 
      'msapplication-tooltip' => 'Find the semester schedule which works for you!',
 
    );
 

	
 
   /* Compliant browsers which care, such as gecko, explicitly request xhtml: */
 
   if(empty($_SERVER['HTTP_ACCEPT'])  /* then the browser doesn't care :-) */
 
      || strpos($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') !== FALSE)
 
       $this->xhtml = TRUE;
 

	
 
   if (count($ga_trackers))
 
     {
 
       $ga_www = 'http://www.';
 
       if ($_SERVER['SERVER_PORT'] != 80)
 
	 $ga_www = 'https://ssl.';
 

	
 
       $this->trackingcode = '<script type="text/javascript" src="' . $ga_www . 'google-analytics.com/ga.js" />' . "\n"
 
	 . $this->trackingcode
 
	 . '  <script type="text/javascript">' . "\n"
 
	 . '  ' . ($this->xhtml ? '<![CDATA[' : '') . "\n"
 
	 . "     var mytrackers = new Array();";
 

	
 
       $i = 0;
 
       foreach ($ga_trackers as $ga_tracker)
 
	 {
 
	   $this->trackingcode .= "\n"
 
	     . '      mytrackers[' . $i . '] = _gat._getTracker(\'' . $ga_tracker . "');\n"
 
	     . '      mytrackers[' . $i . "]._trackPageview();\n";
 
	 }
 

	
 
       $this->trackingcode .= '  ' . ($this->xhtml ? ']]>'       : '') . "\n"
 
	 . "  </script>\n";
 
     }
 

	
 
    self::session_start();
 
    /* everything that needs sessions started to work: */
 

	
 
    if (empty($options['school']))
 
      $options['school'] = school_load_guess();
 
    $this->school = $options['school'];
 
    if ($this->school['id'] != 'default')
 
      /* If we have a non-generic school, put it into base_title */
 
      array_unshift($this->base_title, $this->school['name']);
 

	
 
    if (empty($options['semester']))
 
      $options['semester'] = school_semester_guess($this->school);
 
    $this->semester = $options['semester'];
 

	
 
    if (!isset($options['school_semester_constant']))
 
      $options['school_semester_constant'] = TRUE;
 
    $this->school_semester_constant = (bool)$options['school_semester_constant'];
 

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

	
 
  /**
 
   * \brief
 
   *   Instantiate a new page for the caller.
 
   *
 
   * The caller must explicitly call the page::head() function upon
 
   * the value that is returned. No implicit actions are supported
 
   * anymore.
 
   *
 
   * \param $title
 
   *   The title of the page. Must be completely UTF-8 (will be
 
   *   escaped for you with htmlentitites()).
 
   * \param $scripts
 
   *   A list of scripts which the page desires to be included in the
 
   *   <head /> of the page. Should this param just be moved to the
 
   *   page::head() function?
 
   * \param $options
 
   *   An array containing any of the following keys:
 
   *     - 'school': The school to use instead of the autodetected one.
 
   *     - 'semester': The semester to use instead of the autodetected one.
 
   *     - 'school_semester_constant': Whether the options to change
 
   *        the current school and semester should be hidden. TRUE by
 
   *        default.
 
   */
 
  public static function page_create($title, array $scripts = array(), array $options = array())
 
  {
 
    return new page(htmlentities($title, ENT_QUOTES, 'UTF-8'), $scripts, FALSE, $options);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Adds some headcode to this page.
 
   *
 
   * \param $key
 
   *   The key to register this headcode under.
 
@@ -325,97 +328,97 @@ class page
 
   *   The base URI for the current page.
 
   * \param $query
 
   *   The querystring to canonicalize on.
 
   */
 
  public function canonize($uri, array $query = array())
 
  {
 
    $query_string = '';
 
    $uri_full = $uri;
 
    if (!empty($query))
 
      {
 
	ksort($query);
 
	$query_members = array();
 
	foreach ($query as $key => $value)
 
	  $query_members[] = rawurlencode($key) . '=' . rawurlencode($value);
 
	$query_string = implode('&', $query_members);
 
	$uri_full .= '?' . $query_string;
 
      }
 

	
 
    /* Detect if we are at the canonical location or not... */
 
    list($base_request_uri) = explode('?', $_SERVER['REQUEST_URI'], 2);
 
    $base_request_uri = substr($_SERVER['REQUEST_URI'], strrpos($base_request_uri, '/') + 1);
 
    if ($base_request_uri != $uri_full)
 
      /* We are not canonical, redirect. */
 
      $this->redirect($uri_full);
 

	
 
    /* Mention that this is a canonical URI with <link rel="canonical"/> */
 
    $this->headcode_add('link_rel_canonical', '<link rel="canonical" href="'
 
			. htmlentities(self::uri_resolve($uri_full), ENT_QUOTES) . '"'
 
			. ($this->xhtml ? '/>' : '></link>'),
 
			TRUE);
 
  }
 

	
 
  /**
 
   * \brief
 
   *   Output the HTML header for a page, including <!DOCTYPE>, <head />, and opening structure
 
   */
 
  public function head()
 
  {
 
    if ($this->xhtml) {
 
       header('Content-Type: application/xhtml+xml; charset=utf-8');
 
      echo '<?xml version="1.0" encoding="utf-8"?>' . PHP_EOL;
 
    }
 
    else
 
      header('Content-Type: text/html; charset=utf-8');
 

	
 
    echo '<!DOCTYPE ' . $this->doctype . '>'. PHP_EOL .
 
	  '<html ' . $this->htmlargs . '>'. PHP_EOL .
 
	  '  <head>'. PHP_EOL .
 
	  '    <title>' . $this->pagetitle . ' - ' . $this->base_title . '</title>'. PHP_EOL .
 
	  '    <title>' . $this->pagetitle . ' - ' . $this->base_title[0] . ' - ' . $this->base_title[1] . '</title>'. PHP_EOL .
 
          '    <link rel="stylesheet" href="styles/general.css" type="text/css" media="screen" charset="utf-8" />'.  PHP_EOL .
 
	  '    <link rel="stylesheet" type="text/css" media="print" href="styles/print.css" />'. PHP_EOL .
 
          '    <!--[if IE]>'. PHP_EOL .
 
          '      <link rel="stylesheet" type="text/css" media="screen" charset="utf-8" href="styles/ie.css" />'. PHP_EOL .
 
          '    <![endif]-->'. PHP_EOL .
 
          '    <link rel="shortcut icon" href="images/favicon.png" />'. PHP_EOL
 
      . '    <style type="text/css">' . PHP_EOL
 
      . $this->cdata_wrap(school_page_css($this->school))
 
      . '    </style>' . PHP_EOL;
 

	
 
    foreach ($this->meta as $key => $value)
 
      echo '    <meta name="' . htmlentities($key, ENT_QUOTES)
 
      . '" content="' . htmlentities($value, ENT_QUOTES)
 
      . '" ' . ($this->xhtml ? '/' : '') .  '>' . PHP_EOL;
 

	
 
    // Write out all passed scripts
 
    foreach ($this->scripts as $i)
 
      echo '    ' . $this->headCode["$i"] . "\n";
 

	
 
    /*
 
     * Perhaps we should have a separate array for javascript library
 
     * initialization snippets.
 
     */
 
    $javascript_init = '';
 
    if (in_array('jQuery.cuteTime', $this->scripts))
 
      $javascript_init .= 'jQuery.extend(jQuery.fn.cuteTime.settings, {refresh: 10000, use_html_attribute: false});' . PHP_EOL
 
	. 'jQuery.fn.cuteTime.settings.time_ranges[0].cuteness = \'in the future\';' . PHP_EOL;
 

	
 
    echo $this->script_wrap(''
 
			    . 'var slate_permutate_school = ' . json_encode($this->school['id']) . ';' . PHP_EOL
 
			    . 'var slate_permutate_semester = ' . json_encode($this->semester['id']) . ';' . PHP_EOL
 
			    . $javascript_init) . PHP_EOL;
 

	
 
    $selectschool_query = '&amp;school=' . $this->school['id'];
 
    /* kludge */
 
    if (!empty($_REQUEST['s']))
 
      $selectschool_query .= '&amp;s=' . (int)$_REQUEST['s'];
 

	
 
    echo '  </head>' . PHP_EOL .
 
	 '  <body>'. PHP_EOL .
 
         '    <div id="page">'. PHP_EOL .
 
         '      <div id="header">'. PHP_EOL .
 
	 '        <div id="title">'. PHP_EOL .
 
         '          <h1><a href="index.php"><img src="images/slatepermutate-alpha.png" alt="SlatePermutate" class="noborder" /></a><br /></h1>'. PHP_EOL .
 
         '          <p>'. PHP_EOL .
 
         '            <span id="subtitle">'.$this->pagetitle.'</span>'. PHP_EOL .
 
  	 '            <span id="menu">' . PHP_EOL
 
      . '              Profile: <em>' . $this->school['name'] . '</em>' . ($this->school_semester_constant ? '' : ' <a href="input.php?selectschool=1' . $selectschool_query . '">(change)</a>') . PHP_EOL;
input.php
Show inline comments
 
@@ -66,173 +66,173 @@ if (isset($_REQUEST['s']))
 
      }
 
    else
 
      $parent_schedule_id = NULL;
 

	
 
    /*
 
     * Code outside of this block should _not_ assume $school and/or
 
     * $semester are defined. But it'd be more expensive to unset()
 
     * them here than to just overwrite them later...
 
     */
 
  }
 
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;
 

	
 
    if (!empty($_POST['postData']))
 
      $postData = $_POST['postData'];
 

	
 
    if (!empty($postData['parent_schedule_id']))
 
      $parent_schedule_id = (int)$postData['parent_schedule_id'];
 

	
 
    if (!empty($postData['school']))
 
      {
 
	$school = school_load($postData['school']);
 
	if (!empty($school))
 
	  $inputPage_options['school'] = $school;
 
      }
 

	
 
    if (!empty($school) && !empty($postData['semester']))
 
      {
 
	$semesters = school_semesters($school);
 
	if (!empty($semesters[$postData['semester']]))
 
	  $inputPage_options['semester'] = $semester;
 
      }
 

	
 
    $creating_new_schedule = FALSE;
 
  }
 

	
 
/*
 
 * We cannot initialize the page object nor guess the school before
 
 * figuring loading a saved schedule because we'll default to that
 
 * saved_schedule's school/semester.
 
 */
 
$scripts = array('jQuery', 'jQueryUI', 'qTip2', 'schedInput');
 
$inputPage = page::page_create('Scheduler', $scripts, $inputPage_options);
 
$inputPage = page::page_create('Enter Courses', $scripts, $inputPage_options);
 
$school = $inputPage->get_school();
 
$semester = $inputPage->semester_get();
 

	
 
$my_hc = 'var slate_permutate_example_course_id = ' . json_encode(school_example_course_id($school)) . ';
 

	
 
jQuery(document).ready(
 
  function()
 
  {
 
    var class_last = 0;
 

	
 
';
 
if ($sch)
 
{
 
  foreach ($sch->courses_get() as $course)
 
    {
 
      $my_hc .= input_course_js($course, '    ');
 
    }
 
}
 
elseif ($errors_fix)
 
  {
 
    foreach ($_POST['postData'] as $course)
 
      if (is_array($course))
 
	{
 
	  $title = '';
 
	  if (!empty($course['title']))
 
	    $title = $course['title'];
 
	  if (empty($course['name']))
 
	    $my_hc .= '    class_last = add_class();' . PHP_EOL;
 
	  else
 
	    $my_hc .= '    class_last = add_class_n(' . json_encode($course['name']) . ', ' . json_encode($title) . ');' . PHP_EOL;
 
	  foreach ($course as $section)
 
	    if (is_array($section))
 
	      $my_hc .= '    add_section_n(class_last, ' . json_encode($section['letter']) . ', '
 
		. json_encode($section['synonym']) . ', ' . json_encode($section['start']) . ', '
 
		. json_encode($section['end']) . ', '
 
		. 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])))
 
		. ', ' . json_encode($section['professor']) . ', '
 
		. json_encode($section['location']) . ', '
 
		. json_encode($section['type']) . ', '
 
		. json_encode($section['slot']) . ', '
 
		. json_encode(isset($section['credit_hours']) ? $section['credit_hours'] : -1) . ');' . PHP_EOL;
 
	  $my_hc .= PHP_EOL;
 
	}
 
  }
 
else
 
  {
 
    $default_courses = school_default_courses($school);
 
    foreach ($default_courses as $default_class)
 
      $my_hc .= input_course_js($default_class, '    ');
 
  }
 
$my_hc .= '    class_last = add_class();' . PHP_EOL;
 
if ($qtips_always || !isset($_SESSION['saw_qtips']))
 
  {
 
    $my_hc .= '    addTips();' . PHP_EOL;
 
    $_SESSION['saw_qtips'] = TRUE;
 
  }
 
$my_hc .= '  });
 
';
 

	
 
$inputPage->headcode_add('scheduleInput', $inputPage->script_wrap($my_hc), TRUE);
 

	
 
if ($school['id'] != 'default'
 
    && empty($_REQUEST['selectschool'])
 
    && empty($_REQUEST['selectsemester']))
 
  {
 
    /*
 
     * If we have chosen a school, set the canonical URL so that it
 
     * contains the school and semester.
 
     * contains the school and, optionall, the specified
 
     * schedule. This way, when Google caches the input.php page, the
 
     * <title/> it sees will reflect the selected school.
 
     */
 
    $query = array('school' => $school['id']);
 
    if ($sch)
 
      $query['s'] = $sch->id_get();
 
    if (!empty($semester))
 
      $query['semester'] = $semester['id'];
 
    $inputPage->canonize('input.php', $query);
 
  }
 

	
 
$inputPage->head();
 

	
 
/*
 
 * Force a student to choose a school or declare he's a generic
 
 * student before displaying the input form. To do this, we need
 
 * another variable in $_SESSION: $_SESSION['school_chosen'].
 
 */
 
if (!empty($_REQUEST['school']) && !empty($_SESSION['school']) && !strcmp($_REQUEST['school'], $_SESSION['school']))
 
  $_SESSION['school_chosen'] = TRUE;
 
if (!empty($_REQUEST['selectschool'])
 
    || empty($school) || $school['id'] == 'default' && empty($_SESSION['school_chosen']))
 
  {
 
    $next_page = 'input.php?';
 
    if (isset($_GET['s']))
 
      $next_page .= 's=' . (int)$_GET['s'] . '&';
 
    if (isset($_GET['semester']))
 
      $next_page .= 'semester=' . htmlentities($$_GET['semester']) . '&';
 
?>
 
<h2>School Selection</h2>
 
<p>
 
  Choose the school you attend from the list below. <strong>If you cannot
 
  find your school</strong>, you may proceed using
 
  the <a href="<?php echo htmlentities($next_page); ?>school=default">generic
 
  settings</a>.
 
</p>
 
<?php
 
    $inputPage->showSchools($next_page);
 
    $inputPage->foot();
 
    exit;
 
  }
 

	
 
if (!empty($_REQUEST['selectsemester']))
 
  {
 
?>
 
<h2>Semester Selection</h2>
 
<p>
 
  Choose the semester for which you wish you make a schedule from the
 
  list below. If any semester is missing, please <a
 
  href="feedback.php?feedback=My+school+is+missing+the+&lt;semester+name&gt;+semester.">let us know</a>.
 
</p>
 
<?php
 
  $next_page = 'input.php?';
 
  if (isset($_GET['s']))
 
    $next_page .= 's=' . (int)$_GET['s'] . '&';
 
  if (!empty($_GET['school']))
0 comments (0 inline, 0 general)