Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions app/Config/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ class Email extends BaseConfig
*/
public string $SMTPHost = '';

/**
* Which SMTP authentication method to use: login, plain
*/
public string $SMTPAuthMethod = 'login';

/**
* SMTP Username
*/
Expand Down
56 changes: 44 additions & 12 deletions system/Email/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,11 @@ class Email
*/
protected $SMTPAuth = false;

/**
* Which SMTP authentication method to use: login, plain
*/
protected string $SMTPAuthMethod = 'login';

/**
* Whether to send a Reply-To header
*
Expand Down Expand Up @@ -2020,45 +2025,72 @@ protected function SMTPAuthenticate()
return true;
}

if ($this->SMTPUser === '' && $this->SMTPPass === '') {
// If no username or password is set
if ($this->SMTPUser === '' || $this->SMTPPass === '') {
$this->setErrorMessage(lang('Email.noSMTPAuth'));

return false;
}

$this->sendData('AUTH LOGIN');
// normalize in case user entered capital words LOGIN/PLAIN
$this->SMTPAuthMethod = strtolower($this->SMTPAuthMethod);

// Validate supported authentication methods
$validMethods = ['login', 'plain'];
if (! in_array($this->SMTPAuthMethod, $validMethods, true)) {
$this->setErrorMessage(lang('Email.invalidSMTPAuthMethod', [$this->SMTPAuthMethod]));

return false;
}

// send initial 'AUTH' command
$this->sendData('AUTH ' . strtoupper($this->SMTPAuthMethod));
$reply = $this->getSMTPData();

if (str_starts_with($reply, '503')) { // Already authenticated
return true;
}

// if 'AUTH' command is unsuported by the server
if (! str_starts_with($reply, '334')) {
$this->setErrorMessage(lang('Email.failedSMTPLogin', [$reply]));
$this->setErrorMessage(lang('Email.failureSMTPAuthMethod', [strtoupper($this->SMTPAuthMethod)]));

return false;
}

$this->sendData(base64_encode($this->SMTPUser));
$reply = $this->getSMTPData();
switch ($this->SMTPAuthMethod) {
case 'login':
$this->sendData(base64_encode($this->SMTPUser));
$reply = $this->getSMTPData();

if (! str_starts_with($reply, '334')) {
$this->setErrorMessage(lang('Email.SMTPAuthUsername', [$reply]));
if (! str_starts_with($reply, '334')) {
$this->setErrorMessage(lang('Email.SMTPAuthUsername', [$reply]));

return false;
return false;
}

$this->sendData(base64_encode($this->SMTPPass));
break;

case 'plain':
// send credentials as the single second command
$authString = "\0" . $this->SMTPUser . "\0" . $this->SMTPPass;

$this->sendData(base64_encode($authString));
break;
}

$this->sendData(base64_encode($this->SMTPPass));
$reply = $this->getSMTPData();
if (! str_starts_with($reply, '235')) { // Authentication failed
$errorMessage = $this->SMTPAuthMethod === 'plain' ? 'Email.SMTPAuthCredentials' : 'Email.SMTPAuthPassword';

if (! str_starts_with($reply, '235')) {
$this->setErrorMessage(lang('Email.SMTPAuthPassword', [$reply]));
$this->setErrorMessage(lang($errorMessage, [$reply]));

return false;
}

if ($this->SMTPKeepAlive) {
$this->SMTPAuth = false;
$this->SMTPAuth = false; // Prevent re-authentication for keep-alive sessions
}

return true;
Expand Down
23 changes: 23 additions & 0 deletions system/I18n/TimeTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -749,6 +749,29 @@ public function addMonths(int $months)
return $time->add(DateInterval::createFromDateString("{$months} months"));
}

/**
* Returns a new Time instance with $months calendar months added to the time.
*/
public function addCalendarMonths(int $months): Time
{
$time = clone $this;

$year = (int) $time->getYear();
$month = (int) $time->getMonth() + $months;
$day = (int) $time->getDay();

// Adjust year and month for overflow
$year += intdiv($month - 1, 12);
$month = (($month - 1) % 12) + 1;

// Find the last valid day of the target month
$lastDayOfMonth = cal_days_in_month(CAL_GREGORIAN, $month, $year);
$correctedDay = min($day, $lastDayOfMonth);

// Return new time instance
return static::create($year, $month, $correctedDay, (int) $this->getHour(), (int) $this->getMinute(), (int) $this->getSecond(), $this->getTimezone(), $this->locale);
}

/**
* Returns a new Time instance with $years added to the time.
*
Expand Down
42 changes: 23 additions & 19 deletions system/Language/en/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,27 @@

// Email language settings
return [
'mustBeArray' => 'The email validation method must be passed an array.',
'invalidAddress' => 'Invalid email address: "{0}"',
'attachmentMissing' => 'Unable to locate the following email attachment: "{0}"',
'attachmentUnreadable' => 'Unable to open this attachment: "{0}"',
'noFrom' => 'Cannot send mail with no "From" header.',
'noRecipients' => 'You must include recipients: To, Cc, or Bcc',
'sendFailurePHPMail' => 'Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.',
'sendFailureSendmail' => 'Unable to send email using Sendmail. Your server might not be configured to send mail using this method.',
'sendFailureSmtp' => 'Unable to send email using SMTP. Your server might not be configured to send mail using this method.',
'sent' => 'Your message has been successfully sent using the following protocol: {0}',
'noSocket' => 'Unable to open a socket to Sendmail. Please check settings.',
'noHostname' => 'You did not specify a SMTP hostname.',
'SMTPError' => 'The following SMTP error was encountered: {0}',
'noSMTPAuth' => 'Error: You must assign an SMTP username and password.',
'failedSMTPLogin' => 'Failed to send AUTH LOGIN command. Error: {0}',
'SMTPAuthUsername' => 'Failed to authenticate username. Error: {0}',
'SMTPAuthPassword' => 'Failed to authenticate password. Error: {0}',
'SMTPDataFailure' => 'Unable to send data: {0}',
'exitStatus' => 'Exit status code: {0}',
'mustBeArray' => 'The email validation method must be passed an array.',
'invalidAddress' => 'Invalid email address: "{0}"',
'attachmentMissing' => 'Unable to locate the following email attachment: "{0}"',
'attachmentUnreadable' => 'Unable to open this attachment: "{0}"',
'noFrom' => 'Cannot send mail with no "From" header.',
'noRecipients' => 'You must include recipients: To, Cc, or Bcc',
'sendFailurePHPMail' => 'Unable to send email using PHP mail(). Your server might not be configured to send mail using this method.',
'sendFailureSendmail' => 'Unable to send email using Sendmail. Your server might not be configured to send mail using this method.',
'sendFailureSmtp' => 'Unable to send email using SMTP. Your server might not be configured to send mail using this method.',
'sent' => 'Your message has been successfully sent using the following protocol: {0}',
'noSocket' => 'Unable to open a socket to Sendmail. Please check settings.',
'noHostname' => 'You did not specify a SMTP hostname.',
'SMTPError' => 'The following SMTP error was encountered: {0}',
'noSMTPAuth' => 'Error: You must assign an SMTP username and password.',
'invalidSMTPAuthMethod' => 'Error: SMTP authorization method "{0}" is not supported in codeigniter, set either "login" or "plain" authorization method',
'failureSMTPAuthMethod' => 'Unable to initiate AUTH command. Your server might not be configured to use AUTH {0} authentication method.',
'SMTPAuthCredentials' => 'Failed to authenticate user credentials. Error: {0}',
'SMTPAuthUsername' => 'Failed to authenticate username. Error: {0}',
'SMTPAuthPassword' => 'Failed to authenticate password. Error: {0}',
'SMTPDataFailure' => 'Unable to send data: {0}',
'exitStatus' => 'Exit status code: {0}',
// @deprecated
'failedSMTPLogin' => 'Failed to send AUTH LOGIN command. Error: {0}',
];
1 change: 1 addition & 0 deletions user_guide_src/source/changelogs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ See all the changes.
.. toctree::
:titlesonly:

v4.7.0
v4.6.1
v4.6.0
v4.5.8
Expand Down
89 changes: 89 additions & 0 deletions user_guide_src/source/changelogs/v4.7.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
#############
Version 4.7.0
#############

Release Date: Unreleased

**4.7.0 release of CodeIgniter4**

.. contents::
:local:
:depth: 3

**********
Highlights
**********

- TBD

********
BREAKING
********

Behavior Changes
================

Interface Changes
=================

Method Signature Changes
========================

************
Enhancements
************

Commands
========

Testing
=======

Database
========

Query Builder
-------------

Forge
-----

Others
------

Model
=====

Libraries
=========

**Email:** Added support for choosing the SMTP authorization method. You can change it via ``Config\Email::$SMTPAuthMethod`` option

Helpers and Functions
=====================

Others
======

***************
Message Changes
***************

- Added ``Email.invalidSMTPAuthMethod`` and ``Email.failureSMTPAuthMethod``
- Deprecated ``Email.failedSMTPLogin``

*******
Changes
*******

************
Deprecations
************

**********
Bugs Fixed
**********

See the repo's
`CHANGELOG.md <https://github.com/codeigniter4/CodeIgniter4/blob/develop/CHANGELOG.md>`_
for a complete list of bugs fixed.
55 changes: 55 additions & 0 deletions user_guide_src/source/installation/upgrade_470.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#############################
Upgrading from 4.6.x to 4.7.0
#############################

Please refer to the upgrade instructions corresponding to your installation method.

- :ref:`Composer Installation App Starter Upgrading <app-starter-upgrading>`
- :ref:`Composer Installation Adding CodeIgniter4 to an Existing Project Upgrading <adding-codeigniter4-upgrading>`
- :ref:`Manual Installation Upgrading <installing-manual-upgrading>`

.. contents::
:local:
:depth: 2

**********************
Mandatory File Changes
**********************

****************
Breaking Changes
****************

*********************
Breaking Enhancements
*********************

*************
Project Files
*************

Some files in the **project space** (root, app, public, writable) received updates. Due to
these files being outside of the **system** scope they will not be changed without your intervention.

.. note:: There are some third-party CodeIgniter modules available to assist
with merging changes to the project space:
`Explore on Packagist <https://packagist.org/explore/?query=codeigniter4%20updates>`_.

Content Changes
===============

The following files received significant changes (including deprecations or visual adjustments)
and it is recommended that you merge the updated versions with your application:

Config
------

- @TODO

All Changes
===========

This is a list of all files in the **project space** that received changes;
many will be simple comments or formatting that have no effect on the runtime:

- @TODO
1 change: 1 addition & 0 deletions user_guide_src/source/installation/upgrading.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ See also :doc:`./backward_compatibility_notes`.

backward_compatibility_notes

upgrade_470
upgrade_461
upgrade_460
upgrade_458
Expand Down
3 changes: 2 additions & 1 deletion user_guide_src/source/libraries/email.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Here is a basic example demonstrating how you might send email:
Setting Email Preferences
=========================

There are 21 different preferences available to tailor how your email
There are 22 different preferences available to tailor how your email
messages are sent. You can either set them manually as described here,
or automatically via preferences stored in your config file, described
in `Email Preferences`_.
Expand Down Expand Up @@ -120,6 +120,7 @@ Preference Default Value Options Description
or ``smtp``
**mailPath** /usr/sbin/sendmail The server path to Sendmail.
**SMTPHost** SMTP Server Hostname.
**SMTPAuthMethod** login ``login``, ``plain`` SMTP Authentication Method. (Available since 4.7.0)
**SMTPUser** SMTP Username.
**SMTPPass** SMTP Password.
**SMTPPort** 25 SMTP Port. (If set to ``465``, TLS will be used for the connection
Expand Down
Loading