boka3/include/Cron.php

351 lines
12 KiB
PHP

<?php
class Cron {
private $now = 0;
private $sender = '';
private $error = '';
private $kvs;
private $ldap;
public function __construct($sender, $error, $prefix) {
$this->now = new DateTimeImmutable();
$this->sender = $sender;
$this->error = $error;
$this->subject_prefix = $prefix;
$this->warn_time = DateInterval::createFromDateString('3 days');
$this->warn_date = $this->now->add($this->warn_time);
$this->run_interval = DateInterval::createFromDateString('1 day');
$this->kvs = new Kvs();
$this->ldap = new Ldap();
$days = $this->warn_time->d;
$this->strings = array(
'en' => array(
'new' => array(
'single' => "The following loan has been registered in your name:",
'multi' => "The following loans have been registered in your name:",
'expiry' => "expires on",
'serial' => "serial number",
),
'extend' => array(
'single' => "The following loan has been extended:",
'multi' => "The following loans have been extended:",
'expiry' => "extended to",
'serial' => "serial number",
),
'expiring' => array(
'single' => "The following loan expires in less than $days days:",
'multi' => "The following loans expire in less than $days days:",
'expiry' => "expires on",
'serial' => "serial number",
),
'overdue' => array(
'single' => "The following loan has expired:",
'multi' => "The following loans have expired:",
'expiry' => "expired on",
'serial' => "serial number",
),
),
'sv' => array(
'new' => array(
'single' => "Följande lån har registrerats på din användare:",
'multi' => "Följande lån har registrerats på din användare:",
'expiry' => "går ut",
'serial' => "artikelnummer",
),
'extend' => array(
'single' => "Följande lån har förlängts:",
'multi' => "Följande lån har förlängts:",
'expiry' => "förlängt till",
'serial' => "artikelnummer",
),
'expiring' => array(
'single' => "Följande lån går ut om mindre än $days dagar:",
'multi' => "Följande lån går ut om mindre än $days dagar:",
'expiry' => "går ut",
'serial' => "artikelnummer",
),
'overdue' => array(
'single' => "Följande lån har gått ut:",
'multi' => "Följande lån har gått ut:",
'expiry' => "gick ut",
'serial' => "artikelnummer",
),
),
);
}
public function run() {
$this->run_receipts();
$this->run_reminders();
}
private function run_receipts() {
begin_trans();
$get = prepare('select * from `pending_receipt`
where `send_time` < ?');
bind($get, 'i', $this->now->getTimestamp());
execute($get);
foreach(result_list($get) as $row) {
$user = new User($row['user']);
$since_time = $row['since_time'];
$new_loans = array();
$extended_loans = array();
foreach($user->get_loans('active') as $loan) {
if($loan->get_starttime() >= $since_time) {
$new_loans[] = $loan;
} else if($loan->get_last_extension() >= $since_time) {
$extended_loans[] = $loan;
}
}
if($new_loans || $extended_loans) {
$this->send_receipt($user, $new_loans, $extended_loans);
}
$delete = prepare('delete from `pending_receipt`
where `user` = ? and `send_time` < ?');
bind($delete, 'ii', $user->get_id(), $this->now->getTimestamp());
execute($delete);
}
commit_trans();
}
private function make_receipt_subject($num_new, $num_extended) {
$subject = $this->subject_prefix;
$messages = array();
if($num_new > 1) {
$messages[] = $num_new." nya";
} else if($num_new > 0) {
$messages[] = $num_new." nytt";
}
if($num_extended > 1) {
$messages[] = $num_extended." förlängda";
} else if($num_extended > 0) {
$messages[] = $num_extended." förlängt";
}
return $subject.implode(" och ", $messages)." lån";
}
private function send_receipt($user, $new, $extended) {
$uid = $user->get_name();
$name = $this->ldap->get_firstname($uid);
$new_count = count($new);
$extended_count = count($extended);
$subject = $this->make_receipt_subject($new_count, $extended_count);
$list_sv = array();
$list_en = array();
if($new_count > 0) {
$list_sv[] = $this->make_notice('sv', 'new', $new);
$list_en[] = $this->make_notice('en', 'new', $new);
}
if($extended_count > 0) {
$list_sv[] = $this->make_notice('sv', 'extend', $extended);
$list_en[] = $this->make_notice('en', 'extend', $extended);
}
$list_sv = implode("\n\n", $list_sv);
$list_en = implode("\n\n", $list_en);
$info_sv = array();
$info_en = array();
if($new_count > 0) {
$info_sv[] = "Eventuella artiklar du inte hämtat ut redan kan hämtas från Helpdesk.";
$info_en[] = "Any products you haven't already picked up can be collected from Helpdesk.";
}
$info_sv[] = "Svara på det här mailet om du har några frågor.";
$info_en[] = "Please reply to this email if you have any questions.";
$info_sv = implode(' ', $info_sv);
$info_en = implode(' ', $info_en);
$message = <<<EOF
Hej $name!
Det här är ett automatiskt meddelande från Helpdesk.
$list_sv
$info_sv
----
This is an automated message from Helpdesk.
$list_en
$info_en
Mvh
DSV Helpdesk
helpdesk@dsv.su.se
08 - 16 16 48
EOF;
$this->send_email($uid, $subject, $message);
}
private function run_reminders() {
$lastrun = $this->kvs->get_value('lastrun', 0);
$nextrun = $this->now
->setTimestamp($lastrun)
->add($this->run_interval);
if($nextrun > $this->now) {
return;
}
$this->kvs->set_key('lastrun', $this->now->getTimestamp());
$users = get_items('user');
foreach($users as $user) {
$this->check_loans($user);
}
}
private function check_loans($user) {
$expiring = $user->get_expiring_loans($this->warn_date);
$overdue = $user->get_overdue_loans();
if($expiring || $overdue) {
$this->send_reminder($user, $expiring, $overdue);
}
}
private function make_reminder_subject($num_expiring, $num_expired) {
$subject = $this->subject_prefix;
$messages = array();
if($num_expiring > 0) {
$messages[] = $num_expiring." utgående";
}
if($num_expired > 1) {
$messages[] = $num_expired." försenade";
} elseif($num_expired > 0) {
$messages[] = $num_expired." försenat";
}
return $subject.implode(" och ", $messages)." lån";
}
private function make_notice($lang, $type, $list) {
if(!$list) {
return '';
}
if(!array_key_exists($lang, $this->strings)) {
throw new Exception("Invalid languange: $lang");
}
$strings = $this->strings[$lang];
if(!array_key_exists($type, $strings)) {
throw new Exception("Invalid type: $type");
}
$strings = $strings[$type];
$lines = array();
foreach($list as $loan) {
$product = $loan->get_product();
$serial = $product->get_serial();
$brand = $product->get_brand();
$name = $product->get_name();
$endtime = format_date($loan->get_endtime());
$lines[] = "$brand $name, ".$strings['serial']
." $serial, ".$strings['expiry']." $endtime";
}
$msg = $strings['single'];
if(count($list) > 1) {
$msg = $strings['multi'];
}
return $msg."\n\n".implode("\n", $lines);
}
private function make_return_info($lang, $count) {
switch($lang) {
case 'sv':
if($count > 1) {
$loan = "lånen";
$product = "artiklarna";
} else {
$loan = "lånet";
$product = "artikeln";
}
return "Vänligen kontakta Helpdesk för att förlänga $loan eller lämna tillbaka $product.";
break;
case 'en':
if($count > 1) {
$loan = "loans";
$product = "items";
} else {
$loan = "loan";
$product = "item";
}
return "Please contact Helpdesk in order to extend the $loan or return the $product.";
break;
default:
throw new Exception("Invalid language: ".$lang);
}
}
private function send_reminder($user, $expiring, $overdue) {
$uid = $user->get_name();
$name = $this->ldap->get_firstname($uid);
$expiring_count = count($expiring);
$overdue_count = count($overdue);
$total = $expiring_count + $overdue_count;
$subject = $this->make_reminder_subject($expiring_count,
$overdue_count);
$info_sv = array();
$info_en = array();
if($expiring_count > 0) {
$info_sv[] = $this->make_notice('sv', 'expiring', $expiring);
$info_en[] = $this->make_notice('en', 'expiring', $expiring);
}
if($overdue_count > 0) {
$info_sv[] = $this->make_notice('sv', 'overdue', $overdue);
$info_en[] = $this->make_notice('en', 'overdue', $overdue);
}
$info_sv = implode("\n\n", $info_sv);
$returns_sv = $this->make_return_info('sv', $total);
$info_en = implode("\n\n", $info_en);
$returns_en = $this->make_return_info('en', $total);
$message = <<<EOF
Hej $name!
Det här är en automatisk påminnelse om lånade artiklar från Helpdesk.
$info_sv
$returns_sv
----
This is an automated reminder regarding items on loan from Helpdesk.
$info_en
$returns_en
Mvh
DSV Helpdesk
helpdesk@dsv.su.se
08 - 16 16 48
EOF;
$this->send_email($uid, $subject, $message);
}
private function send_email($uid, $subject, $message) {
try {
mb_send_mail($this->ldap->get_user_email($uid),
$subject,
$message,
'From: '.$this->sender);
} catch(Exception $e) {
error_log($e->getMessage());
mb_send_mail($this->error,
"Kunde inte skicka mail",
"Mail kunde inte skickas till ".$uid);
}
}
}
?>