source: t29-www/lib/mail/mailer.php @ 411

Last change on this file since 411 was 411, checked in by sven, 11 years ago

Terminanmeldung: Weiterer Bugfix im Programm, Designfix.

File size: 8.9 KB
Line 
1<?php
2
3/**
4 * New generic formmailer for technikum29 infrastructure
5 **/
6
7$maillib = dirname(__FILE__);
8require "$maillib/recaptchalib.php";
9require "$maillib/recaptcha_keys.php";
10 
11// This script can be used as standalone or libary.
12if(realpath($_SERVER['SCRIPT_FILENAME']) == __FILE__) {
13        $mailer = new t29Mailer($_REQUEST);
14        $mailer->run();
15}
16
17class t29Mailer {
18        function print_usage() {
19                // problem: vars kriegt man nicht global, require include raum auch nicht global.
20                // bad design.
21                /*global $seiten_id, $version, $titel, $dynamischer_inhalt, $lib;
22                $seiten_id = 'mailer';
23                $version = '$Id$';
24                $titel = "t29v6 form mailer usage";
25                $dynamischer_inhalt = true;
26
27                $lib = "./";
28                require "$lib/technikum29.php";*/
29?>
30<html>
31<h2>Usage</h2>
32
33<p>This small mail system is capable of:
34
35<ul>
36        <li>Mail to upstream and acknowledgement mail back to sender
37        <li>Template based or individual output page with arguments
38</ul>
39
40
41<h3>Get or Post variables</h3>
42<table>
43<tr><th>name <th>default value <th>interpretation
44<tr><th>to   <td>sven          <td>one e-mail prefix, will be used with <tt>@technikum29.de</tt>,
45                                   so mail goes to e.g. <tt>thevalue@technikum29.de</tt>.
46<tr><th>subject <td>           <td>Subject of the mail. Can contain template variables like {foo}, where foo is some other
47                                   variable.
48<tr><th>body<td>                <td>Body of the mail. Can contain template variables.
49                                   
50
51<tr><th>ack   <td>false/no      <td>Give true/yes for sending an ack mail.
52<tr><th>ack_to <td>            <td>Target adress to send acknowledgement mail to. Can contain template variables like {data_sender_mail}.
53<tr><th>ack_subject <td>       <td>Like subject, but for ack mail.
54<tr><th>ack_body <td>    <td>Like body.
55
56
57</table>
58
59        <?php } // end of method print_usage()
60       
61        // the small data holding architecture
62        public $_values;
63        #private $default_values;
64       
65        function __construct(Array $data=array()) {
66                // default values
67                $default_values = array(
68                        "to" => "sven",
69                        "subject" => "technikum29 form mailer",
70                        "body" => null,
71                        "ack" => false,
72                       
73                        'header' => null, // has to be array
74                       
75                        "output_success_page" => '<html><h2>Mail successfully sent</h2><p>Thank you for your mail.</p>',
76                        "output_error_page" => function($mailer, $error) {
77                                ?><html>
78                                <h1>Errors in mail</h1>
79                                <form method="POST">
80                                        <p>Please fill out this captcha to send the mail. We don't like spam:</p>
81                                        <?php $mailer->print_serialized_hidden_form(); ?>
82                                        <?php echo $error; ?>
83                                        <input type="submit" value="Yes I am human">
84                                </form><?php
85                        },
86                       
87                        "mail_info_append_text" => function($mailer) {
88                                $time = date('r');
89                                $ret = <<<EOT
90
91Diese Mail wurde mit einem der technikum29 Web-Form-Mailer geschickt,
92und zwar dem t29v6-NG Formmailer. Ein Besucher hat also auf einer Webseite
93im technikum29.de-Angebot ein Formular ausgefüllt und daraufhin wurde
94diese Mail verschickt.
95
96Adresse wo Benutzer herkam: $_SERVER[HTTP_REFERER]
97Zeit, zu der der Besucher die Mail verschickte: $time
98Browser des Benutzers (User-Agent): $_SERVER[HTTP_USER_AGENT]
99IP-Adresse des Besuchers: $_SERVER[REMOTE_ADDR]
100
101EOT;
102
103                                if($mailer->ack) $ret .= <<<EOT1
104
105Der Besucher bekam dafür eine Bestätigungsmail an die Adresse
106{$mailer->ack_to}  .
107
108EOT1;
109                                return $ret; },
110                       
111                        "recaptcha_challenge_field" => false,
112                        "recaptcha_response_field" => false
113                ); // end of default values
114               
115                // merge given values
116                $this->_values = array_merge($default_values, $data);
117        } // end of constructor
118       
119       
120        public function __set($property, $value){
121                return $this->_values[$property] = $value;
122        }
123
124        public function __get($property){
125                return array_key_exists($property, $this->_values)
126                        ? $this->_values[$property]
127                        #: #(array_key_exists($property, $this->default_values)
128                        #       ? $this->default_values[$property]
129                                : null;
130        }
131        public function __isset($property) {
132                return isset($this->$property) || isset($this->_values[$property]); # || isset($this->default_values[$property]);
133        }
134       
135        // the system
136        public function run() {
137                if(empty($this->_values)) {
138                        $this->print_usage();
139                        return;
140                }
141               
142                // check captcha and check presence of important field
143                if(!$this->to || !$this->body) {
144                        // bubu
145                }
146               
147                // show captcha validation, if neccessary
148                if(!$this->check_captcha()) {
149                        return false;
150                }
151               
152                // send the ACK mail, if appropriate
153                if($this->ack) {
154                        $this->ack_to = $this->call_or_return_callback('ack_to');
155                        $this->ack_subject = $this->call_or_return_callback('ack_subject');
156                        $this->ack_body = $this->call_or_return_callback('ack_body');
157                        $this->send_mail($this->ack_to, $this->ack_subject, $this->ack_body);
158                }
159               
160                // send the mail to t29
161                $this->to .= '@technikum29.de';
162                $this->body = $this->call_or_return_callback('body');
163                $this->body .= $this->call_or_return_callback('mail_info_append_text');
164                $this->send_mail($this->to, $this->subject, $this->body);
165               
166                // show output page
167                $this->show_output_page('success');
168               
169                return true;
170        }
171       
172        public function send_mail($to, $subject, $message_body)  {
173                // compose the header
174                if(!$this->header) $this->header = array();
175                $testset = function($k, $v) { if(!isset($this->_values['header'][$k])) $this->_values['header'][$k] = $v; };
176               
177                $testset('To', $to);
178                $testset('Content-Type', 'text/plain; charset=UTF-8'); // all t29v6 is utf-8 based!
179                $testset('From', 'technikum29 Computer Musem Webmailer <www@technikum29.de>');
180               
181                $additional_headers = join("\r\n", array_map(function($k) { return "$k: ".$this->header[$k]; }, array_keys($this->header)));
182       
183                // debug output
184                $debug_mail = function($t, $s, $m, $a) {
185                        print "<div class='hidden'>";
186                        print "<h2>Debug Mail Output</h2>";
187                        print "<dl><dt>To<dd>$t <dt>Subject <dd>$s <dt>Message <dd><pre>$m</pre> <dt>Add. Headers <dd><pre>$a</pre></dl>";
188                        print "</div>";
189                };
190               
191                $debug_mail($to, $subject, $message_body, $additional_headers);
192                mail($to, $subject, $message_body, $additional_headers);
193        }
194       
195
196        public static function recaptcha_get_publickey() {
197                global $publickey;
198                return $publickey;
199        }
200        public static function recaptcha_get_html() {
201                global $publickey;
202                return recaptcha_get_html($publickey);
203        }
204       
205        public function print_serialized_hidden_form() {
206                // serialize obect to hidden form elements
207                foreach($this->_values as $k => $v) {
208                        if(!is_string($v)) continue;
209                        printf("\t<input type='hidden' name='%s' value='%s'>\n", $k, htmlentities($v, ENT_QUOTES | ENT_HTML401));
210                }
211        }
212       
213        public function call_or_return_callback($property, $additional_argument=null) {
214                if(!isset($this->_values[$property]))
215                        return null;
216                if(is_callable($this->_values[$property])) {
217                        return call_user_func($this->_values[$property], $this, $additional_argument);
218                }
219                elseif(is_string($this->_values[$property])) {
220                        // make string replacements
221                        $mailer = $this; // PHP 5.3 convenience
222                        return preg_replace_callback("/\{([^}]+)\}/", function($match) use ($mailer) {
223                                $identifier = $match[1];
224                                return isset($mailer->_values[$identifier])
225                                        ? $mailer->_values[$identifier]
226                                        : "{?$identifier?}";
227                        }, $this->_values[$property]);
228                }
229               
230        }
231       
232        public function call_or_print_callback($property, $additional_argument=null) {
233                $ret = $this->call_or_return_callback($property, $additional_argument);
234                if($ret != null) print $ret;
235                return true;
236        }
237       
238        public function show_output_page($type, $additional_argument=null) {
239                $id = "output_${type}_page";
240                $this->call_or_print_callback($id, $additional_argument);
241        }
242       
243
244        /**
245         * Check the Recaptcha challenge status and display an error page if
246         * neccessary
247         **/
248        public function check_captcha() {
249                global $publickey;
250                $resp = $this->check_captcha_answer();
251               
252                if($resp === null) {
253                        $page = recaptcha_get_html($publickey);
254                        $this->show_output_page('error', $page);
255                        return false;
256                } else if(!$resp->is_valid) {
257                        // display page
258                        $page = recaptcha_get_html($publickey, $resp->error);
259                        $this->show_output_page('error', $page);
260                        return false;
261                } else {
262                        // valid answer
263                        return true;
264                }
265        }
266       
267        /**
268         * Check the Captcha challenge field.
269         * Return value is a Response object which basically allows to
270         * differ three states:
271         *   $ret == null => no challenge answer present
272         *   $ret->is_valid == true => captcha answered valid (human detected)
273         *   $ret->is_valud == false => captcha answered false (no human detected)
274         *
275         * You can use $ret->error for a further call of
276         *   recaptcha_get_html($publickey, $ret->error);
277         *
278         * @returns librecaptcha Result object
279         **/
280        public function check_captcha_answer() {
281                global $publickey, $privatekey;
282               
283                # the response from reCAPTCHA
284                $resp = null;
285                # the error code from reCAPTCHA, if any
286                $error = null;
287                # display captcha? default: yes!
288                $display_captcha = true;
289
290                if(!$this->recaptcha_challenge_field || !$this->recaptcha_response_field)
291                        return null;
292       
293                $resp = recaptcha_check_answer ($privatekey,
294                        $_SERVER["REMOTE_ADDR"],
295                        $this->recaptcha_challenge_field,
296                        $this->recaptcha_response_field);
297                return $resp;
298        }
299} // end of class t29Mailer
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License