[LON-CAPA-cvs] cvs: modules /msu localenroll.pm

raeburn raeburn at source.lon-capa.org
Wed Sep 8 19:33:00 EDT 2021


raeburn		Wed Sep  8 23:33:00 2021 EDT

  Modified files:              
    /modules/msu	localenroll.pm 
  Log:
  - Integration with MSU campus information systems
    - Automated updates for first name, middle name, last name etc. now use
      preferred first name (where available), middle initial only (unless
      a student), and post-nominal generation (if applicable).
    - LDAP is primary source for all except PIDs.  PIDs are from RO, CS or HR.
      If the Z-PID is unavailable for Faculty, EmplID in used instead.
      If no A-PID, Z-PID or EmplID is available, uidNumber (from LDAP is used).
  
  
-------------- next part --------------
Index: modules/msu/localenroll.pm
diff -u modules/msu/localenroll.pm:1.82 modules/msu/localenroll.pm:1.83
--- modules/msu/localenroll.pm:1.82	Sun Sep  5 18:58:35 2021
+++ modules/msu/localenroll.pm	Wed Sep  8 23:33:00 2021
@@ -1,6 +1,6 @@
 # functions to glue school database system into Lon-CAPA for
 # automated enrollment
-# $Id: localenroll.pm,v 1.82 2021/09/05 18:58:35 raeburn Exp $
+# $Id: localenroll.pm,v 1.83 2021/09/08 23:33:00 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -224,7 +224,7 @@
   <email>$pilot\@msu.edu</email>
   <enddate></enddate>
   <firstname>$first</firstname>
-  <generation></generation>
+  <generation>$generation</generation>
   <groupID>$class</groupID>
   <lastname>$last</lastname>
   <middlename>$middle</middlename>
@@ -1254,16 +1254,95 @@
     return 'ok';
 }
 
+sub userinfo_searchtables {
+    my ($dbh,$dbflag,$srchtables,$affiliation_by_table,$types) = @_;
+    return unless ((ref($dbh) eq 'HASH') &&
+                   (ref($dbflag) eq 'HASH') &&
+                   (ref($srchtables) eq 'HASH'));
+    my @order = ('ro','cs','hr');
+    my %tables = (
+                    ro => {
+                             Faculty => 'RO_CLIFMS',
+                             Student => 'RO_ClassList',
+                          },
+                    cs => {
+                             Faculty => 'R_CLASSINSTRUCTORS_RV',
+                          },
+                    hr => {
+                             Faculty => 'FACULTY_VU',
+                             Staff => 'STAFF_VU',
+                             Student => 'STUDENT',
+                             Assistant => 'ASSISTANT',
+                             StaffAff => 'AFFILIATE',
+                             StuAff => 'STUDENT_AFFILIATE',
+                          },
+                 );
+    my %table_to_affiliation = (
+                                RO_CLIFMS => 'Faculty',
+                                RO_ClassList => 'Student',
+                                R_CLASSINSTRUCTORS_RV => 'Faculty',
+                                FACULTY_VU => 'Faculty',
+                                STAFF_VU => 'Staff',
+                                STUDENT => 'Student',
+                                ASSISTANT => 'Assistant',
+                                AFFILIATE => 'StaffAff',
+                                STUDENT_AFFILIATE => 'StuAff',
+                               );
+    %{$affiliation_by_table} = %table_to_affiliation;
+    my %tableorder = (
+                       ro => ['Student','Faculty'],
+                       cs => ['Faculty'],
+                       hr => ['Student','Faculty','Staff','StuAff','Assistant','StaffAff'],
+                     );
+    ($dbh->{'hr'},$dbflag->{'hr'}) = &connect_DB('HR');
+    ($dbh->{'cs'},$dbflag->{'cs'}) = &connect_DB('SISCS');
+    ($dbh->{'ro'},$dbflag->{'ro'}) = &connect_DB('RO');
+    my @connected;
+    foreach my $key (@order) {
+        if ($dbflag->{$key}) {
+            push(@connected,$key);
+        }
+    }
+    if (@connected) {
+        if (ref($types) eq 'ARRAY') {
+            foreach my $key (@connected) {
+                foreach my $type (@{$types}) {
+                    if (exists($tables{$key}{$type})) {
+                        push(@{$srchtables->{$key}},$tables{$key}{$type});
+                    }
+                }
+            }
+        }
+        foreach my $key (@connected) {
+            unless ((ref($srchtables->{$key}) eq 'ARRAY') && (@{$srchtables->{$key}} > 0)) {
+                if (ref($tableorder{$key}) eq 'ARRAY') {
+                    foreach my $type (@{$tableorder{$key}}) {
+                        if (exists($tables{$key}{$type})) {
+                            push(@{$srchtables->{$key}},$tables{$key}{$type});
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return @connected;
+}
+
 sub allusers_info {
-    my ($dom,$instusers,$instids) = @_;
+    my ($dom,$instusers,$instids,$lc_users) = @_;
     my $outcome;
-    my ($dbh,$dbflag) = &connect_DB('HR');
-    if ($dbflag) {
-        my @srchtables = ('FACULTY_VU','STAFF_VU','STUDENT','AFFILIATE',
-                          'ASSISTANT','STUDENT_AFFILIATE');
-        &query_user_tables($dbflag,$dbh,\@srchtables,$instusers,$instids);
-        $outcome = 'ok';
-        &disconnect_DB($dbh);
+    &query_ldap($instusers,$lc_users);
+    my (%dbh,%dbflag,%srchtables,%affiliation_by_table);
+    my @connected = &userinfo_searchtables(\%dbh,\%dbflag,\%srchtables,
+                                           \%affiliation_by_table);
+    if (@connected) {
+        $outcome = &query_user_tables(\%dbflag,\%dbh,\%srchtables,\%affiliation_by_table,
+                                      $instusers,$instids,$lc_users);
+        foreach my $conn (@connected) {
+            if ($dbflag{$conn}) {
+                &disconnect_DB($dbh{$conn});
+            }
+        }
     }
     return $outcome;
 }
@@ -1272,45 +1351,15 @@
     my ($dom,$caller,$userhash,$instusers,$instids,$types) = @_;
     my $outcome;
     if (ref($userhash) eq 'HASH') {
-        my ($srchby,$stoponmatch);
         if ($caller eq 'id') {
-            $srchby = 'id';
+            $outcome = &query_by_id($instusers,$instids,'',$userhash,$types);
         } else {
-            $srchby = 'uname';
-            $stoponmatch = 1;
-        }
-        my @srchtables;
-        my @tableorder = qw(Student Faculty Staff StuAff Assistant StaffAff);
-        my %tables = (Faculty => 'FACULTY_VU',
-                      Staff => 'STAFF_VU',
-                      Student => 'STUDENT',
-                      Assistant => 'ASSISTANT',
-                      StaffAff => 'AFFILIATE',
-                      StuAff => 'STUDENT_AFFILIATE');
-        my ($dbh,$dbflag) = &connect_DB('HR');
-        if ($dbflag) {
-            if (ref($types) eq 'ARRAY') {
-                foreach my $type (@{$types}) {
-                    if (exists($tables{$type})) {
-                        push(@srchtables,$tables{$type});
-                    }
-                }
-            }
-            if (@srchtables == 0) {
-                foreach my $type (@tableorder) {
-                    if (exists($tables{$type})) {
-                        push(@srchtables,$tables{$type});
-                    }
-                }
-            }
             foreach my $key (keys(%{$userhash})) {
-                &query_user_tables($dbflag,$dbh,\@srchtables,$instusers,$instids,
-                                   $srchby,$key,undef,$types,$stoponmatch);
+                $outcome = &query_ldap($instusers,'','uname',$key,'',$types);
+            }
+            if (keys(%{$instusers})) {
+                &get_pids($instusers,$instids,$types);
             }
-            $outcome = 'ok';
-            &disconnect_DB($dbh);
-        } else {
-            $outcome = 'unavailable';
         }
     } else {
         $outcome = 'invalid';
@@ -1319,228 +1368,454 @@
 }
 
 sub get_userinfo {
-    my ($dom,$uname,$id,$instusers,$instids,$types,
-        $srchby,$srchterm,$srchtype) = @_;
-    my ($outcome,$stoponmatch, at srchtables);
-    my @tableorder = qw(Student Faculty Staff StuAff Assistant StaffAff);
-    my %tables = (Faculty => 'FACULTY_VU',
-                  Staff => 'STAFF_VU',
-                  Student => 'STUDENT',
-                  Assistant => 'ASSISTANT',
-                  StaffAff => 'AFFILIATE',
-                  StuAff => 'STUDENT_AFFILIATE');
-    my ($dbh,$dbflag) = &connect_DB('HR');
-    foreach my $type (@{$types}) {
-        if (exists($tables{$type})) {
-            push(@srchtables,$tables{$type});           
-        }
-    }
-    if (@srchtables == 0) {
-        foreach my $type (@tableorder) {
-            if (exists($tables{$type})) {
-                push(@srchtables,$tables{$type});
-            }
-        }
-    }
+    my ($dom,$uname,$id,$instusers,$instids,$types,$srchby,$srchterm,$srchtype) = @_;
+    my $outcome;
     if ($srchby eq '' && $srchterm eq '') {
         if ($uname ne '') {
             $srchby = 'uname';
             $srchterm = $uname;
-            $stoponmatch = 1;
         } elsif ($id ne '') {
             $srchby = 'id';
             $srchterm = $id;
         }
     }
     if ($srchterm ne '') {
-        $outcome = &query_user_tables($dbflag,$dbh,\@srchtables,$instusers,$instids,
-                                      $srchby,$srchterm,$srchtype,$types,$stoponmatch);
-    }
-    if ($dbflag) {
-        &disconnect_DB($dbh);
+        if ($srchby eq 'id') {
+            $outcome = &query_by_id($instusers,$instids,$srchterm,'',$types);
+        } else {
+            $outcome = &query_ldap($instusers,'',$srchby,$srchterm,$srchtype,$types);
+            if (keys(%{$instusers})) {
+                &get_pids($instusers,$instids,$types);
+            }
+        }
     }
     return $outcome;
 }
 
-sub query_user_tables {
-    my ($dbflag,$dbh,$srchtables,$instusers,$instids,$srchby,$srchterm,$srchtype,$types,$stoponmatch) = @_;
-    my ($outcome,$condition,%multipids,$ldapfilter,$omitldap);
-    if ($srchby eq 'uname') {
-        if ($srchterm =~ /^\w{2,8}$/) {
-            if ($srchtype eq 'contains') {
-                $condition = "WHERE MSUNetID LIKE '%$srchterm%'";
-                $ldapfilter = '(uid=*'.$srchterm.'*)';
-            } elsif ($srchtype eq 'begins') {
-                $condition = "WHERE MSUNetID LIKE '$srchterm%'";
-                $ldapfilter = '(uid='.$srchterm.'*)';
-            } else {
-                $condition = "WHERE MSUNetID = '$srchterm'";
-                $ldapfilter = '(uid='.$srchterm.')';
-                $omitldap = 1;
-            }
-        }
-    } elsif ($srchby eq 'lastname') {
-        if ($srchterm =~ /[A-Za-z\-\.'\s]+/) {
-            if ($srchtype eq 'contains') {
-                if ($dbflag) {
-                    my $quoted_last = $dbh->quote('%'.$srchterm.'%');
-                    $condition = "WHERE LastName LIKE $quoted_last";
-                }
-                $ldapfilter = '(sn=*'.$srchterm.'*)';
-            } elsif ($srchtype eq 'begins') {
-                if ($dbflag) {
-                    my $quoted_last = $dbh->quote($srchterm.'%');
-                    $condition = "WHERE LastName LIKE $quoted_last";
+sub query_ldap {
+    my ($instusers,$lc_users,$srchby,$srchterm,$srchtype,$types) = @_;
+    my $outcome;
+    if ($srchby eq '') {
+        $outcome = &ldap_dump($instusers,$lc_users);
+    } else {
+        my $ldapfilter;
+        if ($srchby eq 'uname') {
+            if ($srchterm =~ /^\w{2,8}$/) {
+                if ($srchtype eq 'contains') {
+                    $ldapfilter = '(uid=*'.$srchterm.'*)';
+                } elsif ($srchtype eq 'begins') {
+                    $ldapfilter = '(uid='.$srchterm.'*)';
+                } else { 
+                    $ldapfilter = '(uid='.$srchterm.')';
+                }
+            }
+        } elsif ($srchby eq 'lastname') {
+            if ($srchterm =~ /[A-Za-z\-\.'\s]+/) {
+                if ($srchtype eq 'contains') {
+                    $ldapfilter = '(sn=*'.$srchterm.'*)';
+                } elsif ($srchtype eq 'begins') {
+                    $ldapfilter = '(sn='.$srchterm.'*)';
+                } else {
+                    $ldapfilter = '(sn='.$srchterm.')';
                 }
-                $ldapfilter = '(sn='.$srchterm.'*)';
-            } else {
-                if ($dbflag) { 
-                    my $quoted_last = $dbh->quote($srchterm);
-                    $condition = "WHERE LastName = $quoted_last";
-                }
-                $ldapfilter = '(sn='.$srchterm.')';
             }
-        }
-    } elsif ($srchby eq 'lastfirst') {
-        my ($srchlast,$srchfirst) = split(/,/,$srchterm);
-        $srchlast =~ s/\s+$//;
-        $srchfirst =~ s/^\s+//;
-        if (($srchlast =~ /[A-Za-z\-\.'\s]+/) &&
-            ($srchfirst  =~ /[A-Za-z\-\.'\s]+/)) {
-            my ($quoted_first,$quoted_last);
+        } elsif ($srchby eq 'lastfirst') {
+            my ($srchlast,$srchfirst) = split(/,/,$srchterm);
+            $srchlast =~ s/\s+$//;
+            $srchfirst =~ s/^\s+//;
             if ($srchtype eq 'contains') {
-                if ($dbflag) {
-                    $quoted_last = $dbh->quote('%'.$srchlast.'%');
-                    $quoted_first = $dbh->quote('%'.$srchfirst.'%');
-                    $condition = "WHERE ( LastName LIKE $quoted_last AND ".
-                                         "FirstName LIKE $quoted_first )";
-                }
                 $ldapfilter = '(&(sn=*'.$srchlast.'*)(givenName=*'.$srchfirst.'*))';
             } elsif ($srchtype eq 'begins') {
-                if ($dbflag) {
-                    $quoted_last = $dbh->quote($srchlast.'%');
-                    $quoted_first = $dbh->quote($srchfirst.'%');
-                    $condition = "WHERE ( LastName LIKE $quoted_last AND ".
-                                        "FirstName LIKE $quoted_first )";
-                }
                 $ldapfilter = '(&(sn='.$srchlast.'*)(givenName='.$srchfirst.'*))';
             } else {
-                if ($dbflag) {
-                    $quoted_last = $dbh->quote($srchterm);
-                    $quoted_first = $dbh->quote($srchterm);
-                    $condition = "WHERE ( LastName = $quoted_last AND ".
-                                        "FirstName = $quoted_first )";
-                }
                 $ldapfilter = '(&(sn='.$srchlast.')(givenName='.$srchfirst.'))';
             }
+        } elsif ($srchby eq 'email') {
+            if ($srchterm =~ /^(\w{2,8})\@msu\.edu$/) {
+                $ldapfilter = '(uid='.$1.')';
+            }
         }
-    } elsif ($srchby eq 'id') {
-        if ($dbflag) {
-            if ($srchterm =~ /^[AZ]\d{8}$/) {
-                $condition = "WHERE Pid = '$srchterm'";
+        if ($ldapfilter ne '') {
+            $outcome = &ldap_search($ldapfilter,$instusers,$types);
+        }
+    }
+    return $outcome;
+}
+
+sub get_pids {
+    my ($instusers,$instids,$types) = @_;
+    my (%dbh,%dbflag,%srchtables,%affiliation_by_table);
+    my @connected = &userinfo_searchtables(\%dbh,\%dbflag,\%srchtables,
+                                           \%affiliation_by_table,$types);
+    if (@connected) {
+        if (ref($instusers) eq 'HASH') {
+            my %unamefields = (
+                                hr => 'MSUNetID',
+                                ro => {
+                                        Faculty => 'MSUNetID',
+                                        Student => 'Pilot_Id',
+                                      },
+                                cs => {
+                                        Faculty => 'CAMPUS_ID',
+                                       },
+                              );
+            my %pidfields = (
+                             hr => 'Pid',
+                             ro => {
+                                      Faculty => 'Emp_Id,PID',
+                                      Student => 'Pid',
+                                   },
+                             cs => {
+                                      Faculty => 'EMPLID',
+                                   },
+                            );
+            if (keys(%dbflag)) {
+                my @order = ('hr','ro','cs');
+                my $stoponmatch = 1;
+                foreach my $uname (keys(%{$instusers})) {
+                    next unless ($uname =~ /^\w{2,8}$/);
+                    my $matched = 0;
+                    my $pid;
+                    foreach my $key (@order) {
+                        last if ($stoponmatch && $matched);
+                        if ($dbflag{$key}) {
+                            foreach my $table (@{$srchtables{$key}}) {
+                                next if ($affiliation_by_table{$table} eq '');
+                                last if ($stoponmatch && $matched);
+                                my $statement;
+                                if (ref($pidfields{$key}) eq 'HASH') {
+                                    next if ($pidfields{$key}{$affiliation_by_table{$table}} eq '');
+                                    $statement = 'SELECT DISTINCT '.$pidfields{$key}{$affiliation_by_table{$table}}.' FROM '.$table;
+                                } else {
+                                    next if ($pidfields{$key} eq '');
+                                    $statement = 'SELECT '.$pidfields{$key}.' FROM '.$table;
+                                }
+                                if (ref($unamefields{$key}) eq 'HASH') {
+                                    next if ($unamefields{$key}{$affiliation_by_table{$table}} eq '');
+                                    $statement .= ' WHERE '.$unamefields{$key}{$affiliation_by_table{$table}};
+                                } else {
+                                    next if ($unamefields{$key} eq '');
+                                    $statement .= ' WHERE '.$unamefields{$key}; 
+                                }
+                                if (ref($dbh{$key})) {
+                                    $statement .= '='.$dbh{$key}->quote($uname);
+                                    my $sth = $dbh{$key}->prepare("$statement");
+                                    $sth->execute();
+                                    while ( my (@info) = $sth->fetchrow_array ) {
+                                        last if ($stoponmatch && $matched);
+                                        if (($key eq 'ro') && ($affiliation_by_table{$table} eq 'Faculty')) {
+                                            $pid = (($info[0] eq '')? $info[1] : $info[0]); 
+                                        } else {
+                                            $pid = $info[0];
+                                        }
+                                        if ($pid ne '') {
+                                            if ($affiliation_by_table{$table} eq 'Student') {
+                                                if ($pid =~ /^1(\d{8})$/) {
+                                                    $pid = 'A'.$1;
+                                                }
+                                            }
+                                            $pid = lc($pid);
+                                            $instusers->{$uname}->{id} = $pid;
+                                            $matched = 1;
+                                        }
+                                    }
+                                    $sth->finish;
+                                }
+                            }
+                        }
+                    }
+                    if ($pid ne '') {
+                        if (defined($instids->{$pid})) {
+                            if (ref($instids->{$pid}) eq 'ARRAY') {
+                                if (!grep(/^$uname$/,@{$instids->{$pid}})) {
+                                    push(@{$instids->{$pid}},$uname);
+                                }
+                            } elsif ($instids->{$pid} ne $uname) {
+                                my $currname = $instids->{$pid};
+                                delete($instids->{$pid});
+                                $instids->{$pid} = [$currname,$uname];
+                            }
+                        } else {
+                            $instids->{$pid} = $uname;
+                        }
+                    }
+                }
             }
         }
-    } elsif ($srchby eq 'email') {
-        if ($dbflag) {
-            if ($srchterm =~ /^(\w{2,8})\@msu\.edu$/) {
-                $condition = "WHERE MSUNetID = '$1'";
-                $ldapfilter = '(uid='.$1.')';
-            } else {
-                return;
+        foreach my $conn (@connected) {
+            if ($dbflag{$conn}) {
+                &disconnect_DB($dbh{$conn});
             }
         }
     }
-    if ($dbflag) {
-        my $matched = 0;
-        foreach my $table (@{$srchtables}) {
-            last if ($srchby && $condition eq '');
-            last if ($stoponmatch && $matched);
-            my $statement = "SELECT MSUNetID,Pid,FirstName,LastName,Person_Type FROM $table $condition";
-            my $sth = $dbh->prepare("$statement");
-            $sth->execute();
-            while ( my($uname,$pid,$given,$last,$type) = $sth->fetchrow_array ) {
-                $uname=lc($uname);
-                $pid =~ s/^1(\d{8})$/A$1/;
-                $pid=lc($pid);
-                $given =~ s/^\s+//;
-                my ($first,$middle);
-                if ($given =~ m/\w\s+\w/) {
-                    $first = substr($given,0,index($given," "));
-                    $middle = substr($given,index($given," ")+1);
-                    $middle =~ s/^\s+//g;
-                    $middle =~ s/\s+$//g;
+    return;
+}
+
+sub query_by_id {
+    my ($instusers,$instids,$srchterm,$userhashref,$types) = @_;
+    return unless ((ref($instusers) eq 'HASH') && (ref($instids) eq 'HASH')); 
+    my (%dbh,%dbflag,%srchtables,%affiliation_by_table,$outcome);
+    my @connected = &userinfo_searchtables(\%dbh,\%dbflag,\%srchtables,
+                                           \%affiliation_by_table,$types);
+    if (@connected) {
+        if (keys(%dbflag)) {
+            my @order = ('hr','ro','cs');
+            my $stoponmatch = 1;
+            my @ids;
+            if ($srchterm ne '') {
+                @ids = ($srchterm);
+            } elsif (ref($userhashref) eq 'HASH') {
+                @ids = keys(%{$userhashref});
+            }
+            foreach my $pid (@ids) {
+                my (%idfield,%unamefield);
+                if ($pid =~ /^[AZ]\d{8}$/i) {
+                    $idfield{'hr'} = 'Pid';
+                    $unamefield{'hr'} = 'MSUNetID';
+                }
+                if ($pid =~ /^A\d{8}$/i) {
+                    $idfield{'ro'}{'Student'} = 'Pid';
+                    $unamefield{'ro'}{'Student'} = 'Pilot_Id';
+                } elsif ($pid =~ /^Z\d{8}$/i) {
+                    $idfield{'ro'}{'Faculty'} = 'PID';
+                    $unamefield{'ro'}{'Faculty'} = 'MSUNetID'; 
+                } elsif ($pid =~ /^1\d{8}$/) {
+                    $idfield{'ro'}{'Faculty'} = 'Emp_Id';
+                    $unamefield{'ro'}{'Faculty'} = 'MSUNetID';
+                    $idfield{'ro'}{'Student'} = 'Pid';
+                    $unamefield{'ro'}{'Student'} = 'Pilot_Id'; 
+                    $idfield{'cs'}{'Faculty'} = 'EMPLID';
+                    $unamefield{'cs'}{'Faculty'} = 'CAMPUS_ID';
                 } else {
-                    $first = $given;
+                    next;
                 }
-                $first =~ s/\s+$//;
-                if (ref($instusers->{$uname}) eq 'HASH') {
-                    if (ref($instusers->{$uname}{'inststatus'}) eq 'ARRAY') {
-                        if (!grep(/^$type$/,@{$instusers->{$uname}{'inststatus'}})) {
-                            push(@{$instusers->{$uname}{'inststatus'}},$type);
+                my $matched = 0;
+                my $uname;
+                foreach my $key (@order) {
+                    last if ($stoponmatch && $matched);
+                    if (($dbflag{$key}) && (ref($srchtables{$key}) eq 'ARRAY')) {
+                        foreach my $table (@{$srchtables{$key}}) {
+                            next if ($affiliation_by_table{$table} eq '');
+                            my $statement;
+                            if (ref($unamefield{$key}) eq 'HASH') {
+                                next if ($unamefield{$key}{$affiliation_by_table{$table}} eq '');
+                                $statement = 'SELECT DISTINCT '.$unamefield{$key}{$affiliation_by_table{$table}}.' FROM '.$table;
+                            } else {
+                                next if ($unamefield{$key} eq '');
+                                $statement = 'SELECT '.$unamefield{$key}.' FROM '.$table;
+                            }
+                            if (ref($idfield{$key}) eq 'HASH') {
+                                next if ($idfield{$key}{$affiliation_by_table{$table}} eq '');
+                                $statement .= ' WHERE '.$idfield{$key}{$affiliation_by_table{$table}};
+                            } else {
+                                next if ($idfield{$key} eq '');
+                                $statement .= ' WHERE '.$idfield{$key}; 
+                            }
+                            if (ref($dbh{$key})) {
+                                $statement .= '='.$dbh{$key}->quote($pid);
+                                my $sth = $dbh{$key}->prepare("$statement");
+                                $sth->execute();
+                                while ( $uname = $sth->fetchrow_array ) {
+                                    $uname = lc($uname);
+                                    last if ($stoponmatch && $matched); 
+                                    $instusers->{$uname}->{id} = $pid;
+                                    $matched = 1;
+                                }
+                                $sth->finish;
+                            }
+                            last if ($stoponmatch && $matched);
+                        }
+                    }
+                }
+                if ($uname ne '') {
+                    if (defined($instids->{$pid})) {
+                        if (ref($instids->{$pid}) eq 'ARRAY') {
+                            if (!grep(/^$uname$/,@{$instids->{$pid}})) {
+                                push(@{$instids->{$pid}},$uname);
+                            }
+                        } elsif ($instids->{$pid} ne $uname) {
+                            my $currname = $instids->{$pid};
+                            delete($instids->{$pid});
+                            $instids->{$pid} = [$currname,$uname];
+                        }
+                    } else {
+                        $instids->{$pid} = $uname;
+                    }
+                }
+            }
+            $outcome = 'ok';
+        }
+        foreach my $conn (@connected) {
+            if ($dbflag{$conn}) {
+                &disconnect_DB($dbh{$conn});
+            }
+        }
+    }
+    return $outcome;
+}
+
+sub query_user_tables {
+    my ($dbflagref,$dbhref,$srchtablesref,$affiliation_by_tableref,$instusers,
+        $instids,$lcusersref) = @_;
+    return unless ((ref($dbflagref) eq 'HASH') && (ref($dbhref) eq 'HASH') &&
+                   (ref($srchtablesref) eq 'HASH') &&(ref($instusers) eq 'HASH') &&
+                   (ref($instids) eq 'HASH'));
+    my ($outcome,$total,%users,%multipids);
+    if (ref($lcusersref) eq 'HASH') {
+        %users = %{$lcusersref};
+        $total = scalar(keys(%users));
+    }
+    return if (($total ne '') && ($total == 0));
+    if (keys(%{$dbflagref})) {
+        my %table_to_key;
+        if (ref($affiliation_by_tableref) eq 'HASH') {
+            %table_to_key = %{$affiliation_by_tableref};
+        }
+        my @order = ('hr','ro','cs');
+        foreach my $key (@order) {
+            if ($dbflagref->{$key}) {
+                foreach my $table (@{$srchtablesref->{$key}}) {
+                    my $statement;
+                    if ($key eq 'hr') {
+                        $statement = "SELECT MSUNetID,Pid,FirstName,LastName,Person_Type FROM $table";
+                    } elsif ($key eq 'ro') {
+                        if ($table eq 'RO_CLIFMS') {
+                            $statement = "SELECT DISTINCT MSUNetId,Emp_Id,PID,Name,Record_Type FROM $table WHERE (Record_Type = '1' OR Record_Type = 'PI')";
+                        } else {
+                            $statement = "SELECT DISTINCT Pilot_Id,Pid,Student_Preferred_First_Name,Student_Name FROM $table";
                         }
+                    } elsif ($key eq 'cs') {
+                        $statement = "SELECT DISTINCT CAMPUS_ID,EMPLID,INSTR_UNIV_NAME,INSTR_ROLE FROM $table";
                     }
-                    if ($pid ne $instusers->{$uname}{'id'}) {
-                        if ($instusers->{$uname}{'id'} =~ /^a\d{8}$/) {
-                            if ($pid =~ /^a\d{8}$/) {
-                                if (ref($multipids{$uname}) eq 'ARRAY') {
-                                    if (!grep(/^$pid$/,@{$multipids{$uname}})) {
-                                        push(@{$multipids{$uname}},$pid);
+                    if (ref($dbhref->{$key})) {
+                        my $sth = $dbhref->{$key}->prepare("$statement");
+                        $sth->execute();
+                        while ( my ($uname,$pid, at rest) = $sth->fetchrow_array ) {
+                            $uname = lc($uname);
+                            next if ($total && !exists($users{$uname}));
+                            $pid =~ s/^\s+|\s+$//g;
+                            my ($name,$given,$first,$middle,$last,$generation,$type);
+                            if ($key eq 'hr') {
+                                ($given,$last,$type) = @rest;
+                            } elsif ($key eq 'ro') {
+                                $name = $rest[1];
+                                $name =~ s/^\s+//;
+                                $name =~ s/\s+$//;
+                                ($last,$given) = split(/\,/,$name,2); 
+                                if ($table eq 'RO_CLIFMS') {
+                                    if ($rest[0] =~ /^Z\d{8}$/) {
+                                        $pid = $rest[0];
+                                    } elsif ($pid eq $uname) {
+                                        undef($pid);
+                                    }
+                                    if ($rest[2] eq '1' || $rest[2] eq 'PI') {
+                                        $type = 'Faculty';
                                     }
                                 } else {
-                                    @{$multipids{$uname}} = ($instusers->{$uname}{'id'},$pid);
+                                    $first = $rest[0];
+                                    $type = 'Student';
+                                }
+                            } else {
+                                $name = $rest[0];
+                                $name =~ s/^\s+//;
+                                $name =~ s/\s+$//;
+                                ($last,$given) = split(/,/,$name,2);
+                                if ($rest[2] eq 'PI') {
+                                    $type = 'Faculty';
                                 }
-                                $instusers->{$uname}{'id'} = $pid;
                             }
-                        } elsif ($instusers->{$uname}{'id'} =~ /^z\d{8}$/) {
-                            if ($pid =~ /^z\d{8}$/) {
-                                if (ref($multipids{$uname}) eq 'ARRAY') {
-                                    if (!grep(/^$pid$/,@{$multipids{$uname}})) {
-                                        push(@{$multipids{$uname}},$pid);
+                            $uname=lc($uname);
+                            if ($type eq 'Student') {
+                                $pid =~ s/^1(\d{8})$/A$1/;
+                            }
+                            $pid=lc($pid);
+                            $given =~ s/^\s+//;
+                            if ($given =~ m/\w\s+\w/) {
+                                (my $officialfirst,$middle) = split(/\s+/,$given,2);
+                                if ($first eq '') {
+                                    $first = $officialfirst;
+                                }
+                                $middle =~ s/\s+$//;
+                                unless ($type eq 'Student') {
+                                    $middle = substr($middle, 0, 1);
+                                }
+                            } elsif ($first eq '') {
+                                $first = $given;
+                            }
+                            $last =~ s/\s+$//;
+                            if ($last =~ /^([\w\s]+)\s+(II|III|IV|V|VI|VII|Jr|Sr)$/) {
+                                $last = $1;
+                                $generation = $2;
+                            }
+                            $first =~ s/\s+$//;
+                            ($first,$middle,$last) = map { ucfirst(lc($_)); } ($first,$middle,$last);
+                            if (ref($instusers->{$uname}) eq 'HASH') {
+                                unless ($type eq '') {
+                                    if (ref($instusers->{$uname}{'inststatus'}) eq 'ARRAY') {
+                                        if (!grep(/^$type$/,@{$instusers->{$uname}{'inststatus'}})) {
+                                            push(@{$instusers->{$uname}{'inststatus'}},$type);
+                                        }
                                     }
-                                } else {
-                                    @{$multipids{$uname}} = ($instusers->{$uname}{'id'},$pid);
                                 }
-                            } elsif ($pid =~ /^a\d{8}$/) {
-                                $instusers->{$uname}{'id'} = $pid;
+                                if ($pid ne $instusers->{$uname}{'id'}) {
+                                    if ($instusers->{$uname}{'id'} =~ /^a\d{8}$/) {
+                                        if ($pid =~ /^a\d{8}$/) {
+                                            if (ref($multipids{$uname}) eq 'ARRAY') {
+                                                if (!grep(/^$pid$/,@{$multipids{$uname}})) {
+                                                    push(@{$multipids{$uname}},$pid);
+                                                }
+                                            } else {
+                                                @{$multipids{$uname}} = ($instusers->{$uname}{'id'},$pid);
+                                            }
+                                            $instusers->{$uname}{'id'} = $pid;
+                                        }
+                                    } elsif ($instusers->{$uname}{'id'} =~ /^z\d{8}$/) {
+                                        if ($pid =~ /^z\d{8}$/) {
+                                            if (ref($multipids{$uname}) eq 'ARRAY') {
+                                                if (!grep(/^$pid$/,@{$multipids{$uname}})) {
+                                                    push(@{$multipids{$uname}},$pid);
+                                                }
+                                            } else {
+                                                @{$multipids{$uname}} = ($instusers->{$uname}{'id'},$pid);
+                                            }
+                                        } elsif ($pid =~ /^a\d{8}$/) {
+                                            $instusers->{$uname}{'id'} = $pid;
+                                        }
+                                    } elsif ($pid =~ /^[az]\d{8}$/) {
+                                        $instusers->{$uname}{'id'} = $pid;
+                                    } elsif ($pid =~ /^1\d{8}$/) {
+                                        $instusers->{$uname}{'id'} = $pid;
+                                    }
+                                }
+                            } else {
+                                $instusers->{$uname} = {firstname      => $first,
+                                                        middlename     => $middle,
+                                                        lastname       => $last,
+                                                        id             => $pid,
+                                                        permanentemail => $uname.'@msu.edu',
+                                                        inststatus => [$type],
+                                                       };
+                            }
+                            if (defined($instids->{$pid})) {
+                                if (ref($instids->{$pid}) eq 'ARRAY') {
+                                    if (!grep(/^$uname$/,@{$instids->{$pid}})) {
+                                        push(@{$instids->{$pid}},$uname);
+                                    }
+                                } elsif ($instids->{$pid} ne $uname) {
+                                    my $currname = $instids->{$pid};
+                                    delete($instids->{$pid});
+                                    $instids->{$pid} = [$currname,$uname];
+                                }
+                            } else {
+                                $instids->{$pid} = $uname;
                             }
                         }
+                        $sth->finish;
                     }
-                } else {
-                    $instusers->{$uname} = {firstname      => $first,
-                                            middlename     => $middle,
-                                            lastname       => $last,
-                                            id             => $pid,
-                                            permanentemail => $uname.'@msu.edu',
-                                            inststatus => [$type],
-                                         };
-                    $matched = 1;
-                }
-                if (defined($instids->{$pid})) {
-                    if (ref($instids->{$pid}) eq 'ARRAY') {
-                        if (!grep(/^$uname$/,@{$instids->{$pid}})) {
-                            push(@{$instids->{$pid}},$uname);
-                        }
-                    } elsif ($instids->{$pid} ne $uname) {
-                        my $currname = $instids->{$pid};
-                        delete($instids->{$pid});
-                        $instids->{$pid} = [$currname,$uname];
-                    }
-                } else {
-                    $instids->{$pid} = $uname;
                 }
             }
-            $sth->finish;
-            $outcome = 'ok';
-        }
-    }
-    if (($stoponmatch) && ($omitldap) && (exists($instusers->{$srchterm}))) {
-        return $outcome;
-    }
-    if ($ldapfilter ne '') {
-        my $ldapres = &ldap_search($ldapfilter,$instusers,$types);
-        if (!$dbflag) {
-            $outcome = $ldapres;
         }
+        $outcome = 'ok';
     }
     return $outcome;
 }
@@ -1554,7 +1829,7 @@
         my $mesg = $ldap->search(
                             base   => "dc=msu, dc=edu",
                             filter => $ldapfilter,
-                            attrs  => ['sn','givenName','title','uid','mail','employeeType'],
+                            attrs  => ['sn','givenName','cn','title','uid','employeeType','uidNumber'],
                           );
         if ($mesg->code) {
             $ldap->unbind;
@@ -1565,26 +1840,37 @@
         foreach my $entry ($mesg->entries) {
             my $uname = $entry->get_value('uid');
             next if ($uname eq '');
-            my $given = $entry->get_value('givenName');
-            $given =~ s/^\s+//;
-            my ($first,$middle);
-            if ($given =~ m/\w\s+\w/) {
-                $first = substr($given,0,index($given," "));
-                $middle = substr($given,index($given," ")+1);
-                $middle =~ s/^\s+//g;
-                $middle =~ s/\s+$//g;
-            } else {
-                $first = $given;
-            }
-            $first =~ s/\s+$//;
+            my $id = $entry->get_value('uidNumber');
+            my $first = $entry->get_value('givenName');
             my $last = $entry->get_value('sn');
-            my $email = $entry->get_value('mail');
-            my $type;
-            if (($entry->get_value('employeeType') eq 'Faculty') ||
-                ($entry->get_value('employeeType') eq 'Staff')) {
-                $type = $entry->get_value('employeeType');
-            } elsif ($entry->get_value('title') eq 'Student') {
+            my ($generation,$middle);
+            my $name = $entry->get_value('cn');
+            $name =~ s/^\s+|\s+$//g;
+            if ($name =~ /\Q$last\E\s+(II|III|IV|V|VI|VII|Jr|Sr)$/) {
+                $generation = $1;
+            }
+            if ($first ne '') {
+                $name =~ s/^\Q$first\E//;
+            }
+            if ($generation ne '') {
+                $name =~ s/\s+\Q$generation\E$//;
+            }
+            if ($last ne '') {
+                $name =~ s/\Q$last\E$//;
+            }
+            $name =~ s/^\s+|\s+$//g;
+            ($first,$name,$last) = map { ucfirst(lc($_)); } ($first,$name,$last);
+            my $type = $entry->get_value('employeeType');
+            unless (($type eq 'Faculty') || ($type eq 'Staff')) {
                 $type = $entry->get_value('title');
+                unless ($type eq 'Student') {
+                    undef($type);
+                }
+            }
+            if ($type eq 'Student') {
+                $middle = $name;
+            } else {
+                $middle = substr($name, 0, 1);
             }
             if (ref($types) eq 'ARRAY') {
                 if (@{$types} > 0) {
@@ -1604,10 +1890,13 @@
                 $instusers->{$uname} = {firstname      => $first,
                                         middlename     => $middle,
                                         lastname       => $last,
-                                        id             => '',
-                                        permanentemail => $email,
+                                        id             => $id,
+                                        permanentemail => $uname.'@msu.edu',
                                         inststatus     => [$type],
                                      };
+                if ($generation ne '') {
+                    $instusers->{$uname}{generation} = $generation;
+                }
             }
         }
         $ldap->unbind;
@@ -1615,6 +1904,78 @@
     return $outcome;
 }
 
+sub ldap_dump {
+    my ($instusers,$lc_users) = @_;
+    my ($outcome,$total,%users);
+    if (ref($lc_users) eq 'HASH') {
+        %users = %{$lc_users};
+        $total = scalar(keys(%users));
+    }
+    return if (($total ne '') && ($total == 0));
+    my $ldap = Net::LDAP->new( 'ldap.msu.edu' );
+    if ($ldap) {
+        $ldap->bind;
+        my $search_string = '(&(objectClass=msuPerson)(objectClass=uidPool)(sn=*))';
+        my $mesg = $ldap->search(
+                                  base   => "dc=msu, dc=edu",
+                                  filter => $search_string,
+                                  attrs  => ['uid','employeeType','title','cn','sn','givenName','uidNumber'],
+                                );
+        if ($mesg->code) {
+            $ldap->unbind;
+            return;
+        } else {
+            $outcome = 'ok';
+        }
+        my $count = 0;
+        foreach my $entry ($mesg->entries) {
+            my $uname = $entry->get_value('uid');
+            next if ($total && !$users{$uname});
+            my $id = $entry->get_value('uidNumber');
+            my $type = $entry->get_value('employeeType');
+            unless (($type eq 'Faculty') || ($type eq 'Staff')) {
+                $type = $entry->get_value('title');
+                unless ($type eq 'Student') {
+                    undef($type);
+                }
+            }
+            my $first = $entry->get_value('givenName');
+            my $last = $entry->get_value('sn');
+            my $generation;
+            my $name = $entry->get_value('cn'); 
+            $name =~ s/^\s+|\s+$//g;
+            if ($name =~ /\Q$last\E\s+(II|III|IV|V|VI|VII|Jr|Sr)$/) {
+                $generation = $1;
+            }
+            if ($first ne '') {
+                $name =~ s/^\Q$first\E//;
+            }
+            if ($generation ne '') {
+                $name =~ s/\s+\Q$generation\E$//;
+            }
+            if ($last ne '') {
+                $name =~ s/\Q$last\E$//;
+            }
+            $name =~ s/^\s+|\s+$//g;
+            my $middle = substr($name, 0, 1);
+            ($first,$middle,$last) = map { ucfirst(lc($_)); } ($first,$middle,$last);
+            $instusers->{$uname} = {firstname      => $first,
+                                    middlename     => $middle,
+                                    lastname       => $last,
+                                    id             => $id,
+                                    permanentemail => $uname.'@msu.edu',
+                                    inststatus => [$type],
+                                   };
+            if ($generation ne '') {
+                $instusers->{$uname}{generation} = $generation;
+            }
+            $count ++;
+        }
+        $ldap->unbind;
+    }
+    return $outcome;
+}
+
 sub inst_usertypes {
     my ($dom,$usertypes,$order) = @_;
     my $outcome = 'ok';
@@ -1665,8 +2026,12 @@
                               name     => 'MSU faculty/staff ID',
                               desc     => 'Letter Z or z, followed by eight digits',
                            },
+                  emplID => {
+                              name     => 'MSU faculty/staff emplID',
+                              desc     => 'Number 1, followed by eight digits',
+                            }
                  );
-    @{$rulesorder} = ('studentID','facstaffID');
+    @{$rulesorder} = ('studentID','facstaffID','emplID');
     return 'ok';
 }
 
@@ -1723,6 +2088,12 @@
                 } else {
                     $resultshash->{$item} = 0;
                 }
+            } elsif ($item eq 'emplID') {
+                if ($id =~ /^1\d{8}$/i) {
+                    $resultshash->{$item} = 1; 
+                } else {
+                    $resultshash->{$item} = 0;
+                }
             }
         }
         $outcome = 'ok';


More information about the LON-CAPA-cvs mailing list