<?php
/**
* SASHA :: inc/lib/lib.base.php
*
* This contains the functions common to all child classes of SASHA.
*
* @package SASHA
* @copyright (C) 2006-2010 Gordon P. Hemsley
* @license docs/LICENSE BSD License
* @version $Id: lib.base.php 82 2010-01-20 03:06:18Z gphemsley $
*/
/**
* Base
*
* Base class for SASHA
*
* @todo Consolidate Base::_create_*_type_selector() functions
*
* @package Base
*/
class Base
{
/**
* Base->semester
*
* @var int $semester Current semester (format: YYYYMM)
*/
var $semester;
/**
* Base->institution
*
* @var string $institution Current institution
*/
var $institution;
const M_bit = 64;
const T_bit = 32;
const W_bit = 16;
const R_bit = 8;
const F_bit = 4;
const S_bit = 2;
const U_bit = 1;
const M_num = 0;
const T_num = 1;
const W_num = 2;
const R_num = 3;
const F_num = 4;
const S_num = 5;
const U_num = 6;
/**
* Base::__construct()
*
* Sets up SASHA class for use.
*
* @access public
* @param int $user User id
* @param bool|string $semester Semester to use (format: YYYYMM; default: FALSE)
* @param bool|string $institution Institution to use (default: FALSE)
* @return void Initializes SASHA class
*/
public function __construct( $semester = FALSE, $institution = FALSE )
{
global $Database, $User;
global $config;
$this->instructor_types = array(
IT_OTHER => 'Other',
IT_LECTURER => 'Lecturer',
IT_INSTRUCTOR => 'Instructor',
IT_ASSISTANT_PROFESSOR => 'Assistant Professor',
IT_ASSOCIATE_PROFESSOR => 'Associate Professor',
IT_PROFESSOR => 'Professor',
IT_SENIOR_LECTURER => 'Senior Lecturer',
IT_CLINICAL_LECTURER => 'Clinical Lecturer',
IT_CLINICAL_INSTRUCTOR => 'Clinical Instructor',
IT_CLINICAL_ASSISTANT_PROFESSOR => 'Clinical Assistant Professor',
IT_CLINICAL_ASSOCIATE_PROFESSOR => 'Clinical Associate Professor',
IT_CLINICAL_PROFESSOR => 'Clinical Professor',
IT_RESEARCH_LECTURER => 'Research Lecturer',
IT_RESEARCH_INSTRUCTOR => 'Research Instructor',
IT_RESEARCH_ASSISTANT_PROFESSOR => 'Research Assistant Professor',
IT_RESEARCH_ASSOCIATE_PROFESSOR => 'Research Associate Professor',
IT_RESEARCH_PROFESSOR => 'Research Professor',
IT_ADJUNCT_LECTURER => 'Adjunct Lecturer',
IT_ADJUNCT_INSTRUCTOR => 'Adjunct Instructor',
IT_ADJUNCT_ASSISTANT_PROFESSOR => 'Adjunct Assistant Professor',
IT_ADJUNCT_ASSOCIATE_PROFESSOR => 'Adjunct Associate Professor',
IT_ADJUNCT_PROFESSOR => 'Adjunct Professor',
IT_VISITING_LECTURER => 'Visiting Lecturer',
IT_VISITING_INSTRUCTOR => 'Visiting Instructor',
IT_VISITING_ASSISTANT_PROFESSOR => 'Visiting Assistant Professor',
IT_VISITING_ASSOCIATE_PROFESSOR => 'Visiting Associate Professor',
IT_VISITING_PROFESSOR => 'Visiting Professor',
IT_VISITING_SENIOR_LECTURER => 'Visiting Senior Lecturer',
IT_EXTENSION_LECTURER => 'Extension Lecturer',
IT_EXTENSION_INSTRUCTOR => 'Extension Instructor',
IT_EXTENSION_ASSISTANT_PROFESSOR => 'Extension Assistant Professor',
IT_EXTENSION_ASSOCIATE_PROFESSOR => 'Extension Associate Professor',
IT_EXTENSION_PROFESSOR => 'Extension Professor',
IT_LIBRARY_LECTURER => 'Library Lecturer',
IT_LIBRARY_INSTRUCTOR => 'Library Instructor',
IT_LIBRARY_ASSISTANT_PROFESSOR => 'Library Assistant Professor',
IT_LIBRARY_ASSOCIATE_PROFESSOR => 'Library Associate Professor',
IT_LIBRARY_PROFESSOR => 'Library Professor'
);
$this->schedule_types = array(
ST_LECTURE => 'Lecture',
ST_LABORATORY => 'Laboratory',
ST_DISCUSSION => 'Discussion',
ST_SEMINAR => 'Seminar',
ST_TESTING => 'Testing',
ST_LECTDISC => 'Lecture/Discussion'
);
$this->assignment_statuses = array(
AT_TODO => 'To Do',
AT_STARTED => 'Started',
AT_MIDWAY => 'Mid-way Through',
AT_ALMOST => 'Almost Done',
AT_DONE => 'Done'
);
$this->test_types = array(
TT_QUIZ => 'Quiz',
TT_EXAM => 'Exam',
TT_MIDTERM => 'Midterm',
TT_FINAL => 'Final'
);
$this->days = array(
'M' => array( self::M_num, self::M_bit ),
'T' => array( self::T_num, self::T_bit ),
'W' => array( self::W_num, self::W_bit ),
'R' => array( self::R_num, self::R_bit ),
'F' => array( self::F_num, self::F_bit ),
'S' => array( self::S_num, self::S_bit ),
'U' => array( self::U_num, self::U_bit )
);
$this->default_institution = ( exists( $User->user_info['default_institution'] ) ) ? $User->user_info['default_institution'] : $config['default_institution'];
$this->institution = ( $institution && $this->validate_institution( $institution ) ) ? $institution : $this->get_current_institution();
$this->default_semester = $this->get_default_semester();
$this->semester = ( $semester && $this->validate_semester( $semester ) ) ? $semester : $this->get_current_semester();
// Ensure that forms can be properly generated.
require_once( ROOT . 'inc/lib/lib.forms.php' );
}
/**
* Base::convert_newlines()
*
* Convert newline characters to XHTML line breaks.
*
* @access public
* @param string $text Text with newline characters
* @return string Text with XHTML line breaks
*/
public function convert_newlines( $text )
{
$text = str_replace( array( "\r\n", "\n\r", "\r" ), "\n", $text );
$text = str_replace( "\n", "<br />", $text );
return $text;
}
/**
* Base::convert_hour()
*
* Convert between 12-hour and 24-hour format.
*
* @access public
* @param bool $to_24 Convert to/from 24-hour time (to: TRUE; from: FALSE)
* @param int $hour Hour to be converted
* @param array $time_parts Array containing time information (default: array())
* @return array Array containing time information
*/
final public function convert_hour( $to_24, $hour, $time_parts = array() )
{
if( $to_24 )
{
if( isset( $time_parts['meridiem'] ) && ( $time_parts['meridiem'] == 'PM' ) )
{
if( $hour == 12 )
{
$time_parts['hour'] = '12';
}
else
{
$time_parts['hour'] = (string) ( $hour + 12 );
}
$time_parts['meridiem'] = FALSE;
}
elseif( isset( $time_parts['meridiem'] ) && ( $time_parts['meridiem'] == 'AM' ) )
{
if( $hour == 12 )
{
$time_parts['hour'] = '00';
}
else
{
$time_parts['hour'] = str_pad( $hour, 2, '0', STR_PAD_LEFT );
}
$time_parts['meridiem'] = FALSE;
}
else
{
// Assume $hour is 24-hour format
$time_parts['hour'] = str_pad( $hour, 2, '0', STR_PAD_LEFT );
$time_parts['meridiem'] = FALSE;
}
}
else
{
if( isset( $time_parts['meridiem'] ) && ( $time_parts['meridiem'] != FALSE ) )
{
// $hour is already in 12-hour format
$time_parts['hour'] = str_pad( $hour, 2, '0', STR_PAD_LEFT );
}
else
{
if( ( $hour == 0 ) || ( $hour == 24 ) )
{
$time_parts['hour'] = '12';
$time_parts['meridiem'] = 'AM';
}
elseif( $hour == 12 )
{
$time_parts['hour'] = '12';
$time_parts['meridiem'] = 'PM';
}
elseif( $hour > 12 )
{
$time_parts['hour'] = (string) ( $hour - 12 );
$time_parts['meridiem'] = 'PM';
}
else
{
$time_parts['hour'] = (string) $hour;
$time_parts['meridiem'] = 'AM';
}
}
}
return $time_parts;
}
/**
* Base::get_current_semester()
*
* Get currently-specified semester.
*
* @access public
* @return string|bool Semester
*/
final public function get_current_semester()
{
$semester = FALSE;
if( exists( $_REQUEST['semester'] ) )
{
if( is_array( $_REQUEST['semester'] ) )
{
$semester = (string) ( $_REQUEST['semester']['year'] . $_REQUEST['semester']['season'] );
}
else
{
$semester = (string) $_REQUEST['semester'];
}
}
$semester = ( $this->validate_semester( $semester ) ) ? $semester : FALSE;
return $semester;
}
/**
* Base::get_default_semester()
*
* Get default semester.
*
* @todo Get custom data from database for semester breakdown (e.g. Winterim).
*
* @access public
* @return string|bool Semester
*/
final public function get_default_semester()
{
$year = date( 'Y' );
switch( date( 'm' ) )
{
case '01':
case '02':
case '03':
case '04':
case '05':
$month = '01';
break;
case '06':
case '07':
case '08':
$month = '06';
break;
case '09':
case '10':
case '11':
case '12':
$month = '09';
break;
}
return $year . $month;
}
/**
* Base::get_current_institution()
*
* Get currently-specified institution.
*
* @access public
* @return string|bool Institution
*/
final public function get_current_institution()
{
if( exists( $_REQUEST['institution'] ) && $this->validate_institution( $_REQUEST['institution'] ) )
{
$institution = (string) $_REQUEST['institution'];
}
else
{
$institution = FALSE;
}
return $institution;
}
/**
* Base::get_course_title()
*
* Get title of given course.
*
* @access public
* @param string $institution Course institution
* @param string $subject Course subject
* @param int $course Course number
* @return string Course title
*/
final public function get_course_title( $institution, $subject, $course )
{
global $Database;
$institution = ( $institution && $this->validate_institution( $institution ) ) ? (string) $institution : $this->institution;
$sql = "SELECT c.course_title
FROM courses c
WHERE institution = '$institution'
AND subject = '$subject'
AND course = '$course'";
$result = $Database->query( $sql );
$course = $Database->fetch_assoc( $result );
$Database->free_result( $result );
if( $course )
{
return $course['course_title'];
}
else
{
return FALSE;
}
}
/**
* Base::validate_institution()
*
* Used to ensure that the given institution is valid.
*
* @access public
* @param string $institution Institution to validate
* @return bool Validity of institution
*/
final public function validate_institution( $institution )
{
return preg_match( '/^[a-z]([a-z0-9.-]*[a-z0-9]+)?$/', $institution );
}
/**
* Base::validate_semester()
*
* Used to ensure that the given semester is valid.
*
* @access public
* @param string $semester Semester to validate
* @return bool Validity of semester
*/
final public function validate_semester( $semester )
{
return preg_match( '/^[0-9]{6}$/', $semester );
}
/**
* Base::validate_instructor_key()
*
* Used to ensure that the given instructor key is valid.
*
* @access public
* @param string $instructor_key Instructor key to validate
* @return bool Validity of instructor key
*/
final public function validate_instructor_key( $instructor_key )
{
return preg_match( '/^[a-z0-9]{40}$/', $instructor_key );
}
/**
* Base::validate_color()
*
* Used to ensure that color is valid.
*
* @todo Implement validation of CSS color keywords
*
* @access public
* @param string $color Color to validate
* @param bool $allow_keywords Allow named colors to validate (default: FALSE)
* @return bool Validity of color
*/
final public function validate_color( $color, $allow_keywords = FALSE )
{
if( $allow_keywords )
{
// Allow color keywords
}
else
{
return preg_match( '/^#?([A-F0-9]{3}){1,2}$/i', $color );
}
}
/**
* Base::format_date()
*
* Format date. Mostly just a surrogate for PHP's date().
*
* @access public
* @param int $date UNIX timestamp
* @param string $format Date format to use (default: 'F j, Y')
* @return string Formatted date
*/
final public function format_date( $date, $format = 'F j, Y' )
{
return date( $format, $date );
}
/**
* Base::prepare_instructors()
*
* Create comma-separated list of instructor keys.
*
* @access public
* @param array $instructors Raw list of instructors
* @return string Prepared list of instructors
*/
final public function prepare_instructors( $instructors )
{
global $Database;
foreach( $instructors as $id => $instructor )
{
if( !empty( $instructor ) && ( (int) $instructor ) )
{
$sql = "SELECT instructor_key
FROM instructors
WHERE instructor_id = '$instructor'";
$result = $Database->query( $sql );
$instructor = $Database->fetch_assoc( $result );
$Database->free_result( $result );
$instructors[$id] = @$instructor['instructor_key'];
}
}
return rtrim( implode( ',', $instructors ), ',' );
}
/**
* Base::format_time()
*
* Format time according to given input and output settings.
*
* @access public
* @param mixed $time Time to format
* @param bool $twelve_hour Use AM/PM format
* @param bool|string $input Input type (possible values: array, timestamp, 24-hour)
* @param string $output Output type (possible values: hour, 24-hour, text, html; default: html)
* @return string Formatted time
*/
final public function format_time( $time, $twelve_hour = TRUE, $input = FALSE, $output = 'html' )
{
$time_parts = array();
if( !$input )
{
if( is_array( $time ) && ( count( $time ) == 3 ) )
{
$input = 'array';
}
elseif( (int) $time )
{
if( @strlen( $time ) == 4 )
{
$input = '24-hour';
}
else
{
$input = 'timestamp';
}
}
}
switch( $input )
{
case 'array':
$time_parts['hour'] = str_pad( $time['hour'], 2, '0', STR_PAD_LEFT );
$time_parts['minute'] = str_pad( $time['minute'], 2, '0', STR_PAD_LEFT );
$time_parts['meridiem'] = $time['meridiem'];
break;
case 'timestamp':
$time_parts['hour'] = ( ( $twelve_hour ) ? date( 'h', $time ) : date( 'H', $time ) );
$time_parts['minute'] = date( 'i', $time );
$time_parts['meridiem'] = ( ( $twelve_hour ) ? date( 'A', $time ) : FALSE );
break;
case '24-hour':
default:
$time_split = str_split( str_pad( $time, 4, '0', STR_PAD_LEFT ), 2 );
$time_parts['hour'] = $time_split[0];
$time_parts['minute'] = $time_split[1];
$time_parts['meridiem'] = FALSE;
if( $twelve_hour )
{
$time_parts = $this->convert_hour( FALSE, (int) $time_split[0], $time_parts );
}
break;
}
switch( $output )
{
case 'hour':
return $this->convert_hour( TRUE, $time_parts['hour'], $time_parts );
break;
case '24-hour':
if( $time_parts['meridiem'] )
{
if( $time_parts['meridiem'] == 'PM' )
{
$time_parts['meridiem'] = FALSE;
if( $time_parts['hour'] < 12 )
{
$time_parts['hour'] += 12;
}
}
elseif( $time_parts['hour'] == 12 )
{
$time_parts['hour'] = '00';
}
}
return $time_parts['hour'] . $time_parts['minute'];
break;
case 'text':
if( $time_parts['meridiem'] )
{
return $time_parts['hour'] . ':' . $time_parts['minute'] . ' ' . $time_parts['meridiem'];
}
else
{
return $time_parts['hour'] . ':' . $time_parts['minute'];
}
break;
case 'html':
default:
if( $time_parts['meridiem'] )
{
return $time_parts['hour'] . ':' . $time_parts['minute'] . ' ' . $time_parts['meridiem'];
}
else
{
return $time_parts['hour'] . ':' . $time_parts['minute'];
}
break;
}
}
/**
* Base::format_days()
*
* Format schedule days according to given input and output settings.
*
* @access public
* @param mixed $days Days to format
* @param bool|string $input Input type (possible values: binary, array; default: array)
* @param string $output Output type (possible values: array, binary, decimal, text, html; default: html)
* @return string Formatted days
*/
final public function format_days( $days, $input = 'array', $output = 'html' )
{
$days_array = array();
if( ( $input === TRUE ) || is_array( $days ) )
{
$input = 'array';
}
elseif( ( in_array( $input, array( 'array', NULL ) ) ) && !is_array( $days ) )
{
// MySQL 5.0 returns bit as binary, while MySQL 5.1 returns decimal
if( $days == chr( ord( $days ) ) )
{
$input = 'binary';
}
else
{
$input = 'decimal';
}
}
switch( $input )
{
case 'decimal':
case 'binary':
$days_dec = ( $input == 'binary' ) ? hexdec( bin2hex( $days ) ) : $days;
$days_array['M'] = (bool) ( ( $days_dec & self::M_bit ) == self::M_bit );
$days_array['T'] = (bool) ( ( $days_dec & self::T_bit ) == self::T_bit );
$days_array['W'] = (bool) ( ( $days_dec & self::W_bit ) == self::W_bit );
$days_array['R'] = (bool) ( ( $days_dec & self::R_bit ) == self::R_bit );
$days_array['F'] = (bool) ( ( $days_dec & self::F_bit ) == self::F_bit );
$days_array['S'] = (bool) ( ( $days_dec & self::S_bit ) == self::S_bit );
$days_array['U'] = (bool) ( ( $days_dec & self::U_bit ) == self::U_bit );
break;
case 'array':
default:
$days_array['M'] = ( isset( $days['M'] ) ) ? (bool) $days['M'] : is_int( array_search( 'M', $days ) );
$days_array['T'] = ( isset( $days['T'] ) ) ? (bool) $days['T'] : is_int( array_search( 'T', $days ) );
$days_array['W'] = ( isset( $days['W'] ) ) ? (bool) $days['W'] : is_int( array_search( 'W', $days ) );
$days_array['R'] = ( isset( $days['R'] ) ) ? (bool) $days['R'] : is_int( array_search( 'R', $days ) );
$days_array['F'] = ( isset( $days['F'] ) ) ? (bool) $days['F'] : is_int( array_search( 'F', $days ) );
$days_array['S'] = ( isset( $days['S'] ) ) ? (bool) $days['S'] : is_int( array_search( 'S', $days ) );
$days_array['U'] = ( isset( $days['U'] ) ) ? (bool) $days['U'] : is_int( array_search( 'U', $days ) );
break;
}
switch( $output )
{
case 'array':
return $days_array;
break;
case 'binary':
case 'decimal':
$formatted_days = 0;
$formatted_days = ( (bool) $days_array['M'] ) ? $formatted_days | self::M_bit : $formatted_days;
$formatted_days = ( (bool) $days_array['T'] ) ? $formatted_days | self::T_bit : $formatted_days;
$formatted_days = ( (bool) $days_array['W'] ) ? $formatted_days | self::W_bit : $formatted_days;
$formatted_days = ( (bool) $days_array['R'] ) ? $formatted_days | self::R_bit : $formatted_days;
$formatted_days = ( (bool) $days_array['F'] ) ? $formatted_days | self::F_bit : $formatted_days;
$formatted_days = ( (bool) $days_array['S'] ) ? $formatted_days | self::S_bit : $formatted_days;
$formatted_days = ( (bool) $days_array['U'] ) ? $formatted_days | self::U_bit : $formatted_days;
$formatted_days = ( $output == 'binary' ) ? decbin( $formatted_days ) : $formatted_days;
break;
case 'text':
case 'html':
default:
$dash = ( $output == 'html' ) ? '–' : "\x2013";
$formatted_days = '';
$formatted_days .= ( (bool) $days_array['M'] ) ? 'M' : $dash;
$formatted_days .= ( (bool) $days_array['T'] ) ? 'T' : $dash;
$formatted_days .= ( (bool) $days_array['W'] ) ? 'W' : $dash;
$formatted_days .= ( (bool) $days_array['R'] ) ? 'R' : $dash;
$formatted_days .= ( (bool) $days_array['F'] ) ? 'F' : $dash;
$formatted_days .= ( (bool) $days_array['S'] ) ? 'S' : $dash;
$formatted_days .= ( (bool) $days_array['U'] ) ? 'U' : $dash;
break;
}
return $formatted_days;
}
/**
* Base::format_instructor_type()
*
* Format instructor type using given id.
*
* @access public
* @param int $instructor_type Instructor type id
* @param bool|string $instructor_type_description Instructor type description (default: FALSE)
* @return string Formatted instructor type
*/
final public function format_instructor_type( $instructor_type, $instructor_type_description = FALSE )
{
if( ( $instructor_type == IT_OTHER ) && $instructor_type_description )
{
return $instructor_type_description;
}
else
{
return ( ( $instructor_type >= 100 ) ? $this->instructor_types[$instructor_type - 100] . ' Emeritus' : $this->instructor_types[$instructor_type] );
}
}
/**
* Base::format_schedule_type()
*
* Format schedule type using given id.
*
* @access public
* @param int $schedule_type Schedule type id
* @return string Formatted schedule type
*/
final public function format_schedule_type( $schedule_type )
{
return $this->schedule_types[$schedule_type];
}
/**
* Base::format_assignment_status()
*
* Format assignment status using given id.
*
* @access public
* @param int $assignment_status Assignment status id
* @return string Formatted assignment status
*/
final public function format_assignment_status( $assignment_status )
{
return $this->assignment_statuses[$assignment_status];
}
/**
* Base::format_test_type()
*
* Format test type using given id.
*
* @access public
* @param int $test_type Test type id
* @return string Formatted test type
*/
final public function format_test_type( $test_type )
{
return $this->test_types[$test_type];
}
/**
* Base::format_institution()
*
* Format institution name, using long or short form.
*
* @access public
* @param string $institution Institution
* @param bool $full Force long form of institution name
* @return string Formatted institution name
*/
final public function format_institution( $institution, $full = FALSE )
{
global $Database;
$sql = "SELECT i.name, i.short_name
FROM institutions i
WHERE i.institution = '$institution'";
$result = $Database->query( $sql );
$names = $Database->fetch_assoc( $result );
$Database->free_result( $result );
return ( ( $names['short_name'] && !$full ) ? $names['short_name'] : $names['name'] );
}
/**
* Base::format_semester()
*
* Format semester, using seasons.
*
* @access public
* @param int|string $semester Semester (format: YYYYMM)
* @return string Formatted semester
*/
final public function format_semester( $semester )
{
$data = preg_split( '/(\d{4})(\d{2})/', $semester, -1, PREG_SPLIT_DELIM_CAPTURE );
if( !$data || ( count( $data ) != 4 ) )
{
return FALSE;
}
$year = $data[1];
switch( $data[2] )
{
case '01':
case '02':
case '03':
case '04':
case '05':
$season = 'Spring';
break;
case '06':
case '07':
case '08':
$season = 'Summer';
break;
case '09':
case '10':
case '11':
case '12':
$season = 'Fall';
break;
default:
return FALSE;
break;
}
return "$season $year";
}
/**
* Base::format_instructors()
*
* Format list of instructors.
*
* @todo Remove obsolete code.
*
* @access public
* @param string $instructors Unformatted list of intructors
* @param string $glue Glue used to connect instructors (default: "\n")
* @return string Formatted list of instructors
*/
final public function format_instructors( $instructors, $glue = "\n" )
{
global $Database;
if( is_array( $instructors ) )
{
$instructors = $this->prepare_instructors( $instructors );
}
$instructors = explode( ',', $instructors );
foreach( $instructors as $id => $instructor )
{
$instructors[$id] = $instructor = trim( $instructor );
if( $this->validate_instructor_key( $instructor ) )
{
$sql = "SELECT *
FROM instructors
WHERE instructor_key = '$instructor'";
$result = $Database->query( $sql );
while( $row = $Database->fetch_assoc( $result ) )
{
$instructors[$id] = $row['last_name'] . ', ' . $row['first_name'];
if( trim( $row['middle_name'] ) )
{
$instructors[$id] .= ' ';
if( strpos( $row['middle_name'], '.' ) )
{
$instructors[$id] .= $row['middle_name'];
}
else
{
$instructors[$id] .= substr( $row['middle_name'], 0, 1 ) . '.';
}
}
}
$Database->free_result( $result );
}
else
{
$last_name = substr( $instructor, 0, strrpos( $instructor, ' ' ) );
$first_initial = substr( $instructor, strrpos( $instructor, ' ' ) + 1, strlen( $instructor ) );
if( $last_name && $first_initial )
{
$instructors[$id] = "$last_name, $first_initial.";
}
}
}
return implode( $glue, $instructors );
}
/**
* Base::format_course()
*
* Format course code.
*
* @access public
* @param string $subject Subject code
* @param string|int $course Course number
* @param bool|string $institution Institution
* @param string $glue Glue to assemble subject and course (default: ' ')
* @return string Formatted course number
*/
final public function format_course( $subject, $course, $institution = FALSE, $glue = ' ' )
{
global $Database;
$institution = ( $institution && $this->validate_institution( $institution ) ) ? (string) $institution : $this->institution;
$sql = "SELECT cf.*
FROM course_format cf
WHERE cf.institution = '$institution'";
$result = $Database->query( $sql );
if( $Database->has_result( $result ) )
{
$course_format = $Database->fetch_assoc( $result );
$course_max_length = $course_format['course_max_length'];
// Don't force the lengths; use them only as a guide
$course = ltrim( $course, '0' );
$course = ( strlen( $course ) > $course_max_length ) ? $course : str_pad( $course, $course_max_length, '0', STR_PAD_LEFT );
// $subject = substr( $subject, 0, $course_format['subject_max_length'] );
// $course = substr( $course, -$course_max_length, $course_max_length );
}
$Database->free_result( $result );
if( $glue === FALSE )
{
return array(
'subject' => $subject,
'course' => $course
);
}
return $subject . $glue . $course;
}
/**
* Base::print_sub_navigation()
*
* Print page-specific navigation.
*
* @access public
* @param array $sub_nav Navigation link data.
* @return bool Status of printing sub-navigation.
*/
public function print_sub_navigation( $sub_nav )
{
if( !is_array( $sub_nav ) )
{
return FALSE;
}
print "\t\t" . '<div id="sub-nav">' . "\n";
print "\t\t\t" . '<ul>' . "\n";
foreach( $sub_nav as $link_id => $link )
{
print "\t\t\t\t" . '<li><a href="' . htmlentities( $link['url'], ENT_QUOTES, 'UTF-8' ) . '">' . htmlentities( $link['title'], ENT_QUOTES, 'UTF-8' ) . '</a></li>' . "\n";
}
print "\t\t\t" . '</ul>' . "\n";
print "\t\t" . '</div>' . "\n";
return TRUE;
}
/**
* Base::print_semester_navigation()
*
* Print semester navigation for previous and next semesters.
*
* @access public
* @param int|string $semester Current semester (format: YYYYMM)
* @param string $file File/path requiring navigation
* @param bool|string $institution Limit selection to given institution
* @return bool Status of printing navigation links
*/
public function print_semester_navigation( $semester, $file, $institution = FALSE )
{
if( !$this->validate_semester( $semester ) || ( $institution && !$this->validate_institution( $institution ) ) )
{
return FALSE;
}
$data = preg_split( '/^(\d{4})(\d{2})$/', $semester, -1, PREG_SPLIT_DELIM_CAPTURE );
$year = $data[1];
switch( $data[2] )
{
case '01':
case '02':
case '03':
case '04':
case '05':
$previous_month = '09';
$previous_year = $year - 1;
$next_month = '06';
$next_year = $year;
break;
case '06':
case '07':
case '08':
$previous_month = '01';
$previous_year = $year;
$next_month = '09';
$next_year = $year;
break;
case '09':
case '10':
case '11':
case '12':
$previous_month = '06';
$previous_year = $year;
$next_month = '01';
$next_year = $year + 1;
break;
default:
return FALSE;
break;
}
$previous = $previous_year . $previous_month;
$next = $next_year . $next_month;
$only_institution = ( $institution ) ? 'institution=' . $institution . '&' : '';
print "\t\t" . '<div class="semester-nav">' . "\n";
print "\t\t\t" . '<div class="left-column"><a href="' . $file . '?' . $only_institution . 'semester=' . $previous . '">← ' . $this->format_semester( $previous ) . '</a></div>' . "\n";
print "\t\t\t" . '<div class="center-column">';
if( $institution )
{
print $this->format_institution( $institution, TRUE ) . ' – <a href="' . $file . '?semester=' . $semester . '">';
}
print $this->format_semester( $semester ) . ( ( $institution ) ? '</a>' : '' ) . '</div>' . "\n";
print "\t\t\t" . '<div class="right-column"><a href="' .$file . '?' . $only_institution . 'semester=' . $next . '">' . $this->format_semester( $next ) . ' →</a></div>' . "\n";
print "\t\t" . '</div>' . "\n";
return TRUE;
}
/**
* Base::print_list_table()
*
* Print table for lists.
*
* @access public
* @param string $nav_file Path to use for navigation
* @param array $columns Data for column structure
* @param array $headers Data for headers and footers
* @param array $rows Data for rows and cells
* @return bool Status of printing list table
*/
public function print_list_table( $nav_file, $columns, $headers, $rows )
{
$semester = ( $this->semester ) ? $this->semester : $this->default_semester;
$this->print_semester_navigation( $semester, $nav_file, $this->institution );
print "\t\t" . '<table class="list">' . "\n";
print "\t\t\t" . '<colgroup>' . "\n";
foreach( $columns as $col )
{
print "\t\t\t\t" . '<col';
if( exists( $col['span'] ) )
{
print ' span="' . $col['span'] . '"';
}
if( exists( $col['class'] ) )
{
print ' class="' . $col['class'] . '"';
}
if( exists( $col['style'] ) )
{
print ' style="' . $col['style'] . '"';
}
print ' />' . "\n";
}
print "\t\t\t" . '</colgroup>' . "\n";
for( $top = 1; $top >= 0; $top-- )
{
if( $top )
{
print "\t\t\t" . '<thead style="border-bottom: 3px solid black;">' . "\n";
}
else
{
print "\t\t\t" . '<tfoot style="border-top: 3px solid black;">' . "\n";
}
print "\t\t\t\t" . '<tr>' . "\n";
foreach( $headers as $head )
{
if( does_not_exist( $head['content'] ) )
{
$head['content'] = ' ';
}
print "\t\t\t\t\t" . '<th';
if( exists( $head['colspan'] ) )
{
print ' colspan="' . $head['colspan'] . '"';
}
if( exists( $head['class'] ) )
{
print ' class="' . $head['class'] . '"';
}
if( exists( $head['style'] ) )
{
print ' style="' . $head['style'] . '"';
}
print '>' . $head['content'] . '</th>' . "\n";
}
print "\t\t\t\t" . '</tr>' . "\n";
if( $top )
{
print "\t\t\t" . '</thead>' . "\n";
}
else
{
print "\t\t\t" . '</tfoot>' . "\n";
}
}
print "\t\t\t" . '<tbody>' . "\n";
foreach( $rows as $row_id => $row )
{
print "\t\t\t\t" . '<tr';
if( exists( $row['class'] ) )
{
print ' class="' . $row['class'] . '"';
}
if( exists( $row['style'] ) )
{
print ' style="' . $row['style'] . '"';
}
print '>' . "\n";
foreach( $row['content'] as $cell )
{
if( empty( $cell ) )
{
continue;
}
if( does_not_exist( $cell['content'] ) )
{
$cell['content'] = ' ';
}
print "\t\t\t\t\t" . '<td';
if( exists( $cell['colspan'] ) )
{
print ' colspan="' . $cell['colspan'] . '"';
}
if( exists( $cell['class'] ) )
{
print ' class="' . $cell['class'] . '"';
}
if( exists( $cell['style'] ) )
{
print ' style="' . $cell['style'] . '"';
}
print '>' . $cell['content'] . '</td>' . "\n";
}
print "\t\t\t\t" . '</tr>' . "\n";
}
print "\t\t\t" . '</tbody>' . "\n";
print "\t\t" . '</table>' . "\n";
$this->print_semester_navigation( $semester, $nav_file, $this->institution );
return TRUE;
}
/**
* Base::create_form()
*
* Create a form using Forms::create_form().
*
* @access public
* @param string $form_name Form name
* @param string $form_action URL to send form data
* @param array $form_data Parameters used to propagate form
* @return void Prints a complete HTML form
*/
public function create_form( $form_name, $form_action, $form_data )
{
return Forms::create_form( $form_name, $form_action, $form_data );
}
}
?>