1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
<?php
/* --------------------------------------------------------------
EmailsApiV2Controller.inc.php 2016-03-07
Gambio GmbH
http://www.gambio.de
Copyright (c) 2016 Gambio GmbH
Released under the GNU General Public License (Version 2)
[http://www.gnu.org/licenses/gpl-2.0.html]
--------------------------------------------------------------
*/
MainFactory::load_class('HttpApiV2Controller');
/**
* Class EmailsApiV2Controller
*
* This controller provides a gateway to the EmailService of the system. The user is able to get, send, queue
* and delete email records through his shop. Email forwarding is not directly supported but can be easily
* implemented by getting an existing email and then sending it with the updated contact addresses.
*
* API consumers can also upload attachments through the AttachmentsApiV2Controller and later use them within
* their emails. The upload operation must be executed before sending/queuing the email because it is not possible
* to send the email JSON data and upload a file at the same time. For more info see the AttachmentsV2Controller.
*
* @category System
* @package ApiV2Controllers
*/
class EmailsApiV2Controller extends HttpApiV2Controller
{
/**
* E-Mail service.
*
* @var EmailService
*/
protected $emailService;
/**
* E-Mail serializer.
*
* @var EmailJsonSerializer
*/
protected $emailSerializer;
/**
* Initialize controller components.
*/
protected function __initialize()
{
$this->emailService = StaticGXCoreLoader::getService('Email');
$this->emailSerializer = MainFactory::create('EmailJsonSerializer');
}
/**
* @api {post} /emails/:id Send Email
* @apiVersion 2.1.0
* @apiName SendEmail
* @apiGroup Emails
*
* @apiDescription
* This method will send and save a new or an existing email to the system. If you include mail attachments
* then they must already exist in the server. You will need to provide the full path to the file. To see an
* example usage take a look at
* `docs/REST/samples/email-service/send_email.php`
*
* @apiParamExample {json} Request-Body
* {
* "subject": "Test Subject",
* "sender": {
* "emailAddress": "sender@email.de",
* "contactName": "John Doe"
* },
* "recipient": {
* "emailAddress": "recipient@email.de",
* "contactName": "Jane Doe"
* },
* "replyTo": {
* "emailAddress": "reply_to@email.de",
* "contactName": "John Doe (Reply To)"
* },
* "contentHtml": "<strong>HTML Content</content>",
* "contentPlain": "Plain Content",
* "bcc": [
* {
* "emailAddress": "bcc@email.de",
* "contactName": "Chris Doe"
* }
* ],
* "cc": [
* {
* "emailAddress": "cc@email.de",
* "contactName": "Chloe Doe"
* }
* ],
* "attachments": [
* {
* "path": "/var/www/html/shop/uploads/attachments/1434614398/myfile.txt",
* "name": "Display For MyFile.txt"
* }
* ]
* }
*
* @apiParam {Number} [id] If provided then an existing email will be resend (only applies to URL).
* @apiParam {String} [subject] Email subject to be sent.
* @apiParam {Object} sender Contains the sender contact data.
* @apiParam {String} sender.emailAddress Sender's email address.
* @apiParam {String} [sender.contactName] Sender display name.
* @apiParam {Object} recipient Contains the recipient contact data.
* @apiParam {String} recipient.emailAddress Recipient's email address.
* @apiParam {String} [recipient.contactName] Recipient's display name.
* @apiParam {Object} replyTo Contains the reply to contact data.
* @apiParam {String} replyTo.emailAddress Email address of the 'Reply-To' contact.
* @apiParam {String} replyTo.contactName Name of the 'Reply-To' contact.
* @apiParam {String} [contentHtml] Email plain content.
* @apiParam {String} [contentPlain] Email HTML content.
* @apiParam {Array} [bcc] Contains the BCC contacts of the email.
* @apiParam {Array} [cc] Contains the CC contacts of the email.
* @apiParam {Array} [attachments] Contains the attachment data.
* @apiParam {String} attachments[].path The path to the attachments (the file must already exist in the server).
* @apiParam {String} [attachments[].name] Set a display name for the attachment file (must also contain
* the file extension).
*
* @apiSuccess (Success 201) Response-Body If successful, this method returns a complete email resource in the
* response body.
*
* @apiError 400-BadRequest Email data were not provided.
* @apiErrorExample Error-Response (400)
* HTTP/1.1 400 Bad Request
* {
* "code": 400,
* "status": "error",
* "message": "Email data were not provided."
* }
*
* @apiError 404-NotFound Email record was not found.
* @apiErrorExample Error-Response (404)
* HTTP/1.1 404 Not Found
* {
* "code": 404,
* "status": "error",
* "message": "Email record was not found."
* }
*/
public function post()
{
$emailJsonString = $this->api->request->getBody();
// Resend existing email without any changes.
if(isset($this->uri[1]) && is_numeric($this->uri[1]) && empty($emailJsonString))
{
$email = $this->emailService->findById(new IdType((int)$this->uri[1]));
if($email === null)
{
throw new HttpApiV2Exception('Email record was not found.', 404);
}
}
// Email json data were provided and they will be used to update the $baseObject.
else
{
if(empty($emailJsonString))
{
throw new HttpApiV2Exception('Email data were not provided.', 400);
}
$baseObject = null;
if(isset($this->uri[1]) && is_numeric($this->uri[1]))
{
$baseObject = $this->emailService->findById(new IdType((int)$this->uri[1]));
if($baseObject === null) // base object could not be found
{
throw new HttpApiV2Exception('Email record was not found.', 404);
}
// Ensure that the email has the correct email id of the request url
$emailJsonString = $this->_setJsonValue($emailJsonString, 'id', (int)$this->uri[1]);
}
$email = $this->emailSerializer->deserialize($emailJsonString, $baseObject);
}
// Send the email through the service.
$this->emailService->send($email);
// Return response to the client.
$this->_locateResource('emails', (string)$email->getId());
$this->_writeResponse($this->emailSerializer->serialize($email, false), 201);
}
/**
* @api {put} /emails Queue Email
* @apiVersion 2.1.0
* @apiName QueueEmail
* @apiGroup Emails
*
* @apiDescription
* This method will queue a new email so that it can be send later (with the POST method). See
* the "post" method for parameter description. To see an example usage take a look at
* `docs/REST/samples/email-service/queue_email.php`
*
* @apiSuccess (Success 200 - Email Was Queued) {String} Response-Body If successful, this
* method returns a complete email resource in the response body.
*
* @apiError 400-BadRequest Email data were not provided.
* @apiErrorExample Error-Response
* HTTP/1.1 400 Bad Request
* {
* "code": 400,
* "status": "error",
* "message": "Email data were not provided."
* }
*/
public function put()
{
$emailJsonString = $this->api->request->getBody();
if(empty($emailJsonString))
{
throw new HttpApiV2Exception('Email data were not provided.', 400);
}
// Parse the email.
$email = $this->emailSerializer->deserialize($emailJsonString);
// Queue the email to the database.
$this->emailService->queue($email);
// Return response to the client.
$this->_writeResponse($this->emailSerializer->serialize($email, false));
}
/**
* @todo Do not throw an error if a record does not exist. Because this is what other controllers do.
*
* @api {delete} /emails/:id Delete Email
* @apiVersion 2.1.0
* @apiName DeleteEmail
* @apiGroup Emails
*
* @apiDescription
* Delete an email record from database. To see an example usage take a look at
* `docs/REST/samples/email-service/remove_email.php`.
*
* @apiSuccess Response-Body If successful this method returns information about the deleted record.
*
* @apiExample {curl} Delete Email with ID = 572
* curl -X DELETE --user admin@shop.de:12345 http://shop.de/api.php/v2/emails/572
*
* @apiSuccessExample {json} Success-Response
* {
* "code": 200,
* "status": "success",
* "action": "delete",
* "emailId": 73
* }
*
* @apiError 400-BadRequest The email ID parameter is missing or is not valid.
*/
public function delete()
{
if(!isset($this->uri[1]) || !is_numeric($this->uri[1]))
{
throw new HttpApiV2Exception('Email record ID was not provided or is not valid in the requested URI.', 400);
}
$id = (int)$this->uri[1];
$email = $this->emailService->getById(new IdType($id));
$this->emailService->delete($email);
// Return response JSON.
$response = array(
'code' => 200,
'status' => 'success',
'action' => 'delete',
'emailId' => $id
);
$this->_writeResponse($response);
}
/**
* @api {get} /emails/:id Get Emails
* @apiVersion 2.1.0
* @apiName GetEmails
* @apiGroup Emails
*
* @apiDescription
* Get multiple or a single email record through the GET method. This resource supports
* the following GET parameters as described in the first section of documentation: sorting
* minimization, search, pagination. Additionally you can filter emails by providing the
* GET parameter "state=pending" or "state=sent". These filter parameters do not apply when
* a single emails record is selected (e.g. api.php/v2/emails/84) or when the emails are searched
* by the "q" parameter. To see an example usage take a look at
* `docs/REST/samples/email-service/fetch_email.php`
*
* @apiExample {curl} Get All Emails
* curl -i --user admin@shop.de:12345 http://shop.de/api.php/v2/emails
*
* @apiExample {curl} Get Email With ID = 527
* curl -i --user admin@shop.de:12345 http://shop.de/api.php/v2/emails/527
*
* @apiExample {curl} Get Pending Emails
* curl -i --user admin@shop.de:12345 http://shop.de/api.php/v2/emails?state=pending
*
* @apiExample {curl} Search Emails
* curl -i --user admin@shop.de:12345 http://shop.de/api.php/v2/emails?q=admin@shop.de
*
* @apiError 404-NotFound Email record not found.
*
* @apiErrorExample Error-Response
* HTTP/1.1 404 Not Found
* {
* "code": 404,
* "status": "error",
* "message": "Email record could not be found."
* }
*/
public function get()
{
$emails = MainFactory::create('EmailCollection');
// Get specific email record (email id was provided in the URL).
if(isset($this->uri[1]) && is_numeric($this->uri[1]))
{
$email = $this->emailService->findById(new IdType((int)$this->uri[1]));
if($email === null)
{
throw new HttpApiV2Exception('Email record could not be found.', 404);
}
$emails->add($email);
}
// Search email records (state filter cannot be applied).
else
{
if($this->api->request->get('q') !== null)
{
$emails = $this->emailService->filter($this->api->request->get('q'));
}
// Filter results by state ("pending" or "sent").
else
{
if($this->api->request->get('state') !== null)
{
$emails = ($this->api->request->get('state')
=== 'pending') ? $this->emailService->getPending() : $this->emailService->getSent();
}
// Get all the records without applying filters.
else
{
$emails = $this->emailService->getAll();
}
}
}
// Serialize email records to be returned with response.
$response = array();
foreach($emails->getArray() as $email)
{
$response[] = $this->emailSerializer->serialize($email, false);
}
// Apply common response filters.
$this->_sortResponse($response);
$this->_paginateResponse($response);
$this->_minimizeResponse($response);
// Check if a single resource was requested.
if(isset($this->uri[1]) && is_numeric($this->uri[1]) && count($response) > 0)
{
$response = $response[0];
}
$this->_writeResponse($response);
}
}