Location: PHPKode > projects > ORS - On-line Resource Scheduler > install/maintfunctions.php
<?php
//--------------------------------------------------------------
// ORS - Online Resource Scheduler
// Copyright (c) Jeremy Shaver 2002-2005
//
// See the license.html file for details on distribution and use
//
// This program is free software; you can redistribute it and/or 
//  modify it under the terms of the GNU General Public License 
//  as published by the Free Software Foundation; either version 
//  2 of the License, or (at your option) any later version.
//  
// This program is distributed in the hope that it will be useful, 
//  but WITHOUT ANY WARRANTY; without even the implied warranty of 
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
//  GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public 
//  License (license.html) along with this program; if not, write 
//  to the Free Software Foundation, Inc., 59 Temple Place, Suite 
//  330, Boston, MA 02111-1307 USA
//  or visit: http://www.opensource.org/licenses/gpl-license.php
//
//--------------------------------------------------------------

//----------------------------------------------------
// DAILYACTIONS
//Do actions we need to do only daily
function dailyactions (){

	purgeActionLog();	// Purge old action log entries first due to next step being memory-intensive
    //Check if the last backup mailing was within mail_backup_interval
    $revitems    = array_reverse(readactionlog());
    $lastmailing = "1/1/80";        //default date if we find none
    foreach ($revitems as $oneitem)
        if ($oneitem['data']['action'] == "Backup Mailed") {
            $lastmailing = $oneitem['date'];
            break;
        }
    if ((strtotime(date("m/d/y",max(0,validatedate($lastmailing))))+backup_interval) <= strtotime(date("m/d/y",zulutime()+timezone))) {
        mailallsignups();                //e-mail signups as backup
    }

    purgecalendar();                                //purge calendar of really old days

    reconcileexpiredaccounts(); //identify expired accounts and restrict their signups

}

//----------------------------------------------------
// PURGEACTIONLOG
// Purge stale entries from the action log
function purgeActionLog() {
	if (file_exists(actionlog_name)) {
		$fp = fopenlock(actionlog_name, 'r+');
		
		// First, find the point at which we reach the entries we want to keep
		$currentStart = 0;
		while ($oneLine = fgetcsv_trim($fp, 1000, ','))  {
		    $thisdate = validatedate($oneLine[1]);
		    if ($thisdate<0) $thisdate = 0;
			if ((strtotime(date("m/d/y",$thisdate))+loglength) < strtotime(date("m/d/y",zulutime()+timezone))) {
				$currentStart = ftell($fp);
			}
		}
		
		// Overwrite the new entries with the old ones (256KB at a time to conserve memory)
		$readPointer = $currentStart;
		$writePointer = 0;
		do {
			fseek ($fp, $readPointer);
			$newData = fread($fp, 262144);
			$readPointer = ftell($fp);
			if (strlen($newData) == 0) {
				break;
			}
			fseek ($fp, $writePointer);
			fwrite($fp, $newData);
			$writePointer = ftell($fp);
		} while (true);
		
		// Truncate the file to the proper length and close the file
		rewind($fp);
		ftruncate($fp, filesize(actionlog_name)-$currentStart);
                fclose ($fp);
	}
}

//----------------------------------------------------
// PURGECALENDAR
//Purge all resouce dirs from really old day files
function purgecalendar (){

        $resourcelist = getresources();
        if (count($resourcelist)>0) foreach ($resourcelist as $resource=>$desc)
                for ($day=0; $day<30; $day++) {                //clear calendar from "calendar_history" days ago back 30 days
                        $datestr = date("mdy", zulutime()+timezone-($day*60*60*24)-calendar_history);
                        $onefile = root_dir . $resource . "/" . $datestr . ".csv";
                        if (file_exists($onefile)) unlink($onefile);
                }
        logaction ("Calendar Purged");
}
//----------------------------------------------------
// RECONCILECALENDAR
// verify that all future calendar entries have matching user entries
function reconcilecalendar (){

    $resourcelist = getresources();
    $users        = getusers();

    $missing = 0;
    $short   = 0;
    $changed = array();

    $today   = strtotime(date("m/d/y",zulutime()+timezone));

    for ($day=0; $day<365*5; $day++) {
        $mydate = $today + $day*60*60*24;
        foreach ($resourcelist as $res=>$resource) {
            $signups = getdaysignups ($mydate,$res);
            if (count($signups)>0) foreach ($signups as $signup) {
                $useritems  = getusersignups($signup['usn']);
                $thissignup = $useritems[$signup['signup']];

                $starttime = strtotime(date('m/d/y',$mydate) . ' ' . floor($signup['hour']) . ':' . ((($signup['hour']+$signup['length'])%1)*3) . "0");
                $endtime   = strtotime(date('m/d/y',$mydate) . ' ' . floor($signup['hour']) . ':' . ((($signup['hour']+$signup['length'])%1)*3) . "0")+$signup['length']*60*60;

                if ($endtime > zulutime()+timezone) {        //if the endtime hasn't passed already
                    //is this signup completely missing in the user file? create it.
                    if ($thissignup == "") {

                        $newinfo = array(
                                'signup'    => $signup['signup'],
                                'starttime' => $starttime,
                                'resource'  => $res,
                                'endtime'   => $endtime,
                                'comment'   => "" );

                        $useritems[$signup['signup']] = $newinfo;
                        putusersignups ($signup['usn'],$useritems);
                        logaction("Recovered Signup","",$newinfo);
                        $changed[] = $users[$signup['usn']]['firstname'] . " " . $users[$signup['usn']]['lastname'];
                        $missing++;

                    }
                    //is this a continuation of the same signup? (maybe?!? Resource # must match, calendar-indicated endtime must be > current endtime,
                    //  and calendar-indicated starttime must be > current starttime)
                    if ($thissignup != "" & $thissignup['endtime'] < $endtime
                        & $thissignup['starttime'] < $starttime & $thissignup['resource']==$res) {

                        $useritems[$signup['signup']]['endtime'] = $endtime;        //update the endtime only
                        putusersignups ($signup['usn'],$useritems);
                        logaction("Combined Signups","",$useritems[$signup['signup']]);
                        $changed[] = $users[$signup['usn']]['firstname'] . " " . $users[$signup['usn']]['lastname'];
                        $short++;

    }   }   }   }   }

    return(array("missing"=>$missing,"short"=>$short,"changed"=>$changed));

}

//----------------------------------------------------
// DECODEALLSIGNUPS
//creates a plain-text string representing all signups
// input $mode indicates type of text:
//     "normal" (default) human-readable
//     "php"  machine-interpretable for restoration of lost data
function decodeallsignups($mode="normal") {

        $resourcelist = getresources();                        //get list of valid resources
        $users        = getusers();
        $strng        = "";
        if ($mode!="normal") {
            $strng  = "<?php\n";
            $strng .= "validateusers();\n";
            $strng .= '$items=array();' . "\n";
        }

        foreach ($resourcelist as $resource=>$resourceinfo) {
            $allsignups   = array();
            foreach ($users as $usn => $user) {              //get future signups for all users
                $signup = getusersignups ($usn,true);
                if (count($signup)>0)                        //and grab those for this resource
                    foreach ($signup as $item) {
                        $item['usn'] = $usn;
                        if ($item['resource'] == $resource) $allsignups[] = $item;
                    }
            }

            if ($mode=="normal") $strng .= "Future signups for " . $resourceinfo['long'] . ":\n\n";

            if (count($allsignups) > 0) {
                $allsignups = sortby($allsignups,'starttime');
                foreach ($allsignups as $item) {

                    if ($mode=="normal")
                        //normal text encoding
                        $strng .= decodesignup($item,$users[$item['usn']]['firstname'] . " " . $users[$item['usn']]['lastname'],false);
                    else {
                        //PHP code encoding
                        $strng .= '$items[]=array(';
                        foreach($item as $key=>$value) {
                            $strng .= '"' . $key . '"';
                            if (gettype($value)=="string") $strng .= '=>"' . $value . '",';
                            else $strng .= '=>' . $value . ',';
                        }
                        $strng .= '"priority"=>' . getsignuppriority ($item['usn'], $item['signup']) . ');';
                    }
                    $strng .= "\n";
                }
            } else
                if ($mode=="normal") $strng .= "No future signups located.\n";

            $strng .= "\n";
        }

        //add "make it happen" code to php encoding
        if ($mode!="normal") {
            $strng .= 'if (count($items)>0) foreach ($items as $item) addsignup($item);' . "\n";
            $strng .= "?>";
        }

        return($strng);
}

//----------------------------------------------------
// CREATEBACKUP
//create backup of current scheduler and save to file (or return if input ASFILE is false)
function createbackup ($asfile = true) {

    $backup_folder = root_dir . "../backup/";
    //Remove old backup files
    $filelist = getfilelist($backup_folder,false);
    foreach ($filelist as $file) {
        if (substr($file,-4)=='.ors' && filectime($backup_folder . $file)<(zulutime()-backup_history)) {
            unlink($backup_folder . $file);
        }
    }

    //create new backup file for today
    $backup_file = $backup_folder . date("Ymd",mktime());
    if (file_exists($backup_file . "_backup.ors")) {
        $rep = 'a';
        while (file_exists($backup_file . $rep . "_backup.ors")) {
            $rep++;
        }
        $backup_file .= $rep;
    }
    $backup_file .= "_backup.ors";

    //Open backup file
    if (in_array('zlib',get_loaded_extensions())) {
        if ($asfile) {
            //open compressed .ors file
            $fid = gzopen($backup_file,'wb');
            if (!$fid) {
                return(false);
            }
        }
    } else {  //if we don't have access to zlib, do regular write
        if ($asfile) {
            //open regular .ors file
            $fid = fopen($backup_file,'wb');
            if (!$fid) {
                return(false);
            }
        }
    }


    //Read in all files and and compress them
    $data = "";
    foreach (getfilelist(root_dir) as $filename) {
        $data .= "[==>FILENAME:" . $filename . "]\n";
        $data .= implode("",file(root_dir . $filename));
        $data .= "[==>EOF]\n";

        if ($asfile) {
            if (in_array('zlib',get_loaded_extensions())) {
                //Write out compressed data to .ors file
                gzwrite($fid,$data);
            } else {  //if we don't have access to zlib, do regular write
                //Write out data to .ors file
                fwrite($fid,$data);
            }
            $data = "";  //start data fresh again
        } else {
            //keep accumulating data until done
        }
    }

    if (in_array('zlib',get_loaded_extensions())) {
        if ($asfile) {
            gzclose($fid);
            return($backup_file);
        } else {
            $compdata = gzcompress($data);
            return($compdata);
        }
    } else {  //if we don't have access to zlib, do regular write
        if ($asfile) {
            fclose($fid);
            return($backup_file);
        } else {
            return($data);
        }
    }

}
//----------------------------------------------------
// MAILALLSIGNUPS
//Create backup and e-mail as needed
function mailallsignups (){

    //create backup file and e-mail to indicated users (if desired)
    $backup_file = createbackup();

    $addheaders = "From: " . email_from . "\n";
    $to         = "";
    foreach (getusers() as $usn => $oneuser) if (checksec($oneuser['sec'],1000)) $to .= getcontact($usn,"emails") . ",";

	//- - - - - - - - - - -
    if (mail_backup) {

        $subject = "On-Line Scheduling Backup (" . date(dateformat . "/Y",zulutime()+timezone) . ")";
        $message = "\nThe attached file is an encoded Backup of the scheduling data and can be ";
        $message .= "used to restore the system at " . scheduling_URL . " as of " . date(dateformat . "/Y " . timeformat,zulutime()+timezone) . ".\n";
        $message .= "To use this file, follow the instructions provided by the administrator maintenance menu \"Restore\" function.\n";
    
        $success1 = sendemail ($to, $subject, $message, $addheaders, $backup_file);
    }
    
	//- - - - - - - - - - -
    if (mail_action_log) mailactionlog();                //e-mail action log to special users

	//- - - - - - - - - - -
	if (mail_signups) {

        $subject = "On-Line Scheduling Signups (" . date(dateformat . "/Y",zulutime()+timezone) . ")";
        $message = "\nThe following is a record of the current signups ";
        $message .= "on the scheduler for " . scheduling_URL . " as of " . date(dateformat . "/Y " . timeformat,zulutime()+timezone) . ".\n";

        $message .= "\n" . decodeallsignups() . "\n";

        $success2 = sendemail ($to, $subject, $message, $addheaders);
	}

	//- - - - - - - - - - -

    logaction("Backup Mailed");

    //if (!$success1) $to = 'Backup e-mail failed';
    //elseif (!$successs2) $to = 'Signup listing e-mail failed';

    return($to);

}
//----------------------------------------------------
// MAILACTIONLOG
//E-mail action log to special users
function mailactionlog ($recent = true){

    $resourcelist = getresources();                        //get list of valid resources
    $users        = getusers();

    $message = "The following actions have been logged:\n\n";

    $items = readactionlog();

    if (count($items) > 0) {
        $items = array_reverse($items);
        if ($recent) {                //send ONLY recent items?
            $allitems = $items;
            $items = array();
            foreach ($allitems as $key => $oneitem) {
                if ($oneitem['data']['action'] != "Log Mailed") $items[$key] = $oneitem;
                else break;
            }
        }
    }

    if (count($items) == 0) {
        $message .= "Log is empty\n";
    } else {
        $message .= "Date, Action [Details]\n";
        foreach ($items as $linenum => $entry) {
            $data = $entry['data'];
            $message .= $entry['date'] . ", ";
            if ($data['action'] == "Bad Password") {
                $message .= $data['action'] . " for " . $data['lastname'];
            } elseif (in_array(strtolower($data['action']),
                   array("deleted authorized user","added authorized user","updated authorized user","restore from backup","updated configuration","assigned usn","deleted user"))) {
                $message .= $users[$data['thisuserid']]['firstname']{0} . ". " . $users[$data['thisuserid']]['lastname'] . " " . $data['action'] . " <b>" . $data['firstname']{0} . ". " . $data['lastname'] . "</b>";
                if (in_array("sec", array_keys ($data))) $message .= " SEC = " . $data['sec'];
                if (in_array("usn", array_keys ($data))) $message .= " USN = " . $data['usn'];
            } else {
                if ($data['thisuserid'] != $data['usn'] & $data['usn'] != "") {
            		$targetuser = $users[$data['usn']]['firstname']{0} . ". " . $users[$data['usn']]['lastname'];
            		if ($users[$data['usn']]['lastname']=="") $targetuser = "(usn " . $data['usn'] . ")";
                        $message .= $users[$data['thisuserid']]['firstname']{0} . ". " . $users[$data['thisuserid']]['lastname'] . " " . $data['action'] . " " . $targetuser;
                } elseif ($data['thisuserid'] != "") {
                        $message .= $users[$data['thisuserid']]['firstname']{0} . ". " . $users[$data['thisuserid']]['lastname'] . " " . $data['action'] . " self";
                } else
                        $message .= $data['action'];
                $message .= " [" . $resourcelist[$data['resource']]['short'];
                if (in_array("sec", array_keys ($data))) $message .= "SEC = " . $data['sec'];
                if (in_array("starttime", array_keys ($data)) & in_array("endtime", array_keys ($data)))
                    $message .= ", " . date(dateformat . " " . timeformat,$data['starttime']) . "-" . date(dateformat . " " . timeformat,$data['endtime']);
                if (in_array("priority", array_keys ($data))) $message .= ", priority " . $data['priority'];
                if (in_array("signup", array_keys ($data))) $message .= " (signup " . $data['signup'] . ")";
                $message .= "]";
            }
            $message .= "\n";
        }
    }
    $message .= "\n";

    $addheaders = "From: " . email_from . "\n";
    $to      = "";
    foreach ($users as $usn => $oneuser) if (checksec($oneuser['sec'],1000)) $to .= getcontact($usn,"emails") . ",";

    $subject = "On-Line Scheduling Action log (" . date(dateformat . "/Y",zulutime()+timezone) . ")";

    sendemail ($to, $subject, $message, $addheaders);

    logaction("Log Mailed");

    return($to);

}

//----------------------------------------------------
// RECONCILEEXPIREDACCOUNTS
// Check user accounts to indentify expired ones.  If expired, delete unauthorized future signups
// If no USN is provided, all accounts are checked for expiration, and reconciled if expired
// If a USN is supplied, force reconciliation for that user whether the account is expired or not
function reconcileexpiredaccounts ($usn = -1){
     $resourcelist = getresources();
     $users        = getusers();

     if ($usn != -1) {
        $selectedusns = array($usn);
        $forcereconciliation = TRUE;
     }else{
        $selectedusns = array_keys($users);  //get all usns
        $forcereconciliation = FALSE;
     }

     //get time stamp for the beginning of today
     $today = validatedate(date(dateformat . "/Y",zulutime()));

     $expiredorinactive = 0;
     foreach ($selectedusns as $memberUSN) {
          $foundexpiredaccount = 0;

          //Check if the account has expired
          if ((strcmp($users[$memberUSN]['expire'],"") != 0) && (strcmp($users[$memberUSN]['expire'],"Expired") != 0) && (!$forcereconciliation)){
                if (validatedate($users[$memberUSN]['expire']) <  $today) {
                    //Set account as expired so we don't check it again until it is reactivated
                    $member = $users[$memberUSN];
                    $users[$memberUSN]['expire'] = "Expired";
                    logaction('User account has expired: ',$thisuserid,array('usn'=>$memberUSN,'member'=>$member['firstname']." ".$member['lastname']));
                    $expiredorinactive = 1;
                    $foundexpiredaccount = 1;
                }
          }

          //Check if the account has become inactive
          if (stristr($users[$memberUSN]['lastactivity'], "inactive") == FALSE){ //first make sure we haven't already marked the account as inactive
               if (($today - validatedate($users[$memberUSN]['lastactivity']) > inactive_account) && (strcmp($users[$memberUSN]['lastactivity'],"") != 0)) {

                     $member = $users[$memberUSN];

                     //send e-mail to administrators
                     $message    = "Please be advised, the following user account has become inactive:.\n";
                     $message   .= $member['firstname']." ".$member['lastname']."\n";
                     $message   .= "Home Phone: ".$member['homephone']."\n";
                     $message   .= "Work Phone: ".$member['workphone']."\n";
                     $message   .= "Email Address 1: ".$member['email1']."\n";
                     $message   .= "Email Address 2: ".$member['email2']."\n";
                     $message   .= "Account Expiration: ".$member['expire']."\n";
                     $message   .= "\n";
                     $message   .= "You may want to contact this person to see if they plan to\n";
                     $message   .= "continue to use this scheduling system.\n";
                     $message   .= "\nIf desired, you may restrict their account in the\n";
                     $message   .= "User Management Screen.  By restricting their account you\n";
                     $message   .= "will limit their ability to keep their existing future signups\n";
                     $message   .= "as well as their ability to create new signups.\n";
                     $message   .= "\n";
                     $message   .= " Visit " . scheduling_URL . " for additional information.\n";
                     $addheaders = "From: " . email_from . "\n";
                     $to         = "";
                     foreach ($users as $usn => $oneuser) if (checksec($oneuser['sec'],100)) $to .= getcontact($usn) . ",";
                     $subject = "ORS User Account has become INACTIVE";
                     sendemail ($to, $subject, $message, $addheaders);

                     //add "inactive" to the inactivity field so we know that we don't have to check it again
                     $users[$memberUSN]['lastactivity'] = $users[$memberUSN]['lastactivity']."inactive";
                     logaction('User account has become inactive: ',$thisuserid,array('usn'=>$memberUSN,'member'=>$member['firstname']." ".$member['lastname']));
                     $expiredorinactive = 1;

                     //uncomment the line below to automatically expire an inactive account
                     //$foundexpiredaccount = 1;
               }
          }

          //If the account has become expired, or reconciliation is forced, then reconcile future signups
          if (($foundexpiredaccount) || ($forcereconciliation)) {
                 $usersignups = getusersignups($memberUSN, TRUE);
                 foreach ($usersignups as $signup) {

                      if (hard_account_expiration) {
                          promote(deletesignup(array('usn'=>$memberUSN,'signup'=>$signup['signup'])));
                          logaction('deleted signup (expired/restricted): ',$thisuserid,array('usn'=>$memberUSN,'signup'=>$signup['signup']));
                      }else {
                           //Check if this signup's resource is double-bookable
                           if (!$resourcelist[$signup['resource']]['doublebook']) {
                                 //Resource is not double-bookable, therefore check if there
                                 //   is another signup for same time period with a double-bookable resource
                                 $signupOK = FALSE;
                                 foreach ($usersignups as $signupcheck){
                                      //Find other signups with double-bookable resources
                                      if ($resourcelist[$signupcheck['resource']]['doublebook']) {
                                          if (($signup['starttime'] >= $signupcheck['starttime'])
                                          && ($signup['endtime'] <= $signupcheck['endtime'])) {
                                               //Matching double-bookable signup found.  Leave signup alone.
                                               $signupOK = TRUE;
                                               break;
                                          }
                                      }
                                 }
                                 //If no matching double-bookable signup found, then delete signup
                                 if ($signupOK == FALSE) {
                                     promote(deletesignup(array('usn'=>$memberUSN,'signup'=>$signup['signup'])));
                                     logaction('deleted signup (account expired): ',$thisuserid,array('usn'=>$memberUSN,'signup'=>$signup['signup']));
                                 }

                           }
                      }
                 }

          }
     }
     if ($expiredorinactive) putusers($users);
     return(0);

}

//---------------------------------------------------
// TIMESHIFTCORRECTION
// Correct calendar for problems due to a shift in system time
//  also handles item overlaps
function timeshiftcorrection() {

    $users = getusers();

    $missing = 0;
    $offsets = array();
    $inconflict = array();
    foreach ($users as $usn=>$user) {

        //get user's signups
        $signups = getusersignups($usn,false);

        if (!empty($signups)) {

            //cycle through all of them
            foreach ($signups as $signup=>$details) {

                foreach (array(0,1,-1) as $dayoffset) { //search day of, day after, day before for this signup

                    $mydate = $details['starttime']+($dayoffset*60*60*24);
                
                    //get the corresponding day
                    $dayssignups = getdaysignups ($mydate,$details['resource']);

                    //search for this signup
                    $found = false;
                    if (!empty($dayssignups)) foreach ($dayssignups as $daykey=>$onesignup) {
                        if ($onesignup['usn']==$usn && $onesignup['signup']==$signup) {
                            //calculate offset (including any day shift we had to make)
                            $offset = date('H',$details['starttime']) - $onesignup['hour'] - ($dayoffset*24);
                            $found = true;
                            break;
                        }
                    }

                    //if found, do correction
                    if ($found) {

                        $signups[$signup]['starttime'] -= $offset*60*60;
                        $signups[$signup]['endtime']   -= $offset*60*60;

                        //add offset to list
                        $offsets[] = "" . $offset;

                        //and check for potential conflicts
                        if (count($dayssignups)>1) {
                            $details = $signups[$signup]; //get modified version
                            $a = $onesignup; //the one we just found
                            foreach ($dayssignups as $b) {
                                if (($a['signup']!=$b['signup'] || $a['usn']!=$b['usn'])
                                    && $a['priority']==$b['priority']
                                    && $a['hour']<($b['hour']+$b['length'])
                                    && ($a['hour']+$a['length'])>$b['hour']) {
                                    //potential conflict!
                                    $pri = findpriority ($details['starttime'],$details['endtime'],$details['resource']);

                                    $dayssignups[$daykey]['priority'] = $pri;
                                    putdaysignups ($mydate,$details['resource'],$dayssignups);
                                
                                    $temp = $dayssignups[$daykey];
                                    $temp = array_merge($temp,$signups[$signup]);
                                    $temp['resource'] = $details['resource'];
                                    $temp['date']     = date(dateformat . "/Y",$mydate);
                                    $inconflict[]     = $temp;

                                }
                            }
                        }


                        //break out of "day loop"
                        break;

                    }
                }  //dayoffset loop

                if (!$found) {
                    //Not found in ANY day?
                    unset($signups[$signup]);
                    $missing ++;
                    //echo 'USN: ' . $usn . ' Signup: ' . $signup . '  Not found in calendar - deleted <br>';
                }
                            
            } //signups loop
            putusersignups($usn,$signups);
        }
    }

    ?>
    <b>Adjusting Mismatch to Calendar</b>
    <table cellpadding=3>
    <tr>
    <td align='center'><b>Offset<br>(hours)</b></td>
    <td align='center'><b>Number of<br>Signups</b></td>
    </tr>
    <p>
    <?
    foreach (array_count_values($offsets) as $offset=>$count) {
        echo "<tr>";
        echo "<td>$offset</td>";
        echo "<td>$count</td>";
        echo "</tr>";
    }
    ?>
    </table>
    <b>Signups without calendar entries:</b> <? echo $missing; ?> (removed)<p>
    <?

    //------------------------------------------------------------------
    // now, check for overlaps (may demote the wrong one, but what can we do!)
    ?>
    <b>Demoting Conflicted Signups (notifying users): </b>
    <?
    $total = 0;
    foreach ($inconflict as $item) {
        if ($item['endtime']<zulutime()) continue; //skip this item (in the past)
        $item['thisuserid'] = 1;  //administrator
        echo $users[$item['usn']]['username'] . ", ";
        message("demotion",$item);                                //Report demotion to user
        $total++;
    }
    if ($total==0) echo "None Found";

    //------------------------------------------------------------------
    // now, check for missed promotions
    ?>
    <p>

    <b>Promotions: </b>
    <?
    foreach ($users as $usn=>$user) {

        //get user's signups
        $signups = getusersignups($usn,false);

        if (!empty($signups)) {

            //cycle through all of them
            foreach ($signups as $signup=>$details) {

                if ($details['endtime']<zulutime()) continue; //skip this item (in the past)
            
                //get the corresponding day
                $dayssignup = getdaysignups ($details['starttime'],$details['resource']);

                //search for this signup
                $found = false;
                foreach ($dayssignup as $daykey=>$onesignup) {
                    if ($onesignup['usn']==$usn && $onesignup['signup']==$signup && $onesignup['priority']>1) {
                        $onesignup['resource']=$details['resource'];
                        promote(array($onesignup));
                        break;
                    }
                }
            }
        }
    }
}


//==============================================================================
//JMS 11/14/02
// -added complete am/pm clock support
//CBW 11/23/02
// -added function call to check for expired and inactive accounts 
//JMS 12/02/02
// -moved reconcileexpiredaccount here from functions
//JMS 2/23/03
// -modified reconciledexpiredaccounts to speed it up (repeated calls to lookupusn)
// -modified mailbackup to allow email of human-readable listing of signups 
// -email action log on schedule of backup (instead of every day)
// -modified format of action log
//JMS 3/02/03
// -added "announcementfile_name" to items to be backed up and restored
//JMS 4/8/03
// -added uselog.csv to list of files to backup
//JMS 7/9/03
// -use timezone offset in all references to zulutime
//JMS 8/17/03
// -add test for empty file in encode backup to avoid warning
//JMS 10/3/03
// -moved expire, restricted, and lastactivity into users
//JMS 10/6/03
// -fixed array_keys bug in reconcileexpiredaccounts
//JMS 12/15/03
// -fixed inactivate bug
//JMS 1/26/04
// -revised backup method
//JMS 2/7/04
// -added test for zlib in backup creation
// -force a minimum backup history of 24 hours
//JMS 2/19/04
// -removed limit of 24 hours backup history (bug anyway)
//JAT 3/25/04
// -added action log purging function
//JMS 4/23/04
// -changed to peace-meal building of backup file (less memory required)
//JMS 2/21/04
// -use validatedate to evaluate inactivity dates and expiration dates

?>
Return current item: ORS - On-line Resource Scheduler