Coding standards
Security in ResourceSpace
Developer reference
Database
Action functions
Admin functions
Ajax functions
Annotation functions
API functions
Collections functions
Comment functions
Config functions
CSV export functions
Dash functions
Debug functions
Encryption functions
Facial recognition functions
File functions
General functions
Language functions
Log functions
Login functions
Message functions
Migration functions
Node functions
PDF functions
Plugin functions
Render functions
Reporting functions
Request functions
Research functions
Slideshow functions
Theme permission functions
User functions
Video functions
Database functions
Metadata functions
Resource functions
Search functions
Map functions
Job functions
Tab functions
Test functions

send_periodic_report_emails()

Description

Sends periodic report emails to users based on configured schedules.

This function checks for any scheduled reports that need to be sent, either because they are
pending or overdue. It gathers the necessary user email addresses, generates the reports,
and sends them as emails with attachments if applicable.

Parameters

ColumnTypeDefaultDescription
$echo_out bool true Determines whether to output progress messages during processing.
$toemail bool true Determines whether to send the reports via email.

Return

void

Location

include/reporting_functions.php lines 387 to 615

Definition

 
function send_periodic_report_emails($echo_out true$toemail=true)
    {
    
# For all configured periodic reports, send a mail if necessary.
    
global $lang,$baseurl$report_rows_zip_limit$email_notify_usergroups$userref;

    if (
is_process_lock("periodic_report_emails")) 
        {
        echo 
" - periodic_report_emails process lock is in place. Skipping.\n";
        return;
        }
    
    
set_process_lock("periodic_report_emails");

    
// Keep record of temporary CSV/ZIP files to delete after emails have been sent
    
$deletefiles = array();
    
$users = [];

    
# Query to return all 'pending' report e-mails, i.e. where we haven't sent one before OR one is now overdue.
    
$query "
        SELECT pe.ref,
               pe.user,
               pe.send_all_users,
               pe.user_groups,
               pe.report,
               pe.period,
               pe.email_days,
               pe.last_sent,
               pe.search_params,
               u.email,
               r.name
          FROM report_periodic_emails pe
          JOIN user u ON pe.user = u.ref
          JOIN report r ON pe.report = r.ref
         WHERE pe.last_sent IS NULL
            OR (date_add(date(pe.last_sent), INTERVAL pe.email_days DAY) <= date(now()) AND pe.email_days > 0);
    "
;
    
$reports=ps_query($query);

    foreach (
$reports as $report)
        {
        
$start=time()-(60*60*24*$report["period"]);

        
$from_y date("Y",$start);
        
$from_m date("m",$start);
        
$from_d date("d",$start);

        
$to_y date("Y");
        
$to_m date("m");
        
$to_d date("d");

        
// Send e-mail reports to users belonging to the specific user groups
        
if(empty($report['user_groups']))
            {
            if (
$report['send_all_users'])
                {
                
// Send to all users is deprecated. Send to $email_notify_usergroups or Super Admin if not set
                
if (!empty($email_notify_usergroups))
                    {
                    foreach (
$email_notify_usergroups as $usergroup)
                        {
                        if(
get_usergroup($usergroup)!==false)
                            {
                            
$addusers get_users($usergroup,"","u.username",false,-1,1);
                            
$users array_merge($users,$addusers);
                            }
                        }
                    }
                else
                    {
                    
$users get_notification_users("SYSTEM_ADMIN");
                    }
                }
            }
        else
            {
            
$users get_users($report['user_groups'],"","u.username",false,-1,1);
            }
        
        
// Always add original report creator
        
$creator get_user($report['user']);
        
$users[] = $creator;
        
$sentousers  = []; 
        if(isset(
$userref))
            {
            
// Store current user before emulating each to get report
            
$saveduserref $userref;
            }

        
// Get unsubscribed users
        
$unsubscribed ps_array(
                
'SELECT user_id as `value` 
                FROM report_periodic_emails_unsubscribe 
                WHERE periodic_email_id = ?'
,
                [
"i",$report['ref']]);

        
$reportcache null;
        foreach(
$users as $user)
            {
            if(
in_array($user["ref"],$unsubscribed) || in_array($user["ref"],$sentousers))
                {
                
// User has unsubscribed from this report or already been sent it
                
continue;
                }

            
// Check valid email
            
$email $user['email'];
            if(!
filter_var($emailFILTER_VALIDATE_EMAIL))
                {
                continue;
                }

            
// Construct and run the report
            // Emulate the receiving user so language text strings are translated and search results take into account any permissions and filters
            
emulate_user($user["ref"]);
            
$userref $user["ref"];
    
            
// Translates the report name.
            
$report["name"] = lang_or_i18n_get_translated($report["name"], "report-");

            
$search_params = (trim($report['search_params']??"") !== '' json_decode($report['search_params'], true) : []);

            
$static_report true// If no dynamic search results are included then the same report results can be used for all  recipients

            
if(!empty($search_params))
                {
                
$static_report false// Report may vary so cannot be cached
                
}
            
            
# Generate report (table or CSV)
            
if($static_report && isset($reportcache))
                {
                
$output $reportcache["output"];
                
$reportfiles $reportcache["reportfiles"];
                }
            else
                {
                
$output do_report($report["report"], $from_y$from_m$from_d$to_y$to_m$to_d,false,true$toemail$search_params);

                if(empty(
$output))
                    {
                    
// No data, maybe no access to search results
                    
$output "<br/>" $lang["reportempty"] . "<br/>";
                    }
                
$reportfiles = [];
                
// If report is large, make it an attachment (requires $use_phpmailer=true)
                
if(is_array($output) && isset($output["file"]))
                    {
                    
$deletefiles[] = $output["file"];
                    
// Include the file as an attachment
                    
if($output["rows"] > $report_rows_zip_limit)
                        {
                        
// Convert to  zip file
                        
$unique_id=uniqid();
                        
$zipfile get_temp_dir(false"Reports") . "/Report_" $unique_id ".zip";
                        
$zip = new ZipArchive();
                        
$zip->open($zipfileZIPARCHIVE::CREATE);
                        
$zip->addFile($output["file"], $output["filename"]);

                        
$zip->close();
                        
$deletefiles[] = $zipfile;
                        
$zipname str_replace(".csv",".zip"$output["filename"]);
                        
$reportfiles[$zipname] = $zipfile;
                        }
                    else
                        {
                        
$reportfiles[$output["filename"]] = $output["file"];
                        }
                    }
                if(
$static_report)
                    {
                    
$reportcache["output"] = $output;
                    
$reportcache["reportfiles"] = $reportfiles;
                    }
                }

            
// Formulate a title
            
$title $report["name"] . ": " str_replace("?",$report["period"],$lang["lastndays"]);
            if(!empty(
$reportfiles))
                {
                
$output str_replace("[report_title]"$title$lang["report_periodic_email_report_attached"]);
                }

            
$unsubscribe_url generateURL($baseurl,["ur"=>$report["ref"],"u"=>$user["ref"]]);
            
$unsubscribe_link sprintf(
                
"<br />%s<br /><a href=\"%s\" target=\"_blank\">%s</a>",
                
$lang["unsubscribereport"],$unsubscribe_url,$unsubscribe_url
            
);

            if (
$echo_out)
                {
                echo 
escape($lang["sendingreportto"]) . " " $email "<br />" $output $unsubscribe_link "<br />";
                }

            
$delete_link "";
            if ((int)
$user['ref'] == (int)$report["user"])
                {
                
// Add a delete link to the report
                
$delete_link "<br />" $lang["report_delete_periodic_email_link"] . "<br /><a href=\"" $baseurl "/?dr=" $report["ref"] . "\" target=\"_blank\">" $baseurl "/?dr=" $report["ref"] . "</a>";
                }
            
send_mail($email,$title,$output $delete_link  $unsubscribe_link,"","","","","","","",$reportfiles);
            
$sentousers[] =  $user['ref'];          
            }

        if(isset(
$saveduserref))
            {
            
$userref $saveduserref;
            
emulate_user($userref);
            }

        
# Mark as done.
        
ps_query('UPDATE report_periodic_emails set last_sent = now() where ref = ?',array("i",$report['ref']));
        }

    
$GLOBALS["use_error_exception"] = true;
    foreach(
$deletefiles as $deletefile)
        {
        try
            {
            
unlink($deletefile);
            }
        catch(
Exception $e)
            {
            
debug("Unable to delete - file not found: " $deletefile);
            }
        }
    unset(
$GLOBALS["use_error_exception"]);

    
clear_process_lock("periodic_report_emails");
    }

This article was last updated 4th December 2024 08:35 Europe/London time based on the source file dated 7th November 2024 17:40 Europe/London time.