Closed quasiperfect closed 8 years ago
smtp_conn_options (CodeIgniter) ---> SMTPOptions (PHPMailer)
v4.0.126
A note: For 'smtp_conn_options' in the administration panel I use a text area control for this setting. I enter the value in JSON notation:
{
"ssl": {
"verify_peer": false,
"verify_peer_name": false,
"allow_self_signed": true
}
}
The helper function set_email_settings() takes the decoded value (an object), converts it into an associative array recursively and then stores it within the database, the 'settings' table. The stored array is PHP-serialized. Sounds weird, but it works.
Demo code for an administrative page:
Controller: Email_settings_controller.php
<?php defined('BASEPATH') OR exit('No direct script access allowed.');
class Email_settings_controller extends Base_Authenticated_Controller {
public function __construct() {
parent::__construct();
$this->load
->language('email_settings')
;
$this->_set_nav('settings/email_settings');
}
public function index() {
$this->load->helper('email');
$this->_set_title($this->lang->line('email_settings'), $this->lang->line('ui_settings').': '.$this->lang->line('email_settings'));
$settings = get_email_settings();
$settings['smtp_port'] = empty($settings['smtp_port']) ? '' : $settings['smtp_port'];
$settings['mailer_enabled'] = (int) $settings['mailer_enabled'];
$settings['smtp_conn_options'] = empty($settings['smtp_conn_options'])
? ''
: (is_php('5.4')
? json_encode($settings['smtp_conn_options'], JSON_PRETTY_PRINT)
: json_encode($settings['smtp_conn_options']));
$validation_rules = array(
array(
'field' => 'site_email',
'label' => $this->lang->line('site_email'),
'rules' => 'nohtml|trim'.($this->input->post('site_email') != '' ? '|valid_email' : '')
),
array(
'field' => 'notification_email',
'label' => $this->lang->line('notification_email'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'cc_email',
'label' => $this->lang->line('cc_email'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'mailer_enabled',
'label' => $this->lang->line('status'),
'rules' => 'nohtml|trim|required'
),
array(
'field' => 'protocol',
'label' => $this->lang->line('email_protocol'),
'rules' => 'nohtml|trim|required'
),
array(
'field' => 'mailpath',
'label' => $this->lang->line('email_mailpath'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'smtp_host',
'label' => $this->lang->line('email_smtp_host'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'smtp_user',
'label' => $this->lang->line('email_smtp_user'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'smtp_pass',
'label' => $this->lang->line('email_smtp_pass'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'smtp_port',
'label' => $this->lang->line('email_smtp_port'),
'rules' => 'nohtml|trim'.($this->input->post('smtp_port') != '' ? '|is_natural|greater_than[0]|less_than_equal_to[65535]' : '')
),
array(
'field' => 'smtp_crypto',
'label' => $this->lang->line('email_smtp_crypto'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'smtp_auto_tls',
'label' => $this->lang->line('email_smtp_auto_tls'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'smtp_conn_options',
'label' => $this->lang->line('email_smtp_conn_options'),
'rules' => 'trim'
),
array(
'field' => 'dkim_domain',
'label' => $this->lang->line('email_dkim_domain'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'dkim_private',
'label' => $this->lang->line('email_dkim_private'),
'rules' => 'strval'
),
array(
'field' => 'dkim_selector',
'label' => $this->lang->line('email_dkim_selector'),
'rules' => 'nohtml|trim'
),
array(
'field' => 'dkim_passphrase',
'label' => $this->lang->line('email_dkim_passphrase'),
'rules' => 'strval'
),
array(
'field' => 'dkim_identity',
'label' => $this->lang->line('email_dkim_identity'),
'rules' => 'nohtml|trim'
),
);
$this->form_validation->set_rules($validation_rules);
if ($this->form_validation->run()) {
$data = array_only($this->input->post(), array(
'protocol',
'mailpath',
'smtp_host',
'smtp_user',
'smtp_pass',
'smtp_port',
'smtp_crypto',
'smtp_auto_tls',
'smtp_conn_options',
'dkim_domain',
'dkim_private',
'dkim_selector',
'dkim_passphrase',
'dkim_identity',
'mailer_enabled',
'site_email',
'notification_email',
'cc_email',
));
$smtp_conn_options = @ json_decode($data['smtp_conn_options']);
if (empty($smtp_conn_options)) {
$smtp_conn_options = array();
}
$data['smtp_conn_options'] = $smtp_conn_options;
// Store data.
set_email_settings($data);
$this->session->set_flashdata('confirmation_message', $this->lang->line('settings_saved'));
redirect(site_url('email-settings'));
} elseif (validation_errors()) {
$this->template->set('error_message', '<ul>'.validation_errors('<li>', '</li>').'</ul>');
$this->template->set('validation_errors', $this->form_validation->error_array());
}
$this->template
->set($settings)
->set_partial('scripts', 'email_settings_scripts')
->build('email_settings');
}
public function _status_active_dropdown($value = '') {
$this->load->model('status_active');
return form_dropdown(
'mailer_enabled',
array('' => '-- '.$this->lang->line('ui_choose').' --') + $this->status_active->dropdown(),
$value,
'id="mailer_enabled" class="form-control" style="width: 100%;"'
);
}
}
View: email_settings.html.twig
{{ form_open('', 'name="admin_form" id="admin_form" method="post" class="form-horizontal" role="form"') }}
<div class="form-group{% if validation_errors['site_email'] is not empty %} has-error{% endif %}">
<label for="site_email" class="col-sm-4 control-label">
{{ lang('site_email') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('site_email_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6">
<input type="text" name="site_email" id="site_email" class="form-control"
value="{{ set_value('site_email', site_email) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['notification_email'] is not empty %} has-error{% endif %}">
<label for="notification_email" class="col-sm-4 control-label">
{{ lang('notification_email') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('notification_email_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6">
<input type="text" name="notification_email" id="notification_email" class="form-control"
value="{{ set_value('notification_email', notification_email) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['cc_email'] is not empty %} has-error{% endif %}">
<label for="cc_email" class="col-sm-4 control-label">
{{ lang('cc_email') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('cc_email_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6">
<input type="text" name="cc_email" id="cc_email" class="form-control"
value="{{ set_value('cc_email', cc_email) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['mailer_enabled'] is not empty %} has-error{% endif %}">
<label for="mailer_enabled" class="col-sm-4 control-label">
* {{ lang('status') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('mailer_enabled_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-2">
{{ widget('email_settings/_status_active_dropdown', set_value('mailer_enabled', mailer_enabled)) }}
</div>
</div>
<hr />
<div class="form-group{% if validation_errors['protocol'] is not empty %} has-error{% endif %}">
<label for="protocol" class="col-sm-4 control-label">
* {{ lang('email_protocol') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_protocol_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-2">
{{ form_dropdown(
'protocol',
{'': '-- ' ~ lang('ui_choose') ~ ' --', 'mail': 'mail', 'sendmail': 'sendmail', 'smtp': 'smtp'},
protocol,
'id="protocol" class="form-control" style="width: 100%;"'
) }}
</div>
</div>
<div class="form-group{% if validation_errors['mailpath'] is not empty %} has-error{% endif %}">
<label for="mailpath" class="col-sm-4 control-label">
{{ lang('email_mailpath') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_mailpath_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="mailpath" id="mailpath" class="form-control"
value="{{ set_value('mailpath', mailpath) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['smtp_host'] is not empty %} has-error{% endif %}">
<label for="smtp_host" class="col-sm-4 control-label">
{{ lang('email_smtp_host') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_host_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="smtp_host" id="smtp_host" class="form-control"
value="{{ set_value('smtp_host', smtp_host) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['smtp_user'] %} has-error{% endif %}">
<label for="smtp_user" class="col-sm-4 control-label">
{{ lang('email_smtp_user') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_user_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="smtp_user" id="smtp_user" class="form-control"
value="{{ set_value('smtp_user', smtp_user) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['smtp_pass'] %} has-error{% endif %}">
<label for="smtp_pass" class="col-sm-4 control-label">
{{ lang('email_smtp_pass') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_pass_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="password" name="smtp_pass" id="smtp_pass" class="form-control"
value="{{ set_value('smtp_pass', smtp_pass) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['smtp_port'] %} has-error{% endif %}">
<label for="smtp_port" class="col-sm-4 control-label">
{{ lang('email_smtp_port') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_port_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-2">
<input type="text" name="smtp_port" id="smtp_port" class="form-control"
value="{{ set_value('smtp_port', smtp_port) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['smtp_crypto'] %} has-error{% endif %}">
<label for="smtp_crypto" class="col-sm-4 control-label">
{{ lang('email_smtp_crypto') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_crypto_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-2">
{{ form_dropdown(
'smtp_crypto',
{'': '-- ' ~ lang('email_none') ~ ' --', 'ssl': 'ssl', 'tls': 'tls'},
smtp_crypto,
'id="smtp_crypto" class="form-control" style="width: 100%;"'
) }}
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<div class="checkbox">
<label for="smtp_auto_tls">
<input type="checkbox" id="smtp_auto_tls" name="smtp_auto_tls" value="1" {{ set_checkbox('smtp_auto_tls', '1', smtp_auto_tls|int != 0) }} /> {{ lang('email_smtp_auto_tls') }}
<a href="javascript://"
class="popover-top"
data-toggle="popover"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_auto_tls_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
</div>
</div>
</div>
<div class="form-group{% if validation_errors['smtp_conn_options'] is not empty %} has-error{% endif %}">
<label for="smtp_conn_options" class="col-sm-4 control-label">
{{ lang('email_smtp_conn_options') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_smtp_conn_options_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6">
<textarea class="form-control" rows="8" name="smtp_conn_options" id="smtp_conn_options">{{ set_value('smtp_conn_options', smtp_conn_options, true) }}</textarea>
</div>
</div>
<hr />
<div class="form-group{% if validation_errors['dkim_domain'] is not empty %} has-error{% endif %}">
<label for="dkim_domain" class="col-sm-4 control-label">
{{ lang('email_dkim_domain') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_dkim_domain_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="dkim_domain" id="dkim_domain" class="form-control"
value="{{ set_value('dkim_domain', dkim_domain) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['dkim_private'] is not empty %} has-error{% endif %}">
<label for="dkim_private" class="col-sm-4 control-label">
{{ lang('email_dkim_private') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_dkim_private_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="dkim_private" id="dkim_private" class="form-control"
value="{{ set_value('dkim_private', dkim_private) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['dkim_selector'] is not empty %} has-error{% endif %}">
<label for="dkim_selector" class="col-sm-4 control-label">
{{ lang('email_dkim_selector') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_dkim_selector_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="dkim_selector" id="dkim_selector" class="form-control"
value="{{ set_value('dkim_selector', dkim_selector) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['dkim_passphrase'] is not empty %} has-error{% endif %}">
<label for="dkim_passphrase" class="col-sm-4 control-label">
{{ lang('email_dkim_passphrase') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_dkim_passphrase_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="password" name="dkim_passphrase" id="dkim_passphrase" class="form-control"
value="{{ set_value('dkim_passphrase', dkim_passphrase) }}"
/>
</div>
</div>
<div class="form-group{% if validation_errors['dkim_identity'] is not empty %} has-error{% endif %}">
<label for="dkim_identity" class="col-sm-4 control-label">
{{ lang('email_dkim_identity') }}:
<a href="javascript://"
class="popover-top"
title="{{ lang('ui_help') }}"
data-content="{{ lang('email_dkim_identity_tip') }}"
>
<i class="fa fa-question-circle"></i>
</a>
</label>
<div class="col-sm-6 col-lg-4">
<input type="text" name="dkim_identity" id="dkim_identity" class="form-control"
value="{{ set_value('dkim_identity', dkim_identity) }}"
/>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<p class="help-block">
{{ lang('ui_required_fields_note') }}
</p>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-4 col-sm-8">
<button type="submit" class="btn btn-primary">
<i class="fa fa-check"></i>
{{ lang('ui_save') }}
</button>
</div>
</div>
{{ form_close() }}
hi
can you please add support for
PHP 5.6 certificate verification failure
In a change from earlier versions, PHP 5.6 verifies certificates on SSL connections. If the SSL config of the server you are connecting to is not correct, you will get an error like this:
Warning: stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
The correct fix for this is to replace the invalid, misconfigured or self-signed certificate with a good one. Failing that, you can allow insecure connections via the SMTPOptions property introduced in PHPMailer 5.2.10 (it's possible to do this by subclassing the SMTP class in earlier versions), though this is not recommended: