I am using CodeIgniter and I would like to store a representation of my emails in my database (to be picked up by a CRON job that sends out these emails). Because we realized there's too many emails being sent at once, causing some to not be sent at all. So we want to track in a database when one is sent correctly.
My database table contains the following columns:
CREATE TABLE `mail_queue`(
`mail_id` INT(11) NOT NULL AUTO_INCREMENT,
`from` VARCHAR(255) NOT NULL,
`to` VARCHAR(255) NOT NULL,
`mail_object` JSON NOT NULL,
`date_inserted` datetime DEFAULT CURRENT_TIMESTAMP,
`priority` INT(11) NOT NULL,
`mail_sent` INT(11) NOT NULL DEFAULT '0',
INDEX `mail_queue_FI_1` (`priority`),
INDEX `mail_queue_FI_2` (`mail_sent`),
PRIMARY KEY (`mail_id`)
) ENGINE = InnoDB;
The following PHP code I have shows how to create an email:
//Initialize mail
$this->load->library('email');
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'smtp.office365.com';
$config['smtp_user'] = GENERAL_MAIL;
$config['smtp_pass'] = GENERAL_MAIL_PW;
$config['smtp_port'] = '587';
$config['charset']='utf-8';
$config['newline']="\r\n";
$config['crlf'] = "\r\n";
$config['smtp_crypto'] = 'tls';
$config['mailtype'] = 'html';
$this->email->initialize($config);
$this->email->from(GENERAL_MAIL, 'me');
$this->email->to('dennis@me.com');
$this->email->subject("test123cron");
$message = $this->load->view('mail/membership/request',"123",TRUE);
$this->email->message($message);
The object $this->email then contains a PHP object with quite a lot of parameters inside. Some are public and some are protected.
for example :
...
public 'bcc_batch_mode' => boolean false
public 'bcc_batch_size' => int 200
protected '_safe_mode' => boolean false
protected '_subject' => string '' (length=0)
protected '_body' => string '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="format-detection" content="telephone=no" /> <!-- disable auto telephone linking in iOS -->
<title> <title>Geregistr'... (length=49335)
protected '_finalbody' => string '' (length=0)
...
By using json_encode it seems that only the public parameters are encoded in JSON while the protected are not.
I've read about implementing JsonSerialization, but according to the documentation "Specify data which should be serialized to JSON". Do I need to define each and every object parameter in there? I am not even sure if it's a fixed amount every time.
EDIT: I tried the suggestion as provided by the comment and my code is like this:
class Cron extends MY_Controller implements JsonSerializable
{
public function __construct()
{
parent::__construct();
// Force SSL
$this->force_ssl();
//Initialize mail
$this->load->library('email');
$config['protocol'] = 'smtp';
$config['smtp_host'] = 'smtp.office365.com';
$config['smtp_user'] = GENERAL_MAIL;
$config['smtp_pass'] = GENERAL_MAIL_PW;
$config['smtp_port'] = '587';
$config['charset']='utf-8';
$config['newline']="\r\n";
$config['crlf'] = "\r\n";
$config['smtp_crypto'] = 'tls';
$config['mailtype'] = 'html';
$this->email->initialize($config);
}
public function sendQueuingMails() {
$this->email->from(GENERAL_MAIL, 'me');
$this->email->to('dennis@me.com');
$this->email->subject("test123cron");
$message = $this->load->view('mail/membership/request',"123",TRUE);
$this->email->message($message);
var_dump($this->email);
$jsonencode = json_encode($this->email);
var_dump($jsonencode);
$jsondecode = json_decode($jsonencode);
var_dump($jsondecode);
}
public function jsonSerialize()
{
return get_object_vars($this);
}
}
The output of the encoded JSON object is :
D:\wamp\www\codeigniter\application\controllers\cli\Cron.php:594:string '{"useragent":"CodeIgniter","mailpath":"\/usr\/sbin\/sendmail","protocol":"smtp","smtp_host":"smtp.office365.com","smtp_user":"dev@giveaday.be","smtp_pass":"266duZg6x4TP66Vn","smtp_port":"587","smtp_timeout":5,"smtp_keepalive":false,"smtp_crypto":"tls","wordwrap":true,"wrapchars":76,"mailtype":"html","charset":"utf-8","multipart":"mixed","alt_message":"","validate":false,"priority":3,"newline":"\r\n","crlf":"\r\n","dsn":false,"send_multipart":true,"bcc_batch_mode":false,"bcc_batch_size":200}' (length=495)
Which shows that it does not encode the protected attributes.
EDIT 2: based on the blog article linked below I changed the code of the jsonSerialize method to the following:
public function jsonSerialize()
{
$json = array();
foreach($this as $key => $value) {
$json[$key] = $value;
}
return $json;
}
The result is the same. I noticed that the jsonSerialize method is just not being called. No matter what i put there, e.g. return "testtest"; it seems to keep on using the json_encode from somewhere else?