1
|
|
|
<?php declare(strict_types=1); |
2
|
|
|
|
3
|
|
|
namespace XoopsModules\Xhelp; |
4
|
|
|
|
5
|
|
|
/* |
6
|
|
|
* You may not change or alter any portion of this comment or credits |
7
|
|
|
* of supporting developers from this source code or any supporting source code |
8
|
|
|
* which is considered copyrighted (c) material of the original comment or credit authors. |
9
|
|
|
* |
10
|
|
|
* This program is distributed in the hope that it will be useful, |
11
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @copyright {@link https://xoops.org/ XOOPS Project} |
17
|
|
|
* @license {@link https://www.gnu.org/licenses/gpl-2.0.html GNU GPL 2 or later} |
18
|
|
|
* @author Eric Juden <[email protected]> |
19
|
|
|
* @author XOOPS Development Team |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* class EmailStore |
24
|
|
|
*/ |
25
|
|
|
class EmailStore |
26
|
|
|
{ |
27
|
|
|
public $responseHandler; |
28
|
|
|
public $ticketHandler; |
29
|
|
|
public $mailEventHandler; |
30
|
|
|
public $_errors; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* EmailStore constructor. |
34
|
|
|
*/ |
35
|
|
|
public function __construct() |
36
|
|
|
{ |
37
|
|
|
$helper = Helper::getInstance(); |
38
|
|
|
$this->responseHandler = $helper->getHandler('Response'); |
39
|
|
|
/** @var TicketHandler $this- >ticketHandler */ |
40
|
|
|
$this->ticketHandler = $helper->getHandler('Ticket'); |
41
|
|
|
/** @var MailEventHandler $this- >mailEventHandler */ |
42
|
|
|
$this->mailEventHandler = $helper->getHandler('MailEvent'); |
43
|
|
|
$this->_errors = []; |
44
|
|
|
} |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @param string|array $desc |
48
|
|
|
*/ |
49
|
|
|
public function _setError($desc): void |
50
|
|
|
{ |
51
|
|
|
if (\is_array($desc)) { |
52
|
|
|
foreach ($desc as $d) { |
53
|
|
|
$this->_errors[] = $d; |
54
|
|
|
} |
55
|
|
|
} |
56
|
|
|
$this->_errors[] = $desc; |
57
|
|
|
} |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @return array|int |
61
|
|
|
*/ |
62
|
|
|
public function _getErrors() |
63
|
|
|
{ |
64
|
|
|
if (\count($this->_errors) > 0) { |
65
|
|
|
return $this->_errors; |
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return 0; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* |
73
|
|
|
*/ |
74
|
|
|
public function clearErrors(): void |
75
|
|
|
{ |
76
|
|
|
$this->_errors = []; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* |
81
|
|
|
*/ |
82
|
|
|
public function renderErrors(): void |
83
|
|
|
{ |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Store the parsed message in database |
88
|
|
|
* @param ParsedMessage $msg {@link ParsedMessage} object Message to add |
89
|
|
|
* @param \XoopsUser $user {@link xoopsUser} object User that submitted message |
90
|
|
|
* @param DepartmentMailBox $mbox {@link DepartmentMailBox} object. Originating Mailbox for message |
91
|
|
|
* @param mixed $errors |
92
|
|
|
* @return array|false Returns <a href='psi_element://Ticket'>Ticket</a> object if new ticket, <a href='psi_element://Response'>Response</a> object if a response, and false if unable to save. |
93
|
|
|
*/ |
94
|
|
|
public function storeMsg(ParsedMessage $msg, \XoopsUser $user, DepartmentMailBox $mbox, &$errors) |
95
|
|
|
{ |
96
|
|
|
//Remove any previous error messages |
97
|
|
|
$this->clearErrors(); |
98
|
|
|
|
99
|
|
|
$type = $msg->getMsgType(); |
100
|
|
|
switch ($type) { |
101
|
|
|
case _XHELP_MSGTYPE_TICKET: |
102
|
|
|
$obj = $this->ticketHandler->create(); |
103
|
|
|
$obj->setVar('uid', $user->getVar('uid')); |
104
|
|
|
$obj->setVar('subject', $msg->getSubject()); |
105
|
|
|
$obj->setVar('description', $msg->getMsg()); |
106
|
|
|
$obj->setVar('department', $mbox->getVar('departmentid')); |
107
|
|
|
$obj->setVar('priority', $mbox->getVar('priority')); |
108
|
|
|
$obj->setVar('posted', \time()); |
109
|
|
|
$obj->setVar('serverid', $mbox->getVar('id')); |
110
|
|
|
$obj->setVar('userIP', 'via Email'); |
111
|
|
|
$obj->setVar('email', $user->getVar('email')); |
112
|
|
|
if (!$status = Utility::getMeta('default_status')) { |
113
|
|
|
Utility::setMeta('default_status', '1'); |
114
|
|
|
$status = 1; |
115
|
|
|
} |
116
|
|
|
$obj->setVar('status', $status); |
117
|
|
|
$obj->createEmailHash($msg->getEmail()); |
|
|
|
|
118
|
|
|
if ($this->ticketHandler->insert($obj)) { |
119
|
|
|
$obj->addSubmitter($user->getVar('email'), $user->getVar('uid')); |
|
|
|
|
120
|
|
|
$this->saveAttachments($msg, $obj->getVar('id')); |
121
|
|
|
|
122
|
|
|
$errors = $this->_getErrors(); |
123
|
|
|
|
124
|
|
|
return [$obj]; |
125
|
|
|
} |
126
|
|
|
break; |
127
|
|
|
case _XHELP_MSGTYPE_RESPONSE: |
128
|
|
|
if (!$ticket = $this->ticketHandler->getTicketByHash($msg->getHash())) { |
129
|
|
|
$this->_setError(\_XHELP_RESPONSE_NO_TICKET); |
130
|
|
|
|
131
|
|
|
return false; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
if ($msg->getEmail() != $ticket->getVar('email')) { |
135
|
|
|
$this->_setError(\sprintf(\_XHELP_MISMATCH_EMAIL, $msg->getEmail(), $ticket->getVar('email'))); |
|
|
|
|
136
|
|
|
|
137
|
|
|
return false; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$obj = $this->responseHandler->create(); |
141
|
|
|
$obj->setVar('ticketid', $ticket->getVar('id')); |
142
|
|
|
$obj->setVar('uid', $user->getVar('uid')); |
143
|
|
|
$obj->setVar('message', $msg->getMsg()); |
144
|
|
|
$obj->setVar('updateTime', \time()); |
145
|
|
|
$obj->setVar('userIP', 'via Email'); |
146
|
|
|
|
147
|
|
|
if ($this->responseHandler->insert($obj)) { |
148
|
|
|
$this->saveAttachments($msg, $ticket->getVar('id'), $obj->getVar('id')); |
149
|
|
|
$ticket->setVar('lastUpdated', \time()); |
150
|
|
|
$this->ticketHandler->insert($ticket); |
151
|
|
|
|
152
|
|
|
$errors = $this->_getErrors(); |
153
|
|
|
|
154
|
|
|
return [$ticket, $obj]; |
155
|
|
|
} |
156
|
|
|
break; |
157
|
|
|
default: |
158
|
|
|
//Sanity Check, should never get here |
159
|
|
|
} |
160
|
|
|
|
161
|
|
|
return false; |
162
|
|
|
} |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* @param ParsedMessage $msg |
166
|
|
|
* @param int $ticketid |
167
|
|
|
* @param int $responseid |
168
|
|
|
*/ |
169
|
|
|
public function saveAttachments(ParsedMessage $msg, int $ticketid, int $responseid = 0): void |
170
|
|
|
{ |
171
|
|
|
$helper = Helper::getInstance(); |
172
|
|
|
|
173
|
|
|
$attachments = $msg->getAttachments(); |
174
|
|
|
$dir = XOOPS_UPLOAD_PATH . '/xhelp'; |
175
|
|
|
$prefix = (0 != $responseid ? $ticketid . '_' . $responseid . '_' : $ticketid . '_'); |
176
|
|
|
/** @var \XoopsModules\Xhelp\MimetypeHandler $mimetypeHandler */ |
177
|
|
|
$mimetypeHandler = $helper->getHandler('Mimetype'); |
178
|
|
|
$allowed_mimetypes = $mimetypeHandler->getArray(); |
179
|
|
|
|
180
|
|
|
if (!\is_dir($dir)) { |
181
|
|
|
if (!\mkdir($dir, 0757) && !\is_dir($dir)) { |
182
|
|
|
throw new \RuntimeException(\sprintf('Directory "%s" was not created', $dir)); |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
$dir .= '/'; |
187
|
|
|
|
188
|
|
|
if ($helper->getConfig('xhelp_allowUpload')) { |
189
|
|
|
/** @var \XoopsModules\Xhelp\FileHandler $fileHandler */ |
190
|
|
|
$fileHandler = $helper->getHandler('File'); |
191
|
|
|
foreach ($attachments as $attach) { |
192
|
|
|
$validators = []; |
193
|
|
|
|
194
|
|
|
//Create Temporary File |
195
|
|
|
$fname = $prefix . $attach['filename']; |
196
|
|
|
$fp = \fopen($dir . $fname, 'wb'); |
197
|
|
|
\fwrite($fp, $attach['content']); |
198
|
|
|
\fclose($fp); |
199
|
|
|
|
200
|
|
|
$validators[] = new Validation\ValidateMimeType($dir . $fname, $attach['content-type'], $allowed_mimetypes); |
201
|
|
|
$validators[] = new Validation\ValidateFileSize($dir . $fname, $helper->getConfig('xhelp_uploadSize')); |
|
|
|
|
202
|
|
|
$validators[] = new Validation\ValidateImageSize($dir . $fname, $helper->getConfig('xhelp_uploadWidth'), $helper->getConfig('xhelp_uploadHeight')); |
|
|
|
|
203
|
|
|
|
204
|
|
|
if (Utility::checkRules($validators, $errors)) { |
205
|
|
|
//Add attachment to ticket |
206
|
|
|
|
207
|
|
|
/** @var \XoopsModules\Xhelp\File $file */ |
208
|
|
|
$file = $fileHandler->create(); |
209
|
|
|
$file->setVar('filename', $fname); |
210
|
|
|
$file->setVar('ticketid', $ticketid); |
211
|
|
|
$file->setVar('mimetype', $attach['content-type']); |
212
|
|
|
$file->setVar('responseid', $responseid); |
213
|
|
|
$fileHandler->insert($file, true); |
214
|
|
|
} else { |
215
|
|
|
//Remove the file |
216
|
|
|
$this->addAttachmentError($errors, $msg, $fname); |
217
|
|
|
\unlink($dir . $fname); |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
} else { |
221
|
|
|
$this->_setError(\_XHELP_MESSAGE_UPLOAD_ALLOWED_ERR); // Error: file uploading is disabled |
222
|
|
|
} |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
/** |
226
|
|
|
* @param array $errors |
227
|
|
|
* @param ParsedMessage $msg |
228
|
|
|
* @param string $fname |
229
|
|
|
*/ |
230
|
|
|
public function addAttachmentError(array $errors, ParsedMessage $msg, string $fname): void |
231
|
|
|
{ |
232
|
|
|
if (0 != $errors) { |
|
|
|
|
233
|
|
|
$aErrors = []; |
234
|
|
|
foreach ($errors as $err) { |
235
|
|
|
if (\in_array($err, $aErrors)) { |
236
|
|
|
continue; |
237
|
|
|
} |
238
|
|
|
$aErrors[] = $err; |
239
|
|
|
} |
240
|
|
|
$error = \implode(', ', $aErrors); |
241
|
|
|
$this->_setError(\sprintf(\_XHELP_MESSAGE_UPLOAD_ERR, $fname, $msg->getEmail(), $error)); |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
} |
245
|
|
|
|