Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature:System] Autofeed Update For PHP 8.1+ #35

Merged
merged 9 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 21 additions & 16 deletions student_auto_feed/add_drop_report.php
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,16 @@ public static function close() {
}

/**
* Verify that DB connection resource is OK
* Verify that DB connection resource/instance is OK
*
* PHP < 8.1: self::$db is a resource
* PHP >= 8.1: self::$db is an instanceof \PgSql\Connection
*
* @access private
* @return bool true when DB connection resource is OK, false otherwise.
* @return bool true when DB connection resource/instance is OK, false otherwise.
*/
private static function check() {
return is_resource(self::$db) && pg_connection_status(self::$db) === PGSQL_CONNECTION_OK;
return (is_resource(self::$db) || self::$db instanceof \PgSql\Connection) && pg_connection_status(self::$db) === PGSQL_CONNECTION_OK;
}

/**
Expand All @@ -148,7 +151,7 @@ public static function get_courses($term) {

// Undergraduate courses from DB.
$sql = "SELECT course FROM courses WHERE term=$1 AND status=1";
$params = array($term);
$params = [$term];
$res = pg_query_params(self::$db, $sql, $params);
if ($res === false)
die("Failed to retrieve course list from DB\n");
Expand All @@ -171,7 +174,7 @@ public static function get_mapped_courses($term) {

// mapped courses from DB
$sql = "SELECT course, mapped_course FROM mapped_courses WHERE term=$1";
$params = array($term);
$params = [$term];
$res = pg_query_params(self::$db, $sql, $params);
if ($res === false) {
die("Failed to retrieve mapped courses from DB\n");
Expand Down Expand Up @@ -199,15 +202,15 @@ public static function count_enrollments($term, $course_list, $mapped_courses) {
die("Not connected to DB when querying course enrollments\n");
}

$course_enrollments = array();
$manual_flags = array();
$course_enrollments = [];
$manual_flags = [];

foreach ($course_list as $course) {
$grad_course = array_search($course, $mapped_courses);
if ($grad_course === false) {
// COURSE HAS NO GRAD SECTION (not mapped).
$sql = "SELECT COUNT(*) FROM courses_users WHERE term=$1 AND course=$2 AND user_group=4 AND registration_section IS NOT NULL";
$params = array($term, $course);
$params = [$term, $course];
$res = pg_query_params(self::$db, $sql, $params);
if ($res === false)
die("Failed to lookup enrollments for {$course}\n");
Expand All @@ -222,7 +225,7 @@ public static function count_enrollments($term, $course_list, $mapped_courses) {
} else {
// UNDERGRADUATE SECTION
$sql = "SELECT COUNT(*) FROM courses_users WHERE term=$1 AND course=$2 AND user_group=4 AND registration_section='1'";
$params = array($term, $course);
$params = [$term, $course];
$res = pg_query_params(self::$db, $sql, $params);
if ($res === false)
die("Failed to lookup enrollments for {$course}\n");
Expand Down Expand Up @@ -254,7 +257,7 @@ public static function count_enrollments($term, $course_list, $mapped_courses) {
// Courses make up array keys. Sort by courses.
ksort($course_enrollments);
ksort($manual_flags);
return array($course_enrollments, $manual_flags);
return [$course_enrollments, $manual_flags];
}
}

Expand Down Expand Up @@ -282,7 +285,7 @@ public static function write_temp_csv($course_enrollments) {
}

foreach($course_enrollments as $course=>$num_students) {
fputcsv($fh, array($course, $num_students), CSV_DELIM_CHAR);
fputcsv($fh, [$course, $num_students], CSV_DELIM_CHAR);
}
fclose($fh);
chmod($tmp_path . $tmp_file, 0660);
Expand All @@ -305,7 +308,7 @@ public static function read_temp_csv() {

unlink($tmp_path . $tmp_file); // remove tmp file.
array_walk($csv, 'callbacks::str_getcsv_cb');
// return array of array('course' => enrollment). e.g. ('csci1000' => 100)
// return array of ['course' => enrollment]. e.g. ['csci1000' => 100]
return array_combine(array_column($csv, 0), array_column($csv, 1));
}

Expand All @@ -321,9 +324,11 @@ public static function compile_report($prev_course_enrollments, $course_enrollme
// Compile stats
$date = date("F j, Y");
$time = date("g:i A");
$report = "Student autofeed counts report for {$date} at {$time}\n";
$report .= "NOTE: Difference and ratio do not account for the manual flag.\n";
$report .= "COURSE YESTERDAY TODAY MANUAL DIFFERENCE RATIO\n";
$report = <<<HEADING
Student autofeed counts report for {$date} at {$time}
NOTE: Difference and ratio do not account for the manual flag.
COURSE YESTERDAY TODAY MANUAL DIFFERENCE RATIO\n
HEADING;

foreach ($course_enrollments as $course=>$course_enrollment) {
// Calculate data
Expand Down Expand Up @@ -363,7 +368,7 @@ public static function send_report($term, $report) {
$from = ADD_DROP_FROM_EMAIL;
$subject = "Submitty Autofeed Add/Drop Report For {$date}";
$report = str_replace("\n", "\r\n", $report); // needed for email formatting
$is_sent = mail($to, $subject, $report, array('from' => $from));
$is_sent = mail($to, $subject, $report, ['from' => $from]);
if (!$is_sent) {
$report = str_replace("\r\n", "\n", $report); // revert back since not being emailed.
fprintf(STDERR, "Add/Drop report could not be emailed.\n%s", $report);
Expand Down
5 changes: 1 addition & 4 deletions student_auto_feed/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* config.php script used by submitty_student_auto_feed
* By Peter Bailie, Systems Programmer (RPI dept of computer science)
*
* Requires minimum PHP version 7.1 with pgsql extension.
* Requires minimum PHP version 7.3 with pgsql extension.
*
* Configuration of submitty_student_auto_feed is structured through a series
* of named constants.
Expand Down Expand Up @@ -127,9 +127,6 @@
//Set to true, if Submitty is using SAML for authentication.
define('PROCESS_SAML', true);

//Allows "\r" EOL encoding. This is rare but exists (e.g. Excel for Macintosh).
ini_set('auto_detect_line_endings', true);

/* DATA SOURCING --------------------------------------------------------------
* The Student Autofeed provides helper scripts to retrieve the CSV file for
* processing. Shell script ssaf.sh is used to invoke one of the helper
Expand Down
20 changes: 11 additions & 9 deletions student_auto_feed/crn_copymap.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,18 @@ private function write_mappings($args) {

$len = count($source_sections);
for ($i = 0; $i < $len; $i++) {
$row = array($source_course, $source_sections[$i], $dest_course, $dest_sections[$i]);
$row = [$source_course, $source_sections[$i], $dest_course, $dest_sections[$i]];
fputcsv($fh, $row, ",");
}

fclose($fh);
}

private function get_mappings($sections) {
if ($sections === "" || $sections === "all") return array($sections);
if ($sections === "" || $sections === "all") return [$sections];

$arr = explode(",", $sections);
$expanded = array();
$expanded = [];
foreach($arr as $val) {
if (preg_match("/(\d+)\-(\d+)/", $val, $matches) === 1) {
$expanded = array_merge($expanded, range((int) $matches[1], (int) $matches[2]));
Expand Down Expand Up @@ -100,10 +100,12 @@ class cli {
Arguments:
-h, --help, help Show this help message.
term Term code of courses and sections being mapped. Required.
course-a Original course
sections Section list, or "all" of preceding course
course-b Course being copied to
sections For course-b, this can be ommited when course-a sections is "all"
course-a Original course.
sections Section list or "all" for course-a.
course-b Course being copied to.
sections Section list or "all" for course-b.

Course-b sections can be ommited when course-a sections is "all"\n
ARGS_LIST;

/**
Expand All @@ -115,7 +117,7 @@ class cli {
*/
public static function parse_args() {
global $argc, $argv;
$matches = array();
$matches = [];

switch(true) {
// Check for request for help
Expand All @@ -130,7 +132,7 @@ public static function parse_args() {
case preg_match("/^[\w\d\-]+$/", $argv[2], $matches['source']['course']) !== 1:
case preg_match("/^\d+(?:(?:,|\-)\d+)*$|^all$/", $argv[3], $matches['source']['sections']) !== 1:
case preg_match("/^[\w\d\-]+$/", $argv[4], $matches['dest']['course']) !== 1:
case preg_match("/^\d+(?:(?:,|\-)\d+)*$|^(?:all)?$/", $argv[5], $matches['dest']['sections']) !== 1:
case preg_match("/^\d+(?:(?:,|\-)\d+)*$|^(?:all)?$/", $argv[5] ?? "", $matches['dest']['sections']) !== 1:
self::print_usage();
exit;
}
Expand Down
2 changes: 1 addition & 1 deletion student_auto_feed/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ policies and practices.__

Detailed instructions can be found at [http://submitty.org/sysadmin/student\_auto\_feed](http://submitty.org/sysadmin/student_auto_feed)

Requirements: PHP 7.1 or higher with pgsql extension. `imap_remote.php` also
Requirements: PHP 7.3 or higher with pgsql extension. `imap_remote.php` also
requires the imap extension. This system is intended to be platform agnostic,
but has been developed and tested with Ubuntu Linux.

Expand Down
17 changes: 8 additions & 9 deletions student_auto_feed/ssaf_cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@
/** class to parse command line arguments */
class cli_args {
/** @var array Holds all CLI argument flags and their values */
private static $args = array();
private static $args = [];
/** @var string usage help message */
private static $help_usage = "Usage: submitty_student_auto_feed.php [-h | --help] [-a auth str] (-t term code)\n";
/** @var string short description help message */
private static $help_short_desc = "Read student enrollment CSV and upsert to Submitty database.\n";
/** @var string argument list help message */
private static $help_args_list = <<<HELP
Arguments:
-h, --help Show this help message.
-a auth str Specify 'user:password@server', overriding config.php. Optional.
-t term code Term code associated with current student enrollment. Required.
-l Send a test message to error log(s) and quit.

HELP;
Arguments:
-h, --help Show this help message.
-a auth str Specify 'user:password@server', overriding config.php. Optional.
-t term code Term code associated with current student enrollment. Required.
-l Send a test message to error log(s) and quit.\n
HELP;

/**
* Parse command line arguments
Expand All @@ -27,7 +26,7 @@ class cli_args {
* @return mixed term code as string or boolean false when no term code is present.
*/
public static function parse_args() {
self::$args = getopt('ha:t:l', array('help'));
self::$args = getopt('ha:t:l', ['help']);

switch(true) {
case array_key_exists('h', self::$args):
Expand Down
36 changes: 22 additions & 14 deletions student_auto_feed/ssaf_db.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,15 +82,15 @@ public static function get_mapped_courses($term) {

// Describe how auto-feed data is translated by mappings.
// There are no mappings when $result is null.
$mappings = array();
$mappings = [];
if (!is_null($results)) {
foreach ($results as $row) {
$course = $row['course'];
$section = $row['registration_section'];
$mappings[$course][$section] = array(
$mappings[$course][$section] = [
'mapped_course' => $row['mapped_course'],
'mapped_section' => $row['mapped_section']
);
];
}
}

Expand All @@ -110,7 +110,7 @@ public static function get_enrollment_count($semester, $course) {
return false;
}

$results = self::run_query(sql::GET_COURSE_ENROLLMENT_COUNT, array($semester, $course));
$results = self::run_query(sql::GET_COURSE_ENROLLMENT_COUNT, [$semester, $course]);
if ($results === false) {
self::$error .= "Error while retrieving course enrollment counts.";
return false;
Expand Down Expand Up @@ -166,14 +166,14 @@ public static function upsert($semester, $course, $rows) : bool {

// Do upsert of course enrollment data.
foreach($rows as $row) {
$users_params = array(
$users_params = [
$row[COLUMN_USER_ID],
$row[COLUMN_NUMERIC_ID],
$row[COLUMN_FIRSTNAME],
$row[COLUMN_LASTNAME],
$row[COLUMN_PREFERREDNAME],
$row[COLUMN_EMAIL]
);
];

// Determine registration type for courses_users table
// Registration type code has already been validated by now.
Expand All @@ -189,19 +189,19 @@ public static function upsert($semester, $course, $rows) : bool {
break;
}

$courses_users_params = array(
$courses_users_params = [
$semester,
$course,
$row[COLUMN_USER_ID],
4,
$row[COLUMN_SECTION],
$registration_type,
"FALSE"
);
];

$reg_sections_params = array($semester, $course, $row[COLUMN_SECTION], $row[COLUMN_REG_ID]);
$tmp_table_params = array($row[COLUMN_USER_ID]);
$dropped_users_params = array($semester, $course);
$reg_sections_params = [$semester, $course, $row[COLUMN_SECTION], $row[COLUMN_REG_ID]];
$tmp_table_params = [$row[COLUMN_USER_ID]];
$dropped_users_params = [$semester, $course];

// Upsert queries
// If any query returns false, we need to rollback and bail out.
Expand Down Expand Up @@ -247,8 +247,16 @@ public static function upsert($semester, $course, $rows) : bool {

// PRIVATE STATIC FUNCTIONS ------------------------------------------------

/**
* Verify that DB connection resource/instance is OK
*
* PHP < 8.1: self::$db is a resource
* PHP >= 8.1: self::$db is an instanceof \PgSql\Connection
*
* @return bool true when DB connection resource/instance is OK, false otherwise.
*/
private static function check() : bool {
if (!is_resource(self::$db) || pg_connection_status(self::$db) !== PGSQL_CONNECTION_OK) {
if ((!is_resource(self::$db) && !(self::$db instanceof \PgSql\Connection)) || pg_connection_status(self::$db) !== PGSQL_CONNECTION_OK) {
self::$error = "No DB connection.";
return false;
}
Expand All @@ -273,8 +281,8 @@ private static function run_query($sql, $params = null) {
return false;
}

if (is_null($params)) $params = array();
else if (!is_array($params)) $params = array($params);
if (is_null($params)) $params = [];
elseif (is_scalar($params)) $params = [$params];

$res = pg_query_params(self::$db, $sql, $params);
if ($res === false) {
Expand Down
Loading