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