1
0
mirror of https://github.com/postfixadmin/postfixadmin.git synced 2025-07-31 10:04:20 +03:00

Merge branch 'master' into michaelkrieger-patch-1

This commit is contained in:
David Goodwin
2024-01-11 08:51:17 +00:00
committed by GitHub
543 changed files with 15120 additions and 40059 deletions

View File

@ -1,10 +1,12 @@
<?php
# $Id$
/**
* Handlers User level alias actions - e.g. add alias, get aliases, update etc.
*/
class AliasHandler extends PFAHandler {
class AliasHandler extends PFAHandler
{
protected $db_table = 'alias';
protected $id_field = 'address';
protected $domain_field = 'domain';
@ -16,12 +18,13 @@ class AliasHandler extends PFAHandler {
*/
public $return = null;
protected function initStruct() {
protected function initStruct()
{
# hide 'goto_mailbox' if $this->new
# (for existing aliases, init() hides it for non-mailbox aliases)
$mbgoto = 1 - $this->new;
$this->struct=array(
$this->struct = array(
# field name allow display in... type $PALANG label $PALANG description default / ...
# editing? form list
'status' => pacol(0, 0, 0, 'html', '' , '' , '', array(),
@ -68,7 +71,8 @@ class AliasHandler extends PFAHandler {
* When using this function to optimize the is_mailbox extrafrom, don't forget to reset it to the default value
* (all domains for this admin) afterwards.
*/
private function set_is_mailbox_extrafrom($condition=array(), $searchmode=array()) {
private function set_is_mailbox_extrafrom($condition=array(), $searchmode=array())
{
$extrafrom = 'LEFT JOIN ( ' .
' SELECT 1 as __is_mailbox, username as __mailbox_username ' .
' FROM ' . table_by_key('mailbox') .
@ -88,7 +92,8 @@ class AliasHandler extends PFAHandler {
}
protected function initMsg() {
protected function initMsg()
{
$this->msg['error_already_exists'] = 'email_address_already_exists';
$this->msg['error_does_not_exist'] = 'alias_does_not_exist';
$this->msg['confirm_delete'] = 'confirm_delete_alias';
@ -106,7 +111,8 @@ class AliasHandler extends PFAHandler {
}
public function webformConfig() {
public function webformConfig()
{
if ($this->new) { # the webform will display a localpart field + domain dropdown on $new
$this->struct['address']['display_in_form'] = 0;
$this->struct['localpart']['display_in_form'] = 1;
@ -136,7 +142,8 @@ class AliasHandler extends PFAHandler {
* AliasHandler needs some special handling in init() and therefore overloads the function.
* It also calls parent::init()
*/
public function init($id) {
public function init(string $id): bool
{
$bits = explode('@', $id);
if (sizeof($bits) == 2) {
$local_part = $bits[0];
@ -151,7 +158,7 @@ class AliasHandler extends PFAHandler {
if (!$retval) {
return false;
} # parent::init() failed, no need to continue
# hide 'goto_mailbox' for non-mailbox aliases
# parent::init called view() before, so we can rely on having $this->result filled
# (only validate_new_id() is called from parent::init and could in theory change $this->result)
@ -174,12 +181,14 @@ class AliasHandler extends PFAHandler {
return $retval;
}
protected function domain_from_id() {
protected function domain_from_id()
{
list(/*NULL*/, $domain) = explode('@', $this->id);
return $domain;
}
protected function validate_new_id() {
protected function validate_new_id()
{
if ($this->id == '') {
$this->errormsg[$this->id_field] = Config::lang('pCreate_alias_address_text_error1');
return false;
@ -191,7 +200,7 @@ class AliasHandler extends PFAHandler {
$this->errormsg[$this->id_field] = Config::lang('pCreate_alias_address_text_error3');
return false;
}
# TODO: already checked in set() - does it make sense to check it here also? Only advantage: it's an early check
# if (!in_array($domain, $this->allowed_domains)) {
# $this->errormsg[] = Config::lang('pCreate_alias_address_text_error1');
@ -216,7 +225,8 @@ class AliasHandler extends PFAHandler {
/**
* check number of existing aliases for this domain - is one more allowed?
*/
private function create_allowed($domain) {
private function create_allowed($domain)
{
if ($this->called_by == 'MailboxHandler') {
return true;
} # always allow creating an alias for a mailbox
@ -240,7 +250,8 @@ class AliasHandler extends PFAHandler {
* merge localpart and domain to address
* called by edit.php (if id_field is editable and hidden in editform) _before_ ->init
*/
public function mergeId($values) {
public function mergeId($values)
{
if ($this->struct['localpart']['display_in_form'] == 1 && $this->struct['domain']['display_in_form']) { # webform mode - combine to 'address' field
if (empty($values['localpart']) || empty($values['domain'])) { # localpart or domain not set
return "";
@ -254,7 +265,8 @@ class AliasHandler extends PFAHandler {
}
}
protected function setmore($values) {
protected function setmore(array $values)
{
if ($this->new) {
if ($this->struct['address']['display_in_form'] == 1) { # default mode - split off 'domain' field from 'address' # TODO: do this unconditional?
list(/*NULL*/, $domain) = explode('@', $values['address']);
@ -303,15 +315,20 @@ class AliasHandler extends PFAHandler {
$this->values['goto'] = join(',', $values['goto']);
}
protected function storemore() {
protected function postSave(): bool
{
# TODO: if alias belongs to a mailbox, update mailbox active status
return true;
}
protected function read_from_db_postprocess($db_result) {
protected function read_from_db_postprocess($db_result)
{
foreach ($db_result as $key => $value) {
# split comma-separated 'goto' into an array
$db_result[$key]['goto'] = explode(',', $db_result[$key]['goto']);
$goto = $db_result[$key]['goto'] ?? null;
if (is_string($goto)) {
$db_result[$key]['goto'] = explode(',', $goto);
}
# Vacation enabled?
list($db_result[$key]['on_vacation'], $db_result[$key]['goto']) = remove_from_array($db_result[$key]['goto'], $this->getVacationAlias());
@ -340,7 +357,8 @@ class AliasHandler extends PFAHandler {
return $db_result;
}
private function condition_ignore_mailboxes($condition, $searchmode) {
private function condition_ignore_mailboxes($condition, $searchmode)
{
# only list aliases that do not belong to mailboxes
if (is_array($condition)) {
$condition['__mailbox_username'] = 1;
@ -354,7 +372,8 @@ class AliasHandler extends PFAHandler {
return array($condition, $searchmode);
}
public function getList($condition, $searchmode = array(), $limit=-1, $offset=-1) {
public function getList($condition, $searchmode = array(), $limit=-1, $offset=-1): bool
{
list($condition, $searchmode) = $this->condition_ignore_mailboxes($condition, $searchmode);
$this->set_is_mailbox_extrafrom($condition, $searchmode);
$result = parent::getList($condition, $searchmode, $limit, $offset);
@ -362,7 +381,8 @@ class AliasHandler extends PFAHandler {
return $result;
}
public function getPagebrowser($condition, $searchmode = array()) {
public function getPagebrowser($condition, $searchmode = array())
{
list($condition, $searchmode) = $this->condition_ignore_mailboxes($condition, $searchmode);
$this->set_is_mailbox_extrafrom($condition, $searchmode);
$result = parent::getPagebrowser($condition, $searchmode);
@ -372,7 +392,8 @@ class AliasHandler extends PFAHandler {
protected function _validate_goto($field, $val) {
protected function _validate_goto($field, $val)
{
if (count($val) == 0) {
# empty is ok for mailboxes - this is checked in setmore() which can clear the error message
$this->errormsg[$field] = Config::lang('pEdit_alias_goto_text_error1');
@ -406,6 +427,11 @@ class AliasHandler extends PFAHandler {
$errors[] = "$singlegoto: $localaliasonly_check";
}
}
if ($this->called_by != "MailboxHandler" && $this->id == $singlegoto) {
// The MailboxHandler needs to create an alias that points to itself (for the mailbox)
// Otherwise, disallow such aliases as they cause severe trouble in the mail system
$errors[] = "$singlegoto: " . Config::Lang('alias_points_to_itself');
}
}
if (count($errors)) {
@ -419,7 +445,8 @@ class AliasHandler extends PFAHandler {
/**
* on $this->new, set localpart based on address
*/
protected function _missing_localpart($field) {
protected function _missing_localpart($field)
{
if (isset($this->RAWvalues['address'])) {
$parts = explode('@', $this->RAWvalues['address']);
if (count($parts) == 2) {
@ -431,7 +458,8 @@ class AliasHandler extends PFAHandler {
/**
* on $this->new, set domain based on address
*/
protected function _missing_domain($field) {
protected function _missing_domain($field)
{
if (isset($this->RAWvalues['address'])) {
$parts = explode('@', $this->RAWvalues['address']);
if (count($parts) == 2) {
@ -445,17 +473,20 @@ class AliasHandler extends PFAHandler {
* Returns the vacation alias for this user.
* i.e. if this user's username was roger@example.com, and the autoreply domain was set to
* autoreply.fish.net in config.inc.php we'd return roger#example.com@autoreply.fish.net
*
* @return string an email alias.
*/
protected function getVacationAlias() {
$vacation_goto = str_replace('@', '#', $this->id);
protected function getVacationAlias()
{
$vacation_goto = str_replace('@', '#', $this->id ?? '');
return $vacation_goto . '@' . Config::read_string('vacation_domain');
}
/**
* @return true on success false on failure
* @return boolean
*/
public function delete() {
public function delete()
{
if (! $this->view()) {
$this->errormsg[] = Config::Lang('alias_does_not_exist');
return false;