Diff for /loncom/enrollment/localenroll.pm between versions 1.29 and 1.63

version 1.29, 2008/01/03 23:28:33 version 1.63, 2022/01/14 16:27:20
Line 24 Line 24
 #  #
 # http://www.lon-capa.org/  # http://www.lon-capa.org/
 #  #
   
   =pod
   
   =head1 NAME
   
   localenroll
   
   =head1 SYNOPSIS
   
   This is part of the LearningOnline Network with CAPA project
   described at http://www.lon-capa.org.
   
   
   =head1 NOTABLE SUBROUTINES
   
   =cut
   
 package localenroll;  package localenroll;
   
 use strict;  use strict;
   
 ################################  =pod
 # sub run  
 # set this to return 1 if you want the auto enrollment to run  =over
 #   
 # Beginning with LON-CAPA version 2.4, use of this routine is  =item run()
 # deprecated.  Whether or not Autoenroll.pl should run is set   set this to return 1 if you want the auto enrollment to run
 # by the Domain Coordinator via "Set domain configuration",  
 # provided in the Domain Management section of the Main menu.    Beginning with LON-CAPA version 2.4, use of this routine is
 ################################   deprecated.  Whether or not Autoenroll.pl should run is set
    by the Domain Coordinator via "Set domain configuration",
    provided in the Domain Management section of the Main menu. 
   
   =cut
   
 sub run() {  sub run() {
     my $dom = shift;      my $dom = shift;
     return 0;      return 0;
 }  }
   
 ################################  
 # sub fetch_enrollment  =pod
 #  
 # connects to the institutional classlist data source,  =item fetch_enrollment()
 # reads classlist data and stores in an XML file  
 # in /home/httpd/perl/tmp/   connects to the institutional classlist data source,
 #   reads classlist data and stores in an XML file
 # classlist files are named as follows:   in /home/httpd/perl/tmp/
 #  
 # DOMAIN_COURSE_INSTITUTIONALCODE_classlist.xml   classlist files are named as follows:
 #  
 # e.g., msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml   DOMAIN_COURSE_INSTITUTIONALCODE_classlist.xml
 # where DOMAIN = msu  COURSE = 43551dedcd43febmsul1   
 # INSTITUTIONALCODE = fs03nop590001    e.g., msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml
 # (MSU's course naming scheme - fs03 = Fall semester 2003, nop =   where DOMAIN = msu  COURSE = 43551dedcd43febmsul1 
 # department name, 590 = course number, 001 = section number.)   INSTITUTIONALCODE = fs03nop590001 
 #   (MSU's course naming scheme - fs03 = Fall semester 2003, nop =
 # fetch_enrollment requires three arguments -   department name, 590 = course number, 001 = section number.)
 # $dom - DOMAIN e.g., msu  
 # $affiliatesref - a reference to a hash of arrays that contains LON-CAPA    fetch_enrollment requires three arguments -
 # courses that are to be updated as keys, and institutional coursecodes    $dom - DOMAIN e.g., msu
 # contributing enrollment to that LON-CAPA course as elements in each array.   $affiliatesref - a reference to a hash of arrays that contains LON-CAPA 
 # $replyref - a reference to a hash that contains LON-CAPA courses   courses that are to be updated as keys, and institutional coursecodes 
 # that are to be updated as keys, and the total enrollment count in all    contributing enrollment to that LON-CAPA course as elements in each array.
 # affiliated sections, as determined from institutional data as hash elements.    $replyref - a reference to a hash that contains LON-CAPA courses
 #   that are to be updated as keys, and the total enrollment count in all 
 # As an example, if fetch_enrollment is called to retrieve institutional   affiliated sections, as determined from institutional data as hash elements. 
 # classlists for a single LON-CAPA course - 43551dedcd43febmsul1 which   
 # corresponds to fs03nop590, sections 001, 601 and 602 , and the course   As an example, if fetch_enrollment is called to retrieve institutional
 # also accommodates enrollment from a crosslisted course in the ost   classlists for a single LON-CAPA course - 43551dedcd43febmsul1 which 
 # department - fs03ost580002:   corresponds to fs03nop590, sections 001, 601 and 602 , and the course
 #   also accommodates enrollment from a crosslisted course in the ost
 # the affiliatesref would be a reference to %affiliates which would be:   department - fs03ost580002:
 #  
 # @{$affiliates{'43551dedcd43febmsul1'}} =   the affiliatesref would be a reference to %affiliates which would be:
 #   ("fs03nop590001","fs03nop590601","fs03nop590602","fs03ost580002");  
 #   @{$affiliates{'43551dedcd43febmsul1'}} =
 # fetch_enrollment would create four files in /home/httpd/perl/tmp/.     ("fs03nop590001","fs03nop590601","fs03nop590602","fs03ost580002");
 # msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml  
 # msu_43551dedcd43febmsul1_fs03nop590601_classlist.xml   fetch_enrollment would create four files in /home/httpd/perl/tmp/.
 # msu_43551dedcd43febmsul1_fs03nop590602_classlist.xml   msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml
 # msu_43551dedcd43febmsul1_fs03ost580002_classlist.xml   msu_43551dedcd43febmsul1_fs03nop590601_classlist.xml
 #   msu_43551dedcd43febmsul1_fs03nop590602_classlist.xml
 # In each file, student data would be stored in the following format   msu_43551dedcd43febmsul1_fs03ost580002_classlist.xml
 #   
 # <student username="smith">   In each file, student data would be stored in the following format
 #  <autharg>MSU.EDU</autharg>   
 #  <authtype>krb4</authtype>   <student username="smith">
 #  <email>smith@msu.edu</email>    <autharg>MSU.EDU</autharg>
 #  <enddate></enddate>    <authtype>krb4</authtype>
 #  <firstname>John</firstname>    <email>smith@msu.edu</email>
 #  <generation>II</generation>    <enddate></enddate>
 #  <groupID>fs03nop590001</groupID>    <firstname>John</firstname>
 #  <lastname>Smith</lastname>    <generation>II</generation>
 #  <middlename>D</middlename>    <groupID>fs03nop590001</groupID>
 #  <startdate></startdate>    <lastname>Smith</lastname>
 #  <studentID>A12345678</studentID>    <middlename>D</middlename>
 # </student>    <startdate></startdate>
 #     <studentID>A12345678</studentID>
 # with the following at the top of the file    <credits></credits>
 #<?xml version="1.0" encoding="UTF-8"?>    <inststatus></inststatus>
 #<!DOCTYPE text>   </student>
 #<students>   
 #   with the following at the top of the file
 # (all comment - #s removed)  <?xml version="1.0" encoding="UTF-8"?>
 #  <!DOCTYPE text>
 # and a closing:  <students>
 #</students>  
 #   (all comment - s removed)
 # The <startdate> and the <enddate> are the activation date and expiration date  
 # for this student's role. If they are absent, then the default access start and   and a closing:
 # default access end dates are used. The default access dates can be set when   </students>
 # the course is created, and can be modified using the Automated Enrollment  
 # Manager, or via the 'Upload a class list','Enroll a single student' or    The <startdate> and the <enddate> are the activation date and expiration date
 # 'Modify student data' utilities in the Enrollment Manager, by checking the    for this student's role. If they are absent, then the default access start and
 # 'make these dates the default for future enrollment' checkbox. If no default    default access end dates are used. The default access dates can be set when 
 # dates have been set, then the tudent role will be active immediately, and will    the course is created, and can be modified using the Automated Enrollment
 # remain active until the role is explicitly expired using ENRL -> Drop students.    Manager, or via the 'Upload a class list','Enroll a single student' or 
 # If dates are to included in the XML file, they should be in the format   'Modify student data' utilities in the Enrollment Manager, by checking the 
 # YYYY:MM:DD:HH:MM:SS (: separators required).   'make these dates the default for future enrollment' checkbox. If no default 
 #   dates have been set, then the student role will be active immediately, and will 
 # If there were 10 students in fs03nop590001, 5 students in fs03nop59o601,    remain active until the role is explicitly expired using ENRL -> Drop students. 
 # 8 students in fs03nop590602, and 2 students in fs03ost580002,   If dates are to included in the XML file, they should be in the format
 # then $$reply{'43551dedcd43febmsul1'} = 25   YYYY:MM:DD:HH:MM:SS (: separators required).
 #  
 # The purpose of the %reply hash is to detect cases where the institutional    The <credits> tag need only be used if the credits earned by the students will 
 # enrollment is 0 (most likely due to a problem with the data source).   be different from the default for the course. The course default is set when the
 # In such a case, the LON-CAPA course roster is left unchanged (i.e., no   course is created and can be modifed by a Domain Coordinator via "View or
 # students are expired, even if automated drops is enabled.   modify a course or community" on the DC's Main Menu screen.
 #   
 # fetch_enrollment should return a 0 or 1, depending on whether a connection   A value for <inststatus> should be the institutional status used for students,
 # could be established to the institutional data source.   and should be one of the types defined in the "Institutional user types"
 # 0 is returned if no connection could be made.   section in the domain config screen for:
 # 1 is returned if connection was successful   "Default authentication/language/timezone/portal/types" 
 #  
 # A return of 1 is required for the calling modules to perform LON-CAPA   If no status types are defined for the domain this tag can be omitted.
 # roster changes based on the contents of the XML classlist file(s), e,g,,   If Autoupdate.pl is enabled in your domain, updates to the institutional 
 # msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml   status set here will be updated by Autoupdate.pl, should changes occur.
 #  
 # XML classlist files are temporary. They are deleted after the enrollment    If there were 10 students in fs03nop590001, 5 students in fs03nop59o601, 
 # update process in the calling module is complete.   8 students in fs03nop590602, and 2 students in fs03ost580002,
 #   then $$reply{'43551dedcd43febmsul1'} = 25
 ################################  
    The purpose of the %reply hash is to detect cases where the institutional 
    enrollment is 0 (most likely due to a problem with the data source).
    In such a case, the LON-CAPA course roster is left unchanged (i.e., no
    students are expired, even if automated drops is enabled.
    
    fetch_enrollment should return a 0 or 1, depending on whether a connection
    could be established to the institutional data source.
    0 is returned if no connection could be made.
    1 is returned if connection was successful
   
    A return of 1 is required for the calling modules to perform LON-CAPA
    roster changes based on the contents of the XML classlist file(s), e,g,,
    msu_43551dedcd43febmsul1_fs03nop590001_classlist.xml
   
    XML classlist files are temporary. They are deleted after the enrollment 
    update process in the calling module is complete.
   
   
   =cut
   
 sub fetch_enrollment {  sub fetch_enrollment {
     my ($dom,$affiliatesref,$replyref) = @_;      my ($dom,$affiliatesref,$replyref) = @_;
Line 156  sub fetch_enrollment { Line 196  sub fetch_enrollment {
     return $okflag;      return $okflag;
 }  }
   
 ###############################  =pod
 # sub get_sections  
 #  =item get_sections()
 # This is called by the Automated Enrollment Manager interface  
 # (lonpopulate.pm) to create an array of valid sections for    This is called by the Automated Enrollment Manager interface
 # a specific institutional coursecode.   (lonpopulate.pm) to create an array of valid sections for 
 # e.g., for MSU coursecode: fs03nop590   a specific institutional coursecode.
 # ("001","601","602") would be returned   e.g., for MSU coursecode: fs03nop590
 #   ("001","601","602") would be returned
 # If the array returned contains at least one element, then   
 # the interface offerred to the course coordinator, lists   If the array returned contains at least one element, then 
 # official sections and provides a checkbox to use to   the interface offered to the course coordinator, lists
 # select enrollment in the LON-CAPA course from each official section.     official sections and provides a checkbox to use to
 #   select enrollment in the LON-CAPA course from each official section.  
 # get_sections takes two arguments - (a) the institutional coursecode  
 # (in the MSU case this is a concatenation of semester code, department   get_sections takes two arguments - (a) the institutional coursecode
 # and course number), and (b) the LON-CAPA domain that contains the course.    (in the MSU case this is a concatenation of semester code, department
 #    and course number), and (b) the LON-CAPA domain that contains the course. 
 # If there is no access to official course sections at your institution,   
 # then an empty array is returned, and the Automated Enrollment Manager   If there is no access to official course sections at your institution,
 # interface will allow the course coordinator to enter section numbers   then an empty array is returned, and the Automated Enrollment Manager
 # in text boxes.   interface will allow the course coordinator to enter section numbers
 #    in text boxes.
 ###############################   
   
   
   =cut
   
 sub get_sections {  sub get_sections {
     my ($coursecode,$dom) = @_;      my ($coursecode,$dom) = @_;
Line 187  sub get_sections { Line 230  sub get_sections {
     return @secs;      return @secs;
 }  }
   
 ###############################  =pod
 # sub new_course  
 #  =item new_course()
 # This is called by loncreatecourse.pm and   
 # lonpopulate.pm to record that fact that a new course section   This is called by loncreatecourse.pm and 
 # has been added to LON-CAPA that requires access to institutional data   lonpopulate.pm to record that fact that a new course section
 # At MSU, this is required, as institutional classlists can only made   has been added to LON-CAPA that requires access to institutional data
 # available to faculty who are officially assigned to a course.   At MSU, this is required, as institutional classlists can only made
 #    available to faculty who are officially assigned to a course.
 # The new_course subroutine is used to check that the course owner   
 # of the LON-CAPA course is permitted to access the institutional   The new_course subroutine is used to check that the course owner
 # classlist for any course sections and crosslisted classes that   of the LON-CAPA course is permitted to access the institutional
 # the course coordinator wishes to have affiliated with the course.   classlist for any course sections and crosslisted classes that
 #    the course coordinator wishes to have affiliated with the course.
 # If access is permitted, then 'ok' is returned.   
 # The course section or crosslisted course will only be added to the list of   If access is permitted, then 'ok' is returned.
 # affiliates if 'ok' is returned.   The course section or crosslisted course will only be added to the list of
 #   affiliates if 'ok' is returned.
 # new_course takes three arguments -  
 # (a) the institutional courseID (in the MSU case this is a concatenation of    new_course takes three required arguments -
 # semester code, department code, course number, and section number   (a) the institutional courseID (in the MSU case this is a concatenation of 
 # e.g., fs03nop590001).   semester code, department code, course number, and section number
 # (b) the course owner. This is the LON-CAPA username and domain of the course    e.g., fs03nop590001).
 # coordinator assigned to the course when it is first created, in the form   (b) the course owner. This is the LON-CAPA username and domain of the course 
 # username:domain   coordinator assigned to the course when it is first created, in the form
 # (c) the LON-CAPA domain that contains the course   username:domain
 #   (c) the LON-CAPA domain that contains the course
 #################################  
    new_course also takes optional fourth and fifth arguments -
    (d) the course co-owners, as a comma-separated list of username:domain for
    any co-owners.
    (e) database handle (might be set when new_course() is called by check_section
    routine within localenroll.pm).
   
   =cut
   
 sub new_course  {  sub new_course  {
     my ($course_id,$owner,$dom) = @_;      my ($course_id,$owner,$dom,$coowners) = @_;
     my $outcome = 'ok';      my $outcome = 'ok';
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub validate_courseID  
 #  =item validate_courseID()
 # This is called whenever a new course section or crosslisted course  
 # is being affiliated with a LON-CAPA course (i.e., by loncreatecourse.pm   This is called whenever a new course section or crosslisted course
 # and the Automated Enrollment Manager in lonpopulate.pm).   is being affiliated with a LON-CAPA course (i.e., by loncreatecourse.pm
 # A check is made that the courseID that the course coordinator wishes   and the Automated Enrollment Manager in lonpopulate.pm).
 # to affiliate with the course is valid according to the institutional   A check is made that the courseID that the course coordinator wishes
 # schedule of official classes    to affiliate with the course is valid according to the institutional
 #   schedule of official classes 
 # A valid courseID is confirmed by returning 'ok'  
 #   A valid courseID is confirmed by returning 'ok'
 # validate_courseID takes two arguments -  
 # (a) the institutional courseID (in the MSU case this is a concatenation of   validate_courseID takes two arguments -
 # semester code, department code, course number, and section number   (a) the institutional courseID (in the MSU case this is a concatenation of
 # e.g., fs03nop590001).   semester code, department code, course number, and section number
 # (b) the LON-CAPA domain that contains the course   e.g., fs03nop590001).
 #   (b) the LON-CAPA domain that contains the course
 ###############################    
   =cut  
   
 sub validate_courseID {  sub validate_courseID {
     my ($course_id,$dom) = @_;      my ($course_id,$dom) = @_;
Line 248  sub validate_courseID { Line 299  sub validate_courseID {
     return $outcome;         return $outcome;   
 }  }
   
 ###############################  =pod
 # sub create_password   
 #  =item validate_instcode()
 # This is called when the authentication method set for the automated   
 # enrollment process when enrolling new users in the domain is "localauth".  This is called when a request is being made for an official course.
 # This could be signalled for the specific user by the value of localauth  A check is made that the institutional code for which a course is
 # for the <authtype> tag from the classlist.xml files, or if this is blank,  is being requested is valid according to the institutional
 # the default authtype, set by the domain coordinator when creating the course  schedule of official classes.
 # with loncreatecourse.pm.  
 #    If the username of the course owner is provided, a more restrictive
 # create_password takes three arguments -  test is used, namely that the requestor is listed as instructor of
 # (a) $authparam - the value of <autharg> from the classlist.xml files,  record for the course in the institution's course schedule/database.
 # or if this blank, the default autharg, set by the domain coordinator when   
 # creating the course with loncreatecourse.pm  validate_instcode takes three arguments -
 # (b) $dom - the domain of the new user.   (a) the LON-CAPA domain that will contain the course
 # (c) $username - the username of the new user (currently not actually used)   (b) the institutional code (in the MSU case this is a concatenation of
 #   semester code, department code, and course number, e.g., fs03nop590.
 # Four values are returned:   (c) an optional institutional username for the course owner.
 # (a) the value of $authparam - which might have been changed  
 # (b) a flag to indicate whether a password had been created  An array is returned containing (a) the result of the check for a valid 
 # 0 means no password created  instcode, (b) an (optional) course description, and (c) the default credits
 # 1 means password created.  In this case the calling module - Enrollment.pm  earned by students when completing this course. If no institutional credits
 # will send the LON-CAPA username and password to the new user's e-mail  value is available, the default credits for the course can be set via the
 # (if one was provided), or to the course owner (if one was not provided and  course request form, or via XML in a batch file, of via the web form used
 # the new user was created by the automated process), or to the active  by the Domain Coordinator to create new courses one at a time.
 # course coordinator (if the new user was created using the 'update roster  
 # now' interface included in the Automated Enrollment Manager).    A valid instcode is confirmed by returning 'valid'.
 # (c) a flag to indicate that the authentication method is correct - 'ok'.  
 # If $authchk is not set to 'ok' then account creation and enrollment of the   If no course description is available, '' should be set as
 # new user will not occur.  the value of the second item in the returned array.
 # (d) if a password was created it can be sent along.  This is the password   
 # which will be included in the e-mail sent to the new user, or made available      =cut
 # to the course owner/course coordinator if no e-mail address is provided. If  
 # you do not wish to send a password, but want to give instructions on obtaining  sub validate_instcode {
 # one, you could set $newpasswd as those instructions. (e.g.,      my ($dom,$instcode,$owner) = @_;
 # $newpasswd = '(Please visit room 212, ACNS Bldg. to obtain your password)';      my $outcome = '';
 # The value of $newpasswd is NOT written in the user's LON-CAPA passwd file in      my $description = '';
 # /home/httpd/lonUsers/$dom/a/b/c/abcuser/passwd, which in the case of a user      my $credits = '';
 # employing localauth will contain 'localauth:$authparam'.  If you need to include      return ($outcome,$description,$credits);
 # a parameter in the user's passwd file, you should return it as $authparam,  }
 # i.e., the first of the variables returned by create_password().               
 ###############################  =pod
   
   =item validate_crosslist_access()
   
   This is called for an official course to check whether a course
   with the institutional code can have access to enrollment data
   from a cross-listed institutional section code, given a co-owner.
   
   validate_crosslist_access() takes four arguments -
   (a) the course's LON-CAPA domain 
   (b) the institional course code assigned to the course
   (c) the institutional course section code for the crosslisting
   (d) the co-owner to check for affiliation with the crosslisting 
       (username:domain).
   
   A combination of (a), (b), (c) and (d) with access to enrollment 
   data, as per institutional policies, is confirmed by returning 'valid'.
   
   =cut
   
   sub validate_crosslist_access {
       my ($dom,$instcode,$inst_xlist,$coowner) = @_;
       my $outcome = '';
       return $outcome;
   }
   
   =pod
   
   =item validate_crsreq()
   
   This is used to check whether a course request should be processed
   automatically, or held in a queue pending administrative action at
   the institution.
   
   Course requests will trigger this check if the process type has been set 
   to 'validate' for the course type (official, unofficial, textbook, 
   placement or community) and the requestor's affiliation.  Whether
   "validate" is an available option in the Domain Configuration menu 
   is controlled by auto_courserequest_checks(). 
   One scenario is where the request is for an official course, in which case
   a check could be made that the requestor is listed as instructor of 
   record for the course in the institution's course schedule/database.
   
   Other scenarios are possible, and the routine can be customized according
   to whatever rules a domain wishes to implement to run validations against
   given the data passed in to the routine.
   
   validate_crsreq takes seven arguments -
    (a) the LON-CAPA domain that will contain the course.
    (b) the username:domain for the course owner.
    (c) the course type (official, unofficial,textbook, placement or community)
    (d) a comma-separated list of institutional affiliations of 
        the course owner.
    (e) the institutional code (in the MSU case this is a concatenation of
    semester code, department code, and course number, e.g., fs03nop590).
    (f) a comma-separated list of institutional sections included in
        the course request (only applicable to official courses).
    (g) an optional reference to a hash of custom form data.
        The custom form data will come from crsreq_updates(), with one
        additional item: $custominfo->{'_LC_clonefrom'}, provided internally
        (the courseID of the LON-CAPA course being cloned).
   
   A valid courserequest is confirmed by returning 'process'.
   The following can be returned: process, rejected, pending, approval or 
   error (with error condition - no :), followed by a : and then an optional message. 
   
   (a) process  - the requestor is the recorded instructor - create the course
   
   (b) rejected - the requestor should never be requesting this course, reject the
       request permanently
   
   (c) pending - the requestor is not the recorded instructor, but could
       become so after administrative action at the institution. Put the
       request in a queue and, if an official course, check 
       localenroll:validate_instcode() periodically until the status changes to 
       "valid".
   
   (d) approval - the request will be held pending review by a Domain Coordinator.
   
   (e) error (followed by the error condition).
   
   =cut
   
   sub validate_crsreq {
       my ($dom,$owner,$crstype,$inststatuslist,$instcode,$instseclist,$custominfo) = @_;
       my $outcome = 'approval';
       return $outcome;
   }
   
   =pod 
   
   =item crsreq_checks()
   
   This is used to determine whether the "validate" option should appear in the
   possible choices for course request processing in the Domain Configuration 
   menu for Course Requests. Ultimately it is called by domainprefs.pm (via: 
   lonnet -> lond -> localenroll.pm) The domain configuration menu includes 
   a table where columns are course type (official, unofficial, textbook,
   placement or community) and rows are institutional affiliations 
   (e.g., Faculty, Staff, Student etc.).
   
   crsreq_checks() takes three arguments: $dom, $reqtypes, $validations.
   $dom - the domain for which validation options are needed.
   $reqtypes - ref to an ARRAY of course types (i.e., official, unofficial and community.
   $validations - ref to a hash of a hash which will determine whether "validate"
   will be one of the possible choices for each course type (outer hash key),
   and institutional type (inner hash key).
   
   For example to allow validate to be a choice for official classes for Faculty,
   req_checks would include:
   
   $validations{'official'}{'Faculty'} = 1;
   
   This routine is closely tied to validate_crsreq(). "Validate" should not be
   a possible choice in the domain configuration menu for a particular course
   type/institutional affiliation, unless a corresponding validation code has
   been implemented in validate_crsreq().
   
   For example at MSU, official courses requested by Faculty will be validated
   against the official schedule of classes to check that the requestor is one
   of the instructors of record for the course.  In this case validate_crsreq()
   includes a call to validate_instcode().
   
   =cut
   
   sub crsreq_checks {
       my ($dom,$reqtypes,$validations) = @_;
       if ((ref($reqtypes) eq 'ARRAY') && (ref($validations) eq 'HASH')) {
           my (%usertypes,@order);
           if (&inst_usertypes($dom,\%usertypes,\@order) eq 'ok') {
               foreach my $type (@{$reqtypes}) {
                   foreach my $inst_type (@order) {
                       $validations->{$type}{$inst_type} = 0;
                   }
               }
           }
       }
       return 'ok';
   }
   
   =pod
   
   =item crsreq_updates()
   
   This is used to customize the LON-CAPA course request process.
   There are two hash references: $incoming, and $outgoing; $incoming can
   contain additional information collected from the requester, whereas $outgoing
   can contain custom items to send back to lonrequestcourse.pm, which creates the
   HTML displayed to the user during a course request.
   
   Different key-value pairs may be returned to lonrequestcourse.pm in the $outgoing
   hashref depending on the current action.  The available actions are:
   review, prevalidate, process, created and queued.
   
   One scenario would be to return HTML markup in: $outgoing->{'reviewweb'},
   i.e., where the action is 'review', to prompt the user to provide additional
   information as part of the course request, at the request review stage, 
   (i.e,, the page which contains the button used to submit a completed course request).
   
   The HTML could contain form elements (e.g., radio buttons etc.). The value(s)
   selected by the requester in those form elements will be available in the incoming
   hashref, for a subsequent action, if the corresponding keys have been included
   in $outgoing->{'formitems'}, i.e., $outgoing will be hash of a hash.  If a
   particular form item will the single valued, the value set for the key in the 
   inner hash in $outgoing should be 1, otherwise, if it will be multi-valued,
   the value should be multiple.
   
   The $outgoing hashref can contain a 'formitems' key for both the prevalidate
   and process actions, as calls to localenroll::crsreq_update() can originate
   in lonrequestcourse::process_request() for both of those actions.
   
   The retrieved form values are passed to localenroll::validate_crsreq() as the
   optional seventh arg (a hashref) -- $custominfo.
   
   =cut
   
   sub crsreq_updates {
       my ($cdom,$cnum,$crstype,$action,$ownername,$ownerdomain,$fullname,$title,
           $code,$accessstart,$accessend,$incoming,$outgoing) = @_;
       unless (ref($outgoing) eq 'HASH') {
           return 'fail';
       }
       my %extrainfo;
       if (ref($incoming) eq 'HASH') {
           %extrainfo = %{$incoming};
       }
       if ($action eq 'review') {
           $outgoing->{'reviewweb'} = '';
       } elsif ($action eq 'prevalidate') {
           $outgoing->{'formitems'} = {}; # key=>value, where key is form element name
                                          #             and value is multiple, if there
                                          #             are multiple form elements with
                                          #             the same name.
       } elsif ($action eq 'process') {
           $outgoing->{'formitems'} = {}; # key=>value, where key is form element name
                                          #             and value is multiple, if there
                                          #             are multiple form elements with
                                          #             the same name.
       } elsif ($action eq 'created') {
           $outgoing->{'createdweb'} = '';
           $outgoing->{'createdmsg'} = [{
                                        mt => '',
                                        args => [],
                                       }];
           $outgoing->{'createdactions'} = {
                                               environment => {},
                                           };
                                           # environment can contain key=>value for
                                           # items to set in the course environment.
                                           # These would be items which are NOT included
                                           # in the items set via options in the course
                                           # request form. Currently self-enrollment
                                           # settings are the only ones allowed, i.e.,
                                           # internal.selfenroll_types internal.selfenroll_registered
                                           # internal.selfenroll_section internal.selfenroll_start_access 
                                           # internal.selfenroll_end_access internal.selfenroll_limit
                                           # internal.selfenroll_cap internal.selfenroll_approval
                                           # internal.selfenroll_notifylist
       } elsif ($action eq 'queued') {
           $outgoing->{'queuedmsg'} = [{
                                        mt   => '',
                                        args => [],
                                       }];
           $outgoing->{'queuedweb'} = '';
       }
       return 'ok'
   }
   
   =pod
   
   =item export_grades()
    
   This routine can be customized to push grade information to some other gradebook,
   LCMS, or administrative system external to LON-CAPA.
   
   export_grades() takes five arguments -
   (a) the LON-CAPA course ID
   (b) the LON-CAPA course domain
   (c) a hash reference containing the following: 
       scope    => scope of the grades (e.g., course, map or resource).
       instcode => institutional course code (if an official course)
       crstype  => course type -- Course, Community or Placement
       context  => calling context, e.g., "completion" when a student completes a placement test.
   (d) a perl data structure (hash of a hash) containing the grade data.
       in the outer hash, the keys are student's username:domain
       in the inner hash, keys are:  
       id        => student/employee ID
       lastname  => student's last name
       firstname => student's first name
       email     => student's "permannent" e-mail address
       section   => student's LON-CAPA course section
       total     => total points earned
       bytitle   => reference to a hash (keys are question titles, values are points
       bysymb    => reference to a hash (keys are symbs, i.e., unique resource identifiers).
   (e) reference to a hash which will contain information to return.
       keys will be the student's username:domain. Value of 1 to show grades pushed 
       successfully. 
   
   =cut
   
   sub export_grades {
       my ($cnum,$cdom,$hashref,$dataref,$outgoing) = @_;
       my %info;
       if (ref($hashref) eq 'HASH') {
           %info = %{$hashref};
       }
       if ((ref($dataref) eq 'HASH') && (ref($outgoing) eq 'HASH')) {
           foreach my $key (keys(%{$dataref})) {
               $outgoing->{$key} = 1;
           }
           return 'ok';
       } else {
           return 'error';
       }
   }
   
   =pod
   
   =item check_instclasses()
   
    This is used to supply information about which instituional course sections
    and cross-listings are available to supply enrollment data, given the current
    list of owner and co-owners. The data are used to populate the column titled:
    "Auto-enrollment of registered students" when showing full detailed for a course
    in the course catalog.
   
    This subroutine takes four arguments -
   
    (a) $owners - comma-separated list of username:domain for course owner 
        and co-owners.
    (b) $dom - domain of course.
    (c) $classes - reference to hash of institutional course sections and
        crosslistings for which access to enrollment data is being checked.
    (d) $validated - reference to hash which will be populated with all
        keys from incoming $classes hashref, for which one or more of the
        owner/co-owners has rights to access enrollment data. For each
        key included in $validated hashref, corresponding value will be set to 1.
     
    The subroutine returns 'ok' if there is no processing error.
   
   =cut
   
   
   sub check_instclasses {
       my ($owners,$dom,$classes,$validated) = @_;
       if ((ref($classes) eq 'HASH') && (ref($validated) eq 'HASH')) {
           foreach my $class (keys(%{$classes})){
               if (&check_section($class,$owners,$dom) eq 'ok') {
                   $validated->{$class} = 1;
               }
           }
       }
       return 'ok';
   }
   
   =pod
   
   =item instsec_reformat()
   
    Inputs: $dom, $action, $instsecref
   
    $dom is the course's domain
    $action is either: clutter or declutter
    $instsecref is a reference to a hash, in which each key is
    course num:course code, and each value is either an array of 
    institutional sections, or (in the case of crosslisted courses)
    an array of institutional course sections.
   
    Returns: ok
   
    Side effects: will modify the items in the array as determined by
    code implemented for the domain.  Modification will differ depending
    on whether the action is clutter or declutter.
   
    The idea is that "clutter" will modify the name of the section such
    that a concatenation of institutional code then (modified) section
    will result in a string that other customized routines in localenroll.pm
    can separate without ambiguity into instituional code then (real)
    institutional section using a regular expression.
   
    Conversely, "declutter" will modify the name of an already modified
    item such that display of the concatenated string (e.g., for a 
    crosslisting in the course catalog) does not include the "added"
    characters used to eliminate ambiguity. 
   
    Examples (MSU):
   
    Starting in Fall 2021 at MSU, institution section numbers are no
    longer guaranteed to be three digit numbers (including leading zeroes).
   
    So, for example the course code: fs21phy183b might have sections:
    001, 002, LEC1, LEC2, and be crosslisted with fs21phy233b (with 
    sections: 730, LEC3, LEC4).
   
    The sections: LEC1, and LEC2 should be changed to _LEC1, and _LEC2
    before creating the inner keys in the %affiliates hash of a hash,
    passed to fetch_enrollment() in Enrollment.pm.  They will however
    be stored in the course's environment as LEC1 and LEC2.
   
    For the crosslistings, LEC3 and LEC4 should be changed to 
    _LEC3 and _LEC4 before storing in the course's environment.db file.
   
    In both cases when it comes time to extract the various components
    of an institutional section code (i.e., the concatenated string) in
    fetch_enrollment(), for example, the regexp used at MSU would be:
    
    if ($class =~ m/^([suf]s)(\d{2})(\w{2,4})(\d{3,4}[A-Za-z]?)(\d{3}|_[A-Za-z0-9]{1,5})$/) {
        my ($sem,$yr,$subj,$crse,$sec) = ($1,$2,$3,$4,$5);
   
    The three digit sections would match the \d{3} and the other sections
    (LEC1, LEC2 etc.) would match the _[A-Za-z0-9]{1,5}.
   
    The customization in &instsec_reformat() would be:
   
        if ($action eq 'clutter') {
            unless ($item =~ /^\d{3}$/) {
                $item = '_'.$item;
            }
        } elsif ($action eq 'declutter') {
            if ($item =~ /^([suf]s\d{2}\w{2,4}\d{3,4}[A-Za-z]?)(\d{3}|_[A-Za-z0-9]{1,5})$/) {
                my ($instcode,$instsec) = ($1,$2);
                $instsec =~ s/^_//;
                $item = $instcode.$instsec;
            } elsif ($item =~ /^_[A-Za-z0-9]{1,5}$/) {
                $item =~ s/^_//;
            }
        }
   
   =cut
   
   sub instsec_reformat {
       my ($dom,$action,$instsecref) = @_;
       if ((ref($instsecref) eq 'HASH') &&
           (($action eq 'clutter') || ($action eq 'declutter'))) {
           foreach my $key (keys(%{$instsecref})) {
               if (ref($instsecref->{$key}) eq 'ARRAY') {
                   foreach my $sec (@{$instsecref->{$key}}) {
                       if ($action eq 'clutter') {
                           # modify the section, as needed.
                           next;
                       } elsif ($action eq 'declutter') {
                           # modify the section, as needed.
                           next;
                       }
                   }
               }
           }
       }
       return 'ok';
   }
   
   =pod
   
   =item create_password()
   
    This is called when the authentication method set for the automated 
    enrollment process when enrolling new users in the domain is "localauth".
    This could be signalled for the specific user by the value of localauth
    for the <authtype> tag from the classlist.xml files, or if this is blank,
    the default authtype, set by the domain coordinator when creating the course
    with loncreatecourse.pm.
     
    create_password takes three arguments -
    (a) $authparam - the value of <autharg> from the classlist.xml files,
    or if this blank, the default autharg, set by the domain coordinator when 
    creating the course with loncreatecourse.pm
    (b) $dom - the domain of the new user.
    (c) $username - the username of the new user (currently not actually used)
   
    Four values are returned:
    (a) the value of $authparam - which might have been changed
    (b) a flag to indicate whether a password had been created
    0 means no password created
    1 means password created.  In this case the calling module - Enrollment.pm
    will send the LON-CAPA username and password to the new user's e-mail
    (if one was provided), or to the course owner (if one was not provided and
    the new user was created by the automated process), or to the active
    course coordinator (if the new user was created using the 'update roster
    now' interface included in the Automated Enrollment Manager).  
    (c) a flag to indicate that the authentication method is correct - 'ok'.
    If $authchk is not set to 'ok' then account creation and enrollment of the 
    new user will not occur.
    (d) if a password was created it can be sent along.  This is the password 
    which will be included in the e-mail sent to the new user, or made available    
    to the course owner/course coordinator if no e-mail address is provided. If
    you do not wish to send a password, but want to give instructions on obtaining
    one, you could set $newpasswd as those instructions. (e.g.,
    $newpasswd = '(Please visit room 212, ACNS Bldg. to obtain your password)';
    The value of $newpasswd is NOT written in the user's LON-CAPA passwd file in
    /home/httpd/lonUsers/$dom/a/b/c/abcuser/passwd, which in the case of a user
    employing localauth will contain 'localauth:$authparam'.  If you need to include
    a parameter in the user's passwd file, you should return it as $authparam,
    i.e., the first of the variables returned by create_password().             
   
   
   =cut 
   
 sub create_password {  sub create_password {
     my ($authparam,$dom,$username) = @_;      my ($authparam,$dom,$username) = @_;
Line 299  sub create_password { Line 805  sub create_password {
     return ($authparam,$create_passwd,$authchk,$newpasswd);      return ($authparam,$create_passwd,$authchk,$newpasswd);
 }  }
   
 ###############################  =pod
 # sub instcode_format   
 #  =item instcode_format()
 # Split coursecodes into constituent parts.     
 # e.g., INSTITUTIONALCODE = fs03nop590, LON-CAPA COURSEID: 43551dedcd43febmsul1   Split coursecodes into constituent parts.   
 # (MSU's course naming scheme - fs03 = Fall semester 2003, nop =   e.g., INSTITUTIONALCODE = fs03nop590, LON-CAPA COURSEID: 43551dedcd43febmsul1
 # department name, 590 = course number)   (MSU's course naming scheme - fs03 = Fall semester 2003, nop =
 #   department name, 590 = course number)
 # Incoming data:  
 # $dom (domain)   Incoming data:
 # $$instcodes{'43551dedcd43febmsul1'} = 'fs03nop590' (hash of courseIDs)   $dom (domain)
 #    $$instcodes{'43551dedcd43febmsul1'} = 'fs03nop590' (hash of courseIDs)
 # fs03nop590 would be split as follows   
 # @{$codetitles} = ("year","semester","department","number")   fs03nop590 would be split as follows
 # $$codes{{'year'} = '2003'   @{$codetitles} = ("year","semester","department","number")
 # $$codes{'semester'} = 'Fall'   $$codes{'year'} = '2003'
 # $$codes{'department'} = 'nop'   $$codes{'semester'} = 'Fall'
 # $$codes{'number'} = '590'   $$codes{'department'} = 'nop'
 #   $$codes{'number'} = '590'
 # requires six arguments:  
 # domain ($dom)   requires six arguments:
 # reference to hash of institutional course IDs ($instcodes)     domain ($dom)
 # reference to hash of codes ($codes)   reference to hash of institutional course IDs ($instcodes)  
 # reference to array of titles ($codetitles)   reference to hash of codes ($codes)
 # reference to hash of abbreviations used in categories   reference to array of titles ($codetitles)
 # reference to hash of arrays specifying sort order used in category titles      reference to hash of abbreviations used in categories
 #   reference to hash of arrays specifying sort order used in category titles   
 # e.g.,     %{$$cat_titles{'Semester'}} = (  
 #                   fs => 'Fall',   e.g.,     %{$$cat_titles{'Semester'}} = (
 #                   ss => 'Spring',                     fs => 'Fall',
 #                   us => 'Summer');                     ss => 'Spring',
 #                     us => 'Summer');
 # e.g., @{$$cat_order{'Semester'}} = ('ss','us','fs');   
 # returns 1 parameter: 'ok' if no processing errors.     e.g., @{$$cat_order{'Semester'}} = ('ss','us','fs'); 
 ###############################   returns 1 parameter: 'ok' if no processing errors. 
   
    Detailed help:
    http://yourloncapaserver/adm/help/Institutional_Integration_Course_Codes.hlp
   
   =cut
   
   
 sub instcode_format () {  sub instcode_format () {
     my ($dom,$instcodes,$codes,$codetitles,$cat_titles,$cat_order) = @_;      my ($dom,$instcodes,$codes,$codetitles,$cat_titles,$cat_order) = @_;
Line 341  sub instcode_format () { Line 853  sub instcode_format () {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub institutional_photos  
 #  =item possible_instcodes()
 # Called when automated enrollment manager is used to update student photos.  
 #  Gather acceptable values for institutional categories to use in course creation request form for official courses.
 # Incoming data: six arguments  
 # (a) $dom (domain)   requires five arguments:
 # (b) $crs (LONCAPA course number)  
 # (c) $affiliates: a reference to a hash with the keys set to the    domain ($dom)
 # institutional course IDs for the course.   reference to array of titles ($codetitles)
 # (d) $result: a reference to a hash which will return usernames     reference to hash of abbreviations used in categories ($cat_titles).
 #     of students (& separated) in following categories (the keys):   reference to hash of arrays specifying sort order used in 
 #     new, update, missing, same, deleted, noid, nouser. The list              category titles ($cat_order).
 #     includes those students for whom the result of the modification    reference to array which will contain order of component parts used 
 #     process was either addition of a new photo. update of an             in institutional code ($code_order).
 #     existing photo, photo was found to be missing from institution's  
 #     data store, photo used is same as before, or photo was    e.g., 
 #     deleted from storage on LON-CAPA server housing student's   @{$codetitles} = ('Year','Semester',"Department','Number');
 #     information, no student ID was available.   
    %{$$cat_titles{'Semester'}} = (
                      fs => 'Fall',
                      ss => 'Spring',
                      us => 'Summer');
   
    @{$$cat_order{'Semester'}} = ('ss','us','fs');
    @{$code_order} = ('Semester','Year','Department','Number');
   
    returns 1 parameter: 'ok' if no processing errors.
   
   =cut
   
   sub possible_instcodes {
       my ($dom,$codetitles,$cat_titles,$cat_order,$code_order) = @_;
       @{$codetitles} = ();
       %{$$cat_titles{'Semester'}} = ();
       @{$$cat_order{'Semester'}} = ('ss','us','fs');
       @{$code_order} = ();
       return 'ok';
   }
   
   
   =pod
   
   =item institutional_photos()
   
    Called when automated enrollment manager is used to update student photos.
   
    Incoming data: six arguments
    (a) $dom (domain)
    (b) $crs (LONCAPA course number)
    (c) $affiliates: a reference to a hash with the keys set to the 
    institutional course IDs for the course.
    (d) $result: a reference to a hash which will return usernames  
        of students (& separated) in following categories (the keys):
        new, update, missing, same, deleted, noid, nouser. The list 
        includes those students for whom the result of the modification 
        process was either addition of a new photo. update of an
        existing photo, photo was found to be missing from institution's
        data store, photo used is same as before, or photo was 
        deleted from storage on LON-CAPA server housing student's
        information, no student/employee ID was available. 
                                 
 # (e) $action: the type of action needed. (e.g., update, delete);   (e) $action: the type of action needed. (e.g., update, delete);
 # (f) $students: a reference to a hash with the keys set to student    (f) $students: a reference to a hash with the keys set to student 
 # usernames and domains in the form username:domain, and values set   usernames and domains in the form username:domain, and values set
 # to the studentID, if action is required for specific students.     to the studentID, if action is required for specific students.  
 #  
 # returns 1 parameter: 'ok' if no processing errors.   returns 1 parameter: 'ok' if no processing errors.
 # other course or student specific values can be stored as values   other course or student specific values can be stored as values
 # in the appropriate referenced hashes.    in the appropriate referenced hashes. 
 ###############################  
   =cut
   
 sub institutional_photos {  sub institutional_photos {
     my ($dom,$crs,$affiliates,$result,$action,$students) = @_;      my ($dom,$crs,$affiliates,$result,$action,$students) = @_;
Line 377  sub institutional_photos { Line 932  sub institutional_photos {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub photo_permission  
 #  =item photo_permission()
 # Incoming data: three arguments  
 # (a) $dom (domain)   Incoming data: three arguments
 # (b) $perm_reqd: a reference to a a scalar that is either 'yes'   (a) $dom (domain)
 # if a course owner must indicate acceptance of conditions of use,   (b) $perm_reqd: a reference to a a scalar that is either 'yes'
 # 'no' otherwise.   if a course owner must indicate acceptance of conditions of use,
 # (c) $conditions: the text of the conditions of use.   'no' otherwise.
 #       (c) $conditions: the text of the conditions of use.
 # returns 1 parameter: 'ok' if no processing errors.      
 # $$perm_reqd is set to 'yes' or 'no'   returns 1 parameter: 'ok' if no processing errors.
 # $$agreement is set to conditions of use - plain text string   $$perm_reqd is set to 'yes' or 'no'
 #             which will be displayed in a textarea in a web form.   $$agreement is set to conditions of use - plain text string
 ###############################               which will be displayed in a textarea in a web form.
    
   
   =cut
   
 sub photo_permission {  sub photo_permission {
    my ($dom,$perm_reqd,$conditions) = @_;     my ($dom,$perm_reqd,$conditions) = @_;
    $$perm_reqd = 'no';     $$perm_reqd = 'no';
Line 401  sub photo_permission { Line 959  sub photo_permission {
    return $outcome;     return $outcome;
 }  }
   
   =pod
   
 ###############################  =item manager_photo_update()
 # sub manager_photo_update  
 #   Incoming data: one argument
 # Incoming data: one argument   (a) $dom (domain)
 # (a) $dom (domain)  
 #   returns 2 parameters: update (0 or 1), and comment.
 # returns 2 parameters: update (0 or 1), and comment.   Called by automated enrollment manager, to determine 
 # Called by automated enrollment manager, to determine    whether "Update Student photos" button will be available,
 # whether "Update Student photos" button will be available,   and if so, the message (plain text string) that will be displayed
 # and if so, the message (plain text string) that will be displayed   with the button. 
 # with the button.   
 ###############################  
   =cut
                                                                                                                                                                                   
 sub manager_photo_update {  sub manager_photo_update {
     my ($dom) = @_;      my ($dom) = @_;
Line 422  sub manager_photo_update { Line 982  sub manager_photo_update {
     return ($update,$comment);      return ($update,$comment);
 }  }
   
 ###############################  =pod
 # sub check_section  
 #  
 # Incoming data: three arguments (+ fourth optional argument)  =item check_section()
 # (a) $class - institutional class id (coursecode concatanated with section)   
 # (b) $owner - course owner (2.2 and later username:domain; pre-2.2 username;   Incoming data: three arguments (+ fourth optional argument)
 #                            2.6 and later - comma-separated list of    (a) $class - institutional class id (coursecode concatanated with section) 
 #                            username:domain for course owner and co-owners.)   (b) $owner - course owner (2.2 and later username:domain; pre-2.2 username;
 # (c) $dom - domain of course                              2.6 and later - comma-separated list of 
 # (d) $dbh - optional database handle                              username:domain for course owner and co-owners.)
 #   (c) $dom - domain of course
 # returns 1 parameter - $sectioncheck ('ok' or other value).    (d) $dbh - optional database handle
 # Verifies that at least one of the course owner (or co-owners) have access   
 # to classlist for specific class according to institution's SIS   returns 1 parameter - $sectioncheck ('ok' or other value). 
 # 'ok' if access available     Verifies that at least one of the course owner (or co-owners) have access 
 ###############################   to classlist for specific class according to institution's SIS
    'ok' if access available  
   
   
   =cut
   
 sub check_section {  sub check_section {
     my ($class,$owner,$dom,$dbh) = @_;      my ($class,$owner,$dom,$dbh) = @_;
Line 445  sub check_section { Line 1009  sub check_section {
     return $sectioncheck;      return $sectioncheck;
 }  }
   
 ###############################  =pod
 # sub instcode_defaults  
 #  =item instcode_defaults()
 # Incoming data: three arguments  
 # (a) $dom - domain   Incoming data: three arguments
 # (b) $defaults - reference to hash which will contain default regular   (a) $dom - domain
 #                 expression matches for different components of an    (b) $defaults - reference to hash which will contain default regular
 #                 institutional course code                    expression matches for different components of an 
 # (c) $code_order - reference to array which will contain order of                    institutional course code 
 #                   component parts used in institutional code.     (c) $code_order - reference to array which will contain order of 
 #                     component parts used in institutional code.  
 # returns 1 parameter - ('ok' or other value).  
 # Used to construct a regular expression to be used when searching for   returns 1 parameter - ('ok' or other value).
 # courses based on fragments of an institutional code.   Used to construct a regular expression to be used when searching for
 # $defaults contains defaults to use for each component, and code_order   courses based on fragments of an institutional code.
 # contains keys of hash in order in which they are to be concatenated.   $defaults contains defaults to use for each component, and code_order
 #   contains keys of hash in order in which they are to be concatenated.
 # e.g., INSTITUTIONALCODE = fs03nop590  
 # (MSU's course naming scheme - fs  = semester, 03 = year, nop =   e.g., INSTITUTIONALCODE = fs03nop590
 # department name, 590 = course number)   (MSU's course naming scheme - fs  = semester, 03 = year, nop =
 #   department name, 590 = course number)
 #     %{$defaults} = (  
 #        'Year' => '\d{2}',       %{$defaults} = (
 #        'Semester' => '^[sfu]s',           'Year' => '\d{2}',
 #        'Department' => '\w{2,3}',          'Semester' => '^[sfu]s', 
 #        'Number' => '\d{3,4}\w?',          'Department' => '\w{2,3}',
 #     );          'Number' => '\d{3,4}\w?',
 #       );
 #     @{$code_order} = ('Semester','Year','Department','Number');  
 #       @{$code_order} = ('Semester','Year','Department','Number');
 ###############################  
    Detailed help:
    http://yourloncapaserver/adm/help/Institutional_Integration_Course_Codes.hlp
   
   =cut
   
 sub instcode_defaults {  sub instcode_defaults {
     my ($dom,$defaults,$code_order) = @_;      my ($dom,$defaults,$code_order) = @_;
     return 'ok';      return 'ok';
 }  }
   
 ###############################  
 # sub allusers_info  =pod
 #  
 # Incoming data: three arguments  =item allusers_info()
 # (a) $dom - domain  
 # (b) $instusers - reference to hash which will contain hashes,    Incoming data: three arguments
 #                 where keys will be usernames and value will be a    (a) $dom - domain
 #                 hash of user information. Keys in the inner hash    (b) $instusers - reference to hash which will contain hashes, 
 #                 will be some or all of: lastname,firstname,                   where keys will be usernames and value will be a 
 #                 middlename, generation, id, inststatus -                    hash of user information. Keys in the inner hash 
 #                 institutional status (e.g., faculty,staff,student)                   will be some or all of: lastname,firstname,
 #                 Values are all scalars except inststatus,                   middlename, generation, id, inststatus - 
 #                 which is an array.                   institutional status (e.g., faculty,staff,student)
 # (c) $instids - reference to hash which will contain ID numbers.                    Values are all scalars except inststatus,
 #                keys will be unique IDs (student or faculty/staff ID)                   which is an array.
 #                values will be either: scalar (username) or an array    (c) $instids - reference to hash which will contain ID numbers. 
 #                if a single ID matches multiple usernames.                  keys will be unique IDs (student or faculty/staff ID)
 # returns 1 parameter - 'ok' if no processing error, or other value                   values will be either: scalar (username) or an array 
 #                       if an error occurred.                  if a single ID matches multiple usernames.
 # side effects - populates the $instusers and $instids refs to hashes.   (d) $lc_users - reference to hash containing LON-CAPA usernames in 
 #                with information for all users from all available                    in domain $dom, as keys. Needed if institutional
 #                institutional datafeeds.                   data source only allows query by username.
 #   (e) $counts - reference to hash (optional), for use when called 
 ###############################                 from Autoupdate.pl which can contain counts for
                  user-specified items retrieved in allusers_info()
                  or in custom subroutines which it calls. Key in
                  hashref, and count value will be printed to 
                  autoupdate.log by Autoupdate.pl.  
                    
    returns 1 parameter - 'ok' if no processing error, or other value 
                          if an error occurred.
    side effects - populates the $instusers and $instids refs to hashes.
                   with information for all users from all available 
                   institutional datafeeds.
   
   
   =cut
   
 sub allusers_info {  sub allusers_info {
     my ($dom,$instusers,$instids) = @_;      my ($dom,$instusers,$instids,$lc_users,$counts) = @_;
     my $outcome = 'ok';      my $outcome = 'ok';
     return $outcome;       return $outcome; 
 }  }
   
 ###############################  =pod
 # sub get_userinfo  
 #  =item get_userinfo()
 # Incoming data: four required arguments and additional optional arguments  
 # Two modes of operation:   Incoming data: four required arguments and additional optional arguments
 # (1) Retrieves institutional data for a single user either by username   Two modes of operation:
 #     if $uname is included as second argument, or by ID if $id is    (1) Retrieves institutional data for a single user either by username
 #     included as a third argument.  Either (b) or (c) must be provided.       if $uname is included as second argument, or by ID if $id is 
 #     (g), (h) and (i) will be undefined.       included as a third argument.  Either (b) or (c) must be provided.
 # (2) Retrieves institutional user data from search of an institutional       (g), (h) and (i) will be undefined.
 #     directory based on a search. (g) and (h) are required.   (2) Retrieves institutional user data from search of an institutional
 #     (i) is optional. (b) and (c) will be undefined.        directory based on a search. (g) and (h) are required.
 #       (i) is optional. (b) and (c) will be undefined. 
 # (a) $dom - domain  
 # (b) $uname - username of user   (a) $dom - domain
 # (c) $id - student/faculty ID of user   (b) $uname - username of user
 # (d) $instusers - reference to hash which will contain info for user   (c) $id - student/faculty ID of user
 #                 as key = value; keys will be one or all of:   (d) $instusers - reference to hash which will contain info for user
 #                 lastname,firstname,middlename,generation,id,inststatus -                   as key = value; keys will be one or all of:
 #                 institutional status (e.g., faculty,staff,student)                   lastname,firstname,middlename,generation,id,inststatus -
 #                 Values are all scalars except inststatus,                   institutional status (e.g., faculty,staff,student)
 #                 which is an array.                   Values are all scalars except inststatus,
 # (e) $instids - reference to hash which will contain ID numbers -                    which is an array.
 #                 keys will be unique IDs (student or faculty/staff ID)     (e) $instids - reference to hash which will contain ID numbers - 
 #                 values will be either: scalar (username) or an array                   keys will be unique IDs (student or faculty/staff ID)  
 #                 if a single ID matches multiple usernames.                   values will be either: scalar (username) or an array
 # (f) $types - optional reference to array which contains                    if a single ID matches multiple usernames.
 #              institutional types to check.   (f) $types - optional reference to array which contains 
 # (g) $srchby - optional if $uname or $id defined, otherwise required.                institutional types to check.
 #               Allowed values include: 1. lastfirst, 2. last, 3. uname   (g) $srchby - optional if $uname or $id defined, otherwise required.
 #               corresponding to searches by 1. lastname,firstname;                 Allowed values include: 1. lastfirst, 2. last, 3. uname
 #               2. lastname; 3. username                 4. email, corresponding to searches by 1. lastname,firstname;
 # (h) $srchterm - optional if $uname or $id defined, otherwise required                 2. lastname; 3. username; 4. e-mail address
 #                String to search for.   (h) $srchterm - optional if $uname or $id defined, otherwise required
 # (i) $srchtype - optional. Allowed values: contains, begins (defaults                  String to search for.
 #                to exact match otherwise).   (i) $srchtype - optional. Allowed values: contains, begins (defaults
 #                  to exact match otherwise).
 # returns 1 parameter - 'ok' if no processing error, or other value   
 #                       if an error occurred.   returns 1 parameter - 'ok' if no processing error, or other value 
 # side effects - populates the $instusers and $instids refs to hashes.                         if an error occurred.
 #                with information for specified username, or specified   side effects - populates the $instusers and $instids refs to hashes.
 #                id, if fifth argument provided, from all available, or                   with information for specified username, or specified
 #                specified (e.g., faculty only) institutional datafeeds,                  id, if fifth argument provided, from all available, or 
 #                if sixth argument provided.                  specified (e.g., faculty only) institutional datafeeds,
 #                  if sixth argument provided.
 # WARNING: You need to set $outcome to 'ok' once you have customized  
 #          this routine to communicate with an instititional    WARNING: You need to set $outcome to 'ok' once you have customized
 #          directory data source, otherwise institutional directory             this routine to communicate with an instititional 
 #          searches will always be reported as being unavailable            directory data source, otherwise institutional directory 
 #          in domain $dom.            searches will always be reported as being unavailable
 #            in domain $dom.
 ###############################  
   =cut
   
 sub get_userinfo {  sub get_userinfo {
     my ($dom,$uname,$id,$instusers,$instids,$types,      my ($dom,$uname,$id,$instusers,$instids,$types,
Line 573  sub get_userinfo { Line 1155  sub get_userinfo {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub inst_usertypes   
 #  =item get_multusersinfo
 # Incoming data: three arguments  
 # (a) $dom - domain   (a) $dom - domain
 # (b) $usertypes - reference to hash which will contain    (b) $type - username or id
 #                 key = value, where keys are institution    (c) $unamenames - reference to hash containing usernames of users
 #                 affiliation types (e.g., Faculty, Student etc.)   (d) $instusers - reference to hash which will contain info for user
 #                 and values are titles (e.g., Faculty/Academic Staff)                   as key = value; keys will be one or all of:
 # (c) $order - reference to array which will contain the order in                   lastname,firstname,middlename,generation,id,inststatus -
 #              which institutional types should be shown                   institutional status (e.g., faculty,staff,student)
 #              when displaying data tables (e.g., default quotas                       Values are all scalars except inststatus,
 #              or updateable user fields (see domainprefs.pm)                    which is an array.
 # returns 1 parameter - 'ok' if no processing error, or other value    (e) $instids - reference to hash which will contain ID numbers -
 #                        if an error occurred.                   keys will be unique IDs (student or faculty/staff ID)
 #                   values will be either: scalar (username) or an array
 ###############################                   if a single ID matches multiple usernames.
   
    returns 1 parameter - 'ok' if no processing error, or other value
                          if an error occurred.
   
    side effects - populates the $instusers and $instids refs to hashes.
                   with information for specified username, or specified
                   id, if fifth argument provided, from all available, or
                   specified (e.g., faculty only) institutional datafeeds,
                   if sixth argument provided.
   
    WARNING: You need to set $outcome to 'ok' once you have customized
             this routine to communicate with an instititional
             directory data source, otherwise retrieval of institutional
             user information will always be reported as being unavailable
             in domain $dom.
   
   =cut
   
   sub get_multusersinfo {
       my ($dom,$type,$usernames,$instusers,$instids) = @_;
       my $outcome = 'unavailable'; 
       return $outcome;
   }
   
   =pod
   
   =item inst_usertypes() 
   
    Starting with LON-CAPA 2.11.0 use of this subroutine
    is deprecated. The domain configuration web GUI
    accessible to Domain Coordinators will be used to
    manage institutional types.  If you have previously
    customized this routine, then values set there will
    be used when displaying the "Institutional user types"
    section in the domain config screen for:
    "Default authentication/language/timezone/portal/types".
   
    Once you have visited that screen and saved the settings,
    configuration thereafter will be via the web GUI of
    values stored in the domain's configuration.db file on
    the primary library server in the domain, and values in
    inst_usertypes() will no longer be consulted.
    
    Incoming data: three arguments
    (a) $dom - domain
    (b) $usertypes - reference to hash which will contain 
                    key = value, where keys are institution 
                    affiliation types (e.g., Faculty, Student etc.)
                    and values are titles (e.g., Faculty/Academic Staff)
    (c) $order - reference to array which will contain the order in
                 which institutional types should be shown
                 when displaying data tables (e.g., default quotas    
                 or updateable user fields (see domainprefs.pm) 
    returns 1 parameter - 'ok' if no processing error, or other value 
                           if an error occurred.
   
   
   =cut
   
 sub inst_usertypes {  sub inst_usertypes {
     my ($dom,$usertypes,$order) = @_;      my ($dom,$usertypes,$order) = @_;
Line 599  sub inst_usertypes { Line 1239  sub inst_usertypes {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub username_rules  
 #  
 # Incoming data: three arguments   
 # (a) $dom - domain  
 # (b) $ruleshash - reference to hash containing rules  
 #                  (a hash of a hash)  
 #                  keys of top level hash are short names    
 #                   (e.g., netid, noncredit)   
 #                  for each key, value is a hash  
 #                      desc => long name for rule    
 #                      rule => description of rule  
 #                      authtype => (krb5,krb4,int, or loc)  
 #                                 authentication type for rule   
 #                      authparm => authentication parameter for rule  
 #                      authparmfixed => 1 if authparm used when  
 #                          creating user for rule must be authparm    
 #                      authmsg => Message to display describing   
 #                                 authentication to use for this rule  
 #  
 # (c) $rulesorder - reference to array containing rule names   
 #                   in order to be displayed  
   
 #  =item username_rules()
 #  returns 'ok' if no processing error.  
 #   Incoming data: three arguments 
 ###############################    (a) $dom - domain
    (b) $ruleshash - reference to hash containing rules
                     (a hash of a hash)
                     keys of top level hash are short names  
                      (e.g., netid, noncredit) 
                     for each key, value is a hash
                         desc => long name for rule  
                         rule => description of rule
                         authtype => (krb5,krb4,int, or loc)
                                    authentication type for rule 
                         authparm => authentication parameter for rule
                         authparmfixed => 1 if authparm used when
                             creating user for rule must be authparm  
                         authmsg => Message to display describing 
                                    authentication to use for this rule
   
    (c) $rulesorder - reference to array containing rule names 
                      in order to be displayed
   
   
     returns 'ok' if no processing error.
   
   =cut
   
 sub username_rules {  sub username_rules {
     my ($dom,$ruleshash,$rulesorder) = @_;      my ($dom,$ruleshash,$rulesorder) = @_;
Line 633  sub username_rules { Line 1274  sub username_rules {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub id_rules  
 #  
 # Incoming data: three arguments  
 # (a) $dom - domain  
 # (b) $ruleshash - reference to hash containing rules  
 #                  (a hash of a hash)  
 #                  keys of top level hash are short names  
 #                   (e.g., netid, noncredit)  
 #                  for each key, value is a hash  
 #                      desc => long name for rule  
 #                      rule => description of rule  
 #  
 # (c) $rulesorder - reference to array containing rule names  
 #                   in order to be displayed  
   
 #  =item id_rules()
 #  returns 'ok' if no processing error.  
 #   Incoming data: three arguments
 ###############################   (a) $dom - domain
    (b) $ruleshash - reference to hash containing rules
                     (a hash of a hash)
                     keys of top level hash are short names
                      (e.g., netid, noncredit)
                     for each key, value is a hash
                         desc => long name for rule
                         rule => description of rule
   
    (c) $rulesorder - reference to array containing rule names
                      in order to be displayed
   
     returns 'ok' if no processing error.
   
   =cut
   
 sub id_rules {  sub id_rules {
     my ($dom,$ruleshash,$rulesorder) = @_;      my ($dom,$ruleshash,$rulesorder) = @_;
Line 660  sub id_rules { Line 1301  sub id_rules {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub username_check   
 #  =item selfcreate_rules()
 # Incoming data: four arguments  
 # (a) $dom - domain (scalar)    Incoming data: three arguments
 # (b) $uname - username to compare against rules (scalar)   (a) $dom - domain
 # (c) $to_check (reference to array of rule names to check)   (b) $ruleshash - reference to hash containing rules
 # (d) $resultshash (reference to hash of results)                    (a hash of a hash)
 #                    hash of results for rule checked                    keys of top level hash are short names
 #                   - keys are rule names                     (e.g., netid)
 #                   - values are: 1 or 0 (for matched or unmatched)                     for each key, value is a hash
 #                        desc => long name for rule
 # returns 'ok' if no processing error.                        rule => description of rule
 #  
 ###############################   (c) $rulesorder - reference to array containing rule names
                      in order to be displayed
   
     returns 'ok' if no processing error.
   
   
   =cut
   
   sub selfcreate_rules {
       my ($dom,$ruleshash,$rulesorder) = @_;
       my $outcome;
       return $outcome;
   }
   
   =pod
   
   =item username_check() 
   
    Incoming data: four arguments
    (a) $dom - domain (scalar) 
    (b) $uname - username to compare against rules (scalar)
    (c) $to_check (reference to array of rule names to check)
    (d) $resultshash (reference to hash of results)
                       hash of results for rule checked
                      - keys are rule names
                      - values are: 1 or 0 (for matched or unmatched) 
   
    returns 'ok' if no processing error.
   
   
   =cut
   
 sub username_check {  sub username_check {
     my ($dom,$uname,$to_check,$resultshash) = @_;      my ($dom,$uname,$to_check,$resultshash) = @_;
Line 682  sub username_check { Line 1353  sub username_check {
     return $outcome;       return $outcome; 
 }  }
   
 ###############################  =pod
 # sub id_check  
 #  =item id_check()
 # Incoming data: four arguments  
 # (a) $dom - domain (scalar)   Incoming data: four arguments
 # (b) $id - ID to compare against rules (scalar)   (a) $dom - domain (scalar)
 # (c) $to_check (reference to array of rule names to check)   (b) $id - ID to compare against rules (scalar)
 # (d) $resultshash (reference to hash of results)   (c) $to_check (reference to array of rule names to check)
 #                    hash of results for rule checked   (d) $resultshash (reference to hash of results)
 #                   - keys are rule names                      hash of results for rule checked
 #                   - values are: 1 or 0 (for matched or unmatched)                     - keys are rule names
 #                     - values are: 1 or 0 (for matched or unmatched)
 # returns 'ok' if no processing error.  
 #   returns 'ok' if no processing error.
 ###############################  
   
   =cut
   
 sub id_check {  sub id_check {
     my ($dom,$id,$to_check,$resultshash) = @_;      my ($dom,$id,$to_check,$resultshash) = @_;
Line 704  sub id_check { Line 1377  sub id_check {
     return $outcome;      return $outcome;
 }  }
   
 ###############################  =pod
 # sub AUTOLOAD  
 #  =item selfcreate_check()
 # Incoming data: none  
 # Returns ''   Incoming data: four arguments
 #   (a) $dom - domain (scalar)
 # Prevents errors when undefined subroutines are called in this package   (b) $selfcreatename - e-mail proposed as username (compare against rules - scalar)
 # Will allow new routines added in the future to be called from lond etc.   (c) $to_check (reference to array of rule names to check)
 # without the need for customized versions of local*.pm packages to be   (d) $resultshash (reference to hash of results)
 # modified to include the new subroutines immediately.                     hash of results for rule checked
 #                     - keys are rule names
 # See "Programming Perl" 3rd ed. pp 296-298.                        - values are: 1 or 0 (for matched or unmatched)
 ###############################  
    returns 'ok' if no processing error.
   
   
   =cut
   
   sub selfcreate_check {
       my ($dom,$selfcreatename,$to_check,$resultshash) = @_;
       my $outcome;
       return $outcome;
   }
   
   =pod
   
   =item AUTOLOAD()
   
    Incoming data: none
    Returns ''
   
    Prevents errors when undefined subroutines are called in this package
    Will allow new routines added in the future to be called from lond etc.
    without the need for customized versions of local*.pm packages to be
    modified to include the new subroutines immediately.
   
    See "Programming Perl" 3rd ed. pp 296-298.   
   
   =back
   
   =cut
   
 sub AUTOLOAD {  sub AUTOLOAD {
     our $AUTOLOAD;      our $AUTOLOAD;

Removed from v.1.29  
changed lines
  Added in v.1.63


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>