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(); $this->email_fragments = get_fragments('./email-fragments.txt'); $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[] = $this->email_fragments['sv_new_loans_pickup']; $info_en[] = $this->email_fragments['en_new_loans_pickup']; } $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); $intro_sv = $this->email_fragments['sv_new_loans_intro']; $intro_en = $this->email_fragments['en_new_loans_intro']; $footer = $this->email_fragments['footer']; $message = <<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 replace(array('loan' => $loan, 'product' => $product), $this->email_fragments['sv_return_info']); break; case 'en': if($count > 1) { $loan = "loans"; $product = "items"; } else { $loan = "loan"; $product = "item"; } return replace(array('loan' => $loan, 'product' => $product), $this->email_fragments['en_return_info']); 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); $intro_sv = $this->email_fragments['sv_reminder_intro']; $intro_en = $this->email_fragments['en_reminder_intro']; $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); $info_en = implode("\n\n", $info_en); $returns_sv = $this->make_return_info('sv', $total); $returns_en = $this->make_return_info('en', $total); $footer = $this->email_fragments['footer']; $message = <<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); } } } ?>