PageRenderTime 2ms CodeModel.GetById 272ms app.highlight 6ms RepoModel.GetById 114ms app.codeStats 0ms

/lib/classes/message/inbound/handler.php

https://bitbucket.org/moodle/moodle
PHP | 306 lines | 111 code | 30 blank | 165 comment | 15 complexity | ee2ad4ea97f7b6b3e62a537bceb70a05 MD5 | raw file
  1<?php
  2// This file is part of Moodle - http://moodle.org/
  3//
  4// Moodle is free software: you can redistribute it and/or modify
  5// it under the terms of the GNU General Public License as published by
  6// the Free Software Foundation, either version 3 of the License, or
  7// (at your option) any later version.
  8//
  9// Moodle is distributed in the hope that it will be useful,
 10// but WITHOUT ANY WARRANTY; without even the implied warranty of
 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 12// GNU General Public License for more details.
 13//
 14// You should have received a copy of the GNU General Public License
 15// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
 16
 17/**
 18 * Abstract class describing Inbound Message Handlers.
 19 *
 20 * @package    core_message
 21 * @copyright  2014 Andrew Nicols
 22 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 23 */
 24namespace core\message\inbound;
 25
 26/**
 27 * Abstract class describing Inbound Message Handlers.
 28 *
 29 * @copyright  2014 Andrew NIcols
 30 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 31 *
 32 * @property-read int $id The ID of the handler in the database
 33 * @property-read string $component The component of this handler
 34 * @property-read int $defaultexpiration Default expiration of new addresses for this handler
 35 * @property-read string $description The description of this handler
 36 * @property-read string $name The name of this handler
 37 * @property-read bool $validateaddress Whether the address validation is a requiredment
 38 * @property-read bool $enabled Whether this handler is currently enabled
 39 * @property-read string $classname The name of handler class
 40 */
 41abstract class handler {
 42
 43    /**
 44     * @var int $id The id of the handler in the database.
 45     */
 46    private $id = null;
 47
 48    /**
 49     * @var string $component The component to which this handler belongs.
 50     */
 51    private $component = '';
 52
 53    /**
 54     * @var int $defaultexpiration The default expiration time to use when created a new key.
 55     */
 56    private $defaultexpiration = WEEKSECS;
 57
 58    /**
 59     * @var bool $validateaddress Whether to validate the sender address when processing this handler.
 60     */
 61    private $validateaddress = true;
 62
 63    /**
 64     * @var bool $enabled Whether this handler is currently enabled.
 65     */
 66    private $enabled = false;
 67
 68    /**
 69     * @var $accessibleproperties A list of the properties which can be read.
 70     */
 71    private $accessibleproperties = array(
 72        'id' => true,
 73        'component' => true,
 74        'defaultexpiration' => true,
 75        'validateaddress' => true,
 76        'enabled' => true,
 77    );
 78
 79    /**
 80     * Magic getter to fetch the specified key.
 81     *
 82     * @param string $key The name of the key to retrieve
 83     */
 84    public function __get($key) {
 85        // Some properties have logic behind them.
 86        $getter = 'get_' . $key;
 87        if (method_exists($this, $getter)) {
 88            return $this->$getter();
 89        }
 90
 91        // Check for a commonly accessibly property.
 92        if (isset($this->accessibleproperties[$key])) {
 93            return $this->$key;
 94        }
 95
 96        // Unknown property - bail.
 97        throw new \coding_exception('unknown_property ' . $key);
 98    }
 99
100    /**
101     * Set the id name.
102     *
103     * @param int $id The id to set
104     * @return int The newly set id
105     */
106    public function set_id($id) {
107        return $this->id = $id;
108    }
109
110    /**
111     * Set the component name.
112     *
113     * @param string $component The component to set
114     * @return string The newly set component
115     */
116    public function set_component($component) {
117        return $this->component = $component;
118    }
119
120    /**
121     * Whether the current handler allows changes to the address validation
122     * setting.
123     *
124     * By default this will return true, but for some handlers it may be
125     * necessary to disallow such changes.
126     *
127     * @return boolean
128     */
129    public function can_change_validateaddress() {
130        return true;
131    }
132
133    /**
134     * Set whether validation of the address is required.
135     *
136     * @param bool $validateaddress The new state of validateaddress
137     * @return bool
138     */
139    public function set_validateaddress($validateaddress) {
140        return $this->validateaddress = $validateaddress;
141    }
142
143    /**
144     * Whether the current handler allows changes to expiry of the generated email address.
145     *
146     * By default this will return true, but for some handlers it may be
147     * necessary to disallow such changes.
148     *
149     * @return boolean
150     */
151    public function can_change_defaultexpiration() {
152        return true;
153    }
154
155    /**
156     * Whether this handler can be disabled (or enabled).
157     *
158     * By default this will return true, but for some handlers it may be
159     * necessary to disallow such changes. For example, a core handler to
160     * handle rejected mail validation should not be disabled.
161     *
162     * @return boolean
163     */
164    public function can_change_enabled() {
165        return true;
166    }
167
168    /**
169     * Set the enabled name.
170     *
171     * @param bool $enabled The new state of enabled
172     * @return bool
173     */
174    public function set_enabled($enabled) {
175        return $this->enabled = $enabled;
176    }
177
178    /**
179     * Set the default validity for new keys.
180     *
181     * @param int $period The time in seconds before a key expires
182     * @return int
183     */
184    public function set_defaultexpiration($period) {
185        return $this->defaultexpiration = $period;
186    }
187
188    /**
189     * Get the non-namespaced name of the current class.
190     *
191     * @return string The classname
192     */
193    private function get_classname() {
194        $classname = get_class($this);
195        if (strpos($classname, '\\') !== 0) {
196            $classname = '\\' . $classname;
197        }
198
199        return $classname;
200    }
201
202    /**
203     * Return a description for the current handler.
204     *
205     * @return string
206     */
207    protected abstract function get_description();
208
209    /**
210     * Return a name for the current handler.
211     * This appears in the admin pages as a human-readable name.
212     *
213     * @return string
214     */
215    protected abstract function get_name();
216
217    /**
218     * Process the message against the current handler.
219     *
220     * @param \stdClass $record The Inbound Message Handler record
221     * @param \stdClass $messagedata The message data
222     */
223    public abstract function process_message(\stdClass $record, \stdClass $messagedata);
224
225    /**
226     * Return the content of any success notification to be sent.
227     * Both an HTML and Plain Text variant must be provided.
228     *
229     * If this handler does not need to send a success notification, then
230     * it should return a falsey value.
231     *
232     * @param \stdClass $messagedata The message data.
233     * @param \stdClass $handlerresult The record for the newly created post.
234     * @return \stdClass with keys `html` and `plain`.
235     */
236    public function get_success_message(\stdClass $messagedata, $handlerresult) {
237        return false;
238    }
239
240    /**
241     * Remove quoted message string from the text (NOT HTML) message.
242     *
243     * @param \stdClass $messagedata The Inbound Message record
244     *
245     * @return array message and message format to use.
246     */
247    protected static function remove_quoted_text($messagedata) {
248        if (!empty($messagedata->plain)) {
249            $text = $messagedata->plain;
250        } else {
251            $text = html_to_text($messagedata->html);
252        }
253        $messageformat = FORMAT_PLAIN;
254
255        $splitted = preg_split("/\n|\r/", $text);
256        if (empty($splitted)) {
257            return array($text, $messageformat);
258        }
259
260        $i = 0;
261        $flag = false;
262        foreach ($splitted as $i => $element) {
263            if (stripos($element, ">") === 0) {
264                // Quoted text found.
265                $flag = true;
266                // Remove 2 non empty line before this.
267                for ($j = $i - 1; ($j >= 0); $j--) {
268                    $element = $splitted[$j];
269                    if (!empty($element)) {
270                        unset($splitted[$j]);
271                        break;
272                    }
273                }
274                break;
275            }
276        }
277        if ($flag) {
278            // Quoted text was found.
279            // Retrieve everything from the start until the line before the quoted text.
280            $splitted = array_slice($splitted, 0, $i-1);
281
282            // Strip out empty lines towards the end, since a lot of clients add a huge chunk of empty lines.
283            $reverse = array_reverse($splitted);
284            foreach ($reverse as $i => $line) {
285                if (empty($line)) {
286                    unset($reverse[$i]);
287                } else {
288                    // Non empty line found.
289                    break;
290                }
291            }
292
293            $replaced = implode(PHP_EOL, array_reverse($reverse));
294            $message = trim($replaced);
295        } else {
296            // No quoted text, fallback to original text.
297            if (!empty($messagedata->html)) {
298                $message = $messagedata->html;
299                $messageformat = FORMAT_HTML;
300            } else {
301                $message = $messagedata->plain;
302            }
303        }
304        return array($message, $messageformat);
305    }
306}