diff --git a/include/class-Breadcrumb.php b/include/class-Breadcrumb.php index 5105877..8731ae5 100644 --- a/include/class-Breadcrumb.php +++ b/include/class-Breadcrumb.php @@ -1,79 +1,79 @@ . /** * Handle a breadcrumb with the related microdata * * @url https://schema.org/BreadcrumbList * @url https://developers.google.com/search/docs/data-types/breadcrumb */ class Breadcrumb { /** * Spawn the breadcrumb * * @param $uid string|null Starting menu uid * @param $title string|null Starting title * @param $parent_uid string|null Parent menu uid */ public static function spawn( $breadcrumbs ) { ?> url ? $entry->getSitePage() : null; + $url = $entry->url ? $entry->getURL() : null; return self::link( $i, $url, $entry->name ); } /** * Get a link with microdata * * @param int $i * @param string $url * @param string $title * @return string */ public static function link( $i, $url, $title ) { $s = '
  • '; if( $url ) { $s .= ''; $s .= '' . esc_html( $title ) . ''; $s .= ''; } else { $s .= '' . esc_html( $title ) . ''; } $s .= ''; $s .= "
  • \n"; return $s; } } diff --git a/include/class-Header.php b/include/class-Header.php index 9f6bce7..93838be 100644 --- a/include/class-Header.php +++ b/include/class-Header.php @@ -1,91 +1,99 @@ . /** * The header of the web page */ class Header { /** * Header arguments * * It's public because the Footer reads it. * * @var array */ public static $args; /** * Spawn the header to standard output * * @param $args mixed Can be the page UID, or arguments where: * uid: menu UID like 'home' * title: document title */ public static function spawn( $args = [] ) { // store arguments for future reads self::$args = & $args; // shortcut if( is_string( $args ) ) { $args = [ 'uid' => $args ]; } - // eventually retrieve actual page UID - if( ! isset( $args[ 'uid' ] ) ) { - $args[ 'uid' ] = self::actualPageUID(); + // eventually retrieve actual page UID from the URL + if( !isset( $args['uid'] ) ) { + $args['uid'] = self::actualPageUID(); } - // retrieve page informations - $page = isset( $args[ 'uid' ] ) - ? menu_entry( $args[ 'uid' ] ) - : null; + // get menu entry (MenuEntry) + $page = null; + if( $args['uid'] ) { - // populate the page informations - if( $page ) { + // check if this menu entry is registered + $page = menu_entry( $args['uid'] ); + if( !$page ) { + error( "unexisting menu entry {$args['uid']}" ); + PageNotFound::spawn(); + } + + // populate arguments with page informations $args = array_replace( [ 'title' => $page->name, ], $args ); - } else { - $args[ 'uid' ] = null; + + // check if the page should be visible + if( !$page->isVisible() ) { + require_more_privileges(); + } } // populate default arguments $args = array_replace( [ 'container' => true, 'sidebar' => true, 'breadcrumb' => [], ], $args ); // charset is usually UTF-8 header( 'Content-Type: text/html; charset=' . CHARSET ); // spawn header template template( 'header', [ 'args' => $args ] ); } /** * Get the default page UID * * @return string */ public static function actualPageUID() { $page = basename( $_SERVER[ 'SCRIPT_NAME' ] ); return str_replace( '.php', '', $page ); } } diff --git a/include/class-PageNotFound.php b/include/class-PageNotFound.php index db99301..cfd4915 100644 --- a/include/class-PageNotFound.php +++ b/include/class-PageNotFound.php @@ -1,30 +1,38 @@ . class PageNotFound { public static function spawn() { http_response_code( 404 ); + Header::spawn( [ + // this is not a real page + 'uid' => false, + + // page title 'title' => __( "Page not found" ) ] ); + template( '404' ); + Footer::spawn(); + exit; } } diff --git a/include/class-UserAPI.php b/include/class-UserAPI.php new file mode 100644 index 0000000..1195e8c --- /dev/null +++ b/include/class-UserAPI.php @@ -0,0 +1,93 @@ +. + +/** + * User users API + */ +class UserAPI extends DomainAPI { + + /** + * Column name of the User ID + */ + const USER_ID = 'user.user_ID'; + + /** + * Constructor + */ + public function __construct() { + Query::__construct(); + $this->from( User::T ); + $this->defaultClass( 'User' ); + } + + /** + * Filter to a certain User UID + * + * @param string $uid User UID + * @return self + */ + public function whereUserUID( $uid ) { + return $this->whereStr( 'user_uid', $uid ); + } + + /** + * Filter to a certain User ID + * + * @param string $uid User ID + * @return self + */ + public function whereUserID( $id ) { + return $this->whereInt( static::USER_ID, $id ); + } + + /** + * Filter to myself + * + * @return self + */ + public function whereUserIsMe() { + $id = get_user()->getSessionuserID(); + return $this->whereUserID( $id ); + } + + /** + * WHere the User(s) is editable + * + * @return Query + */ + public function whereUserIsEditable() { + + // if I can't see everyone, just see myself + if( !has_permission( 'edit-all-users' ) ) { + $this->whereUserIsMe(); + } + + return $this; + } + + /** + * Limit to a specific User + * + * @param object $user User + * @return self + */ + public function whereUser( $user ) { + $id = $user->whereSessionuserID(); + return $this->whereUserID( $id ); + } + +} diff --git a/template/ftp-access.php b/include/class-UserPager.php similarity index 53% copy from template/ftp-access.php copy to include/class-UserPager.php index be16693..7853551 100644 --- a/template/ftp-access.php +++ b/include/class-UserPager.php @@ -1,41 +1,61 @@ . -/* - * This is the template for FTP instructions - * - * Called from: - * ftp.php - * - * Available variables: - * $domain Domain object - * $ftp FTP object +/** + * User users API */ +class UserPager extends QueryPager { -// unuseful when load directly -defined( 'BOZ_PHP' ) or die; -?> + /** + * Constructor + * + * @param $data array + */ + public function __construct( $data = [] ) { + parent::__construct(); -

    + if( isset( $data['uid'] ) ) { + $data['uid'] = luser_input( $data['uid'], 32 ); + $this->setArg( 'uid', $data['uid'] ); + } + } -
    - ftp://getFTPLogin() ); - echo '@'; - _esc_html( $domain->getDomainName() ); - ?> -
    + /** + * Create a Query for User(s) + * + * @return Query + */ + public function createQuery() { + $query = new UserAPI(); + + $query->whereUserIsEditable(); + + return $query; + } + + + /** + * Eventually apply an order + * + * @override + */ + public function applyOrder( & $query, $order_by, $direction ) { + + + } + +} diff --git a/include/functions.php b/include/functions.php index ffb00a4..c00a77d 100644 --- a/include/functions.php +++ b/include/functions.php @@ -1,195 +1,201 @@ . /** * Require a certain page from the template directory * * @param $name string page name (to be sanitized) * @param $args mixed arguments to be passed to the page scope */ function template( $template_name, $template_args = [] ) { extract( $template_args, EXTR_SKIP ); return require TEMPLATE_PATH . __ . "$template_name.php"; } /** * Get the returned text from a template * * @param $name string page name (to be sanitized) * @param $args mixed arguments to be passed to the page scope * @see template() * @return string */ function template_content( $name, $args = [] ) { ob_start(); template( $name, $args ); $text = ob_get_contents(); ob_end_clean(); return $text; } /** * Print an e-mail (safe for bots) * * @param $email string */ function email_blur( $email ) { $dot = strip_tags( __( " dot " ) ); $at = strip_tags( __( " at " ) ); $email = esc_html( $email ); echo str_replace( [ '.', '@' ], [ $dot, $at ], $email ); } /** * Send an e-mail to someone * * @param $subject string E-mail subject * @param $message string E-mail message * @param $to string E-mail recipient (from current logged-in user as default) */ function send_email( $subject, $message, $to = false ) { if( ! $to ) { if( ! is_logged() ) { die( "can't retrieve e-mail address from anon user" ); } $to = get_user( 'user_email' ); } return SMTPMail::instance() ->to( $to ) ->message( $subject, $message ) ->disconnect(); } /** * Require a certain permission * * @param $permission string An internal permission like 'edit-all-user' * @param $redirect boolean Enable or disable the redirect */ function require_permission( $permission, $redirect = true ) { if( ! has_permission( $permission ) ) { - if( is_logged() ) { - Header::spawn( [ - 'title' => __( "Permission denied" ), + require_more_privileges( $redirect ); + } +} + +/** + * Require more privileges then actual ones + */ +function require_more_privileges( $redirect = true ) { + if( is_logged() ) { + Header::spawn( [ + 'title' => __( "Permission denied" ), + ] ); + Footer::spawn(); + exit; + } else { + $login = menu_entry( 'login' ); + $url = $login->getAbsoluteURL(); + if( $redirect && isset( $_SERVER[ 'REQUEST_URI' ] ) ) { + $url = http_build_get_query( $url, [ + 'redirect' => $_SERVER[ 'REQUEST_URI' ], ] ); - Footer::spawn(); - exit; - } else { - $login = menu_entry( 'login' ); - $url = $login->getSitePage( URL ); - if( $redirect && isset( $_SERVER[ 'REQUEST_URI' ] ) ) { - $url = http_build_get_query( $url, [ - 'redirect' => $_SERVER[ 'REQUEST_URI' ], - ] ); - } - http_redirect( $url, 307 ); } + http_redirect( $url, 307 ); } } - /** * Get URL parts from the PATH_INFO * * It spawn a "bad request" page if something goes wrong. * * @param $max int If $min is specified, this is the maximum number of parameters. When unspecified, this is the exact number of parameters. * @param $min int Mininum number of parameters. * @return array * @see https://httpd.apache.org/docs/2.4/mod/core.html#acceptpathinfo */ function url_parts( $max, $min = false ) { if( $min === false ) { $min = $max; } // split the PATH_INFO parts $parts = explode( _, $_SERVER[ 'PATH_INFO' ] ); array_shift( $parts ); // eventually spawn the "bad request" $n = count( $parts ); if( $n > $max || $n < $min ) { BadRequest::spawn( __( "unexpected URL" ) ); } // eventually fill expected fields for( $i = $n; $i < $max; $i++ ) { $parts[] = null; } return $parts; } /** * Link to an existing page from the menu * * @param $uid string E.g. 'index' * @param $args mixed Arguments */ function the_menu_link( $uid, $args = [] ) { $page = menu_entry( $uid ); - the_link( $page->getSitePage(), $page->name, $args ); + the_link( $page->getURL(), $page->name, $args ); } /** * Link to a whatever page * * P.S. link() is a reserved function * * @param $url string * @param $title string * @param $args mixed Arguments */ function the_link( $url, $title, $args = [] ) { template( 'link', [ 'title' => $title, 'url' => $url, 'args' => $args, ] ); } /** * Generate a password * * @param $bytes int */ function generate_password( $bytes = 8 ) { return rtrim( base64_encode( bin2hex( openssl_random_pseudo_bytes( $bytes ) ) ), '=' ); } /** * Validate a mailbox username * * @param $mailbox string * @return bool */ function validate_mailbox_username( $mailbox ) { return 1 === preg_match( '/^[a-z][a-z0-9-_.]+$/', $mailbox ); } /** * A certain value must be an e-mail * * @param $email string * @return string filtered e-mail */ function require_email( $email ) { $email = luser_input( $email, 128 ); if( filter_var( $email, FILTER_VALIDATE_EMAIL ) === false ) { BadRequest::spawn( __( "fail e-mail validation" ) ); } return $email; } diff --git a/template/ftp-access.php b/template/ftp-access.php index be16693..79fe536 100644 --- a/template/ftp-access.php +++ b/template/ftp-access.php @@ -1,41 +1,41 @@ . /* * This is the template for FTP instructions * * Called from: * ftp.php * * Available variables: * $domain Domain object * $ftp FTP object */ // unuseful when load directly defined( 'BOZ_PHP' ) or die; ?> -

    +

    - ftp://getFTPLogin() ); - echo '@'; - _esc_html( $domain->getDomainName() ); + ftp://getFTPLogin() ) . + '@' . + esc_html( $domain->getDomainName() ); ?>
    diff --git a/template/header.php b/template/header.php index 28b88a8..dc7aaf0 100644 --- a/template/header.php +++ b/template/header.php @@ -1,73 +1,73 @@ . /* * This is the template for the website header * * Called from: * include/class-Header.php * * Available variables: * $args array */ // unuseful when load directly defined( 'BOZ_PHP' ) or die; // load Bootstrap stuff enqueue_js( 'jquery' ); enqueue_js( 'bootstrap' ); enqueue_css( 'bootstrap' ); enqueue_css( 'custom-css' ); ?> <?= strip_tags( $args[ 'title' ] ) ?> - <?php echo strip_tags( SITE_NAME ) ?>

    -

    :

    +

    :

    $args ] ) ?>
    diff --git a/template/menu.php b/template/menu.php index d924052..84a34ec 100644 --- a/template/menu.php +++ b/template/menu.php @@ -1,48 +1,48 @@ . /* * This is the template for the navigation menu * * Called from * template/sidebar.php */ // unuseful when load directly defined( 'BOZ_PHP' ) or die; ?>
    • uid === Header::$args[ 'uid' ] ): ?> name ) ?> getSitePage(), + $entry->getURL(), $entry->name ) ?> $entry->uid, 'level' => $level + 1, ] ) ) ?>
    diff --git a/www/domain.php b/www/domain.php index ace4475..196f5cb 100644 --- a/www/domain.php +++ b/www/domain.php @@ -1,88 +1,89 @@ . /* * This is the domain edit page */ // load framework require '../load.php'; // wanted domain list( $domain_name ) = url_parts( 1, 0 ); $domain = null; if( $domain_name ) { // retrieve domain $domain = ( new DomainAPI() ) ->whereDomainName( $domain_name ) ->whereDomainIsEditable() ->queryRow(); // 404? $domain or PageNotFound::spawn(); } else { // try to create require_permission( 'edit-domain-all' ); if( is_action( 'add-domain' ) && isset( $_POST[ 'domain_name' ] ) ) { // trim and normalize to max length $domain_name = luser_input( $_POST[ 'domain_name' ], 64 ); // existing domain $existing = ( new DomainAPI() ) ->whereDomainName( $domain_name ) ->queryRow(); // go to the existing one if( $existing ) { http_redirect( $existing->getDomainPermalink() ); } // insert this new domain insert_row( Domain::T, [ new DBCol( 'domain_name', $domain_name, 's' ), new DBCol( 'domain_active', 1, 'd' ), new DBCol( 'domain_born', 'NOW()', '-' ), ] ); // go to the new domain http_redirect( Domain::permalink( $domain_name, true ) ); } } // spawn header Header::spawn( [ + 'uid' => false, 'title-prefix' => __( "Domain" ), 'title' => $domain_name ? $domain_name : __( "Add" ), ] ); if( $domain ) { // spawn the domain template template( 'domain', [ 'domain' => $domain, ] ); } else { // form to create the domain template( 'domain-create' ); } // spawn the footer Footer::spawn(); diff --git a/www/ftp.php b/www/ftp.php index c250275..b57aeee 100644 --- a/www/ftp.php +++ b/www/ftp.php @@ -1,151 +1,152 @@ . /* * This is the single FTP account creation/edit page */ // load framework require '../load.php'; // wanted informations $domain = null; $ftp = null; // URL paramenters (maximum both domain and FTP login, minimum just domain) list( $domain_name, $ftp_login ) = url_parts( 2, 1 ); // eventually retrieve mailforward from database if( $ftp_login ) { $ftp = ( new FTPAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'ftp_login', ] ) ->joinFTPDomain() ->whereDomainName( $domain_name ) ->whereFTPLogin( $ftp_login ) ->whereDomainIsEditable() ->queryRow(); // 404 $ftp or PageNotFound::spawn(); // recycle the mailforward object that has domain informations $domain = $ftp; } // eventually retrieve domain from database if( ! $domain ) { $domain = ( new DomainAPI() ) ->select( [ 'domain.domain_ID', 'domain.domain_name', ] ) ->whereDomainName( $domain_name ) ->whereDomainIsEditable() ->queryRow(); // 404 $domain or PageNotFound::spawn(); } if( ! $ftp ) { // to create an FTP user, must edit all FTP users require_permission( 'edit-ftp-all' ); } // save destination action if( is_action( 'ftp-save' ) ) { // save source only during creation if( ! $ftp ) { // sanitize if( ! isset( $_POST[ 'ftp_login' ] ) ) { BadRequest::spawn( __( "missing parameter" ) ); } $username = luser_input( $_POST[ 'ftp_login' ], 128 ); if( ! validate_mailbox_username( $username ) ) { BadRequest::spawn( __( "invalid mailbox name" ) ); } // check existence $ftp_exists = ( new FTPAPI ) ->select( 1 ) ->whereDomain( $domain ) ->whereFTPLogin( $username ) ->queryRow(); // die if exists if( $ftp_exists ) { BadRequest::spawn( __( "FTP account already existing" ) ); } // insert as new row insert_row( 'ftp', [ new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ), new DBCol( 'ftp_login', $username, 's' ), ] ); // POST/redirect/GET http_redirect( FTP::permalink( $domain->getDomainName(), $username, true ), 303 ); } } // delete action if( $ftp ) { // action fired when deleting a whole mailforward if( is_action( 'ftp-delete' ) ) { // delete the account ( new FTPAPI() ) ->whereFTP( $ftp ) ->delete(); // POST/redirect/GET http_redirect( $domain->getDomainPermalink( true ), 303 ); } } // spawn header Header::spawn( [ + 'uid' => false, 'title-prefix' => __( "FTP user" ), 'title' => $ftp ? $ftp->getFTPLogin() : __( "create" ), 'breadcrumb' => [ new MenuEntry( null, $domain->getDomainPermalink(), $domain->getDomainName() ), ], ] ); // spawn the page content template( 'ftp', [ 'domain' => $domain, 'ftp' => $ftp, ] ); // spawn the footer Footer::spawn(); diff --git a/www/login.php b/www/login.php index 41b236b..bf0110a 100644 --- a/www/login.php +++ b/www/login.php @@ -1,76 +1,77 @@ . /* * This is the login page */ // load framework require '../load.php'; // spawn header Header::spawn(); // go to the wanted page (or homepage) -if( login() ) { +if( isset( $_POST['user_uid'] ) && login() ) { http_redirect( after_login_url(), 307 ); } ?>

    - " /> + " required="required" />
    - +

    getSitePage( URL ); + return menu_entry( 'index' )->getURL(); } diff --git a/www/mailbox.php b/www/mailbox.php index 81d0138..5080bd0 100644 --- a/www/mailbox.php +++ b/www/mailbox.php @@ -1,132 +1,133 @@ . /* * This is the mailbox edit page */ // load framework require '../load.php'; // wanted domain and mailbox username list( $domain_name, $mailbox_username ) = url_parts( 2, 1 ); $domain = null; $mailbox = null; $mailbox_password = null; if( $mailbox_username ) { // retrieve the mailbox and its domain $mailbox = ( new MailboxFullAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'domain_active', 'mailbox_username', ] ) ->whereDomainName( $domain_name ) ->whereStr( 'mailbox_username', $mailbox_username ) ->whereMailboxIsEditable() ->queryRow(); // 404? $mailbox or PageNotFound::spawn(); // the mailbox has the domain stuff $domain = $mailbox; } else { // retrieve just the domain $domain = ( new DomainAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'domain_active', ] ) ->whereDomainName( $domain_name ) ->whereDomainIsEditable() ->queryRow(); // 404? $domain or PageNotFound::spawn(); } /* * Change the mailbox password */ if( $mailbox && is_action( 'mailbox-password-reset' ) ) { $mailbox_password = $mailbox->updateMailboxPassword(); } /* * Create the mailbox */ if( !$mailbox && is_action( 'mailbox-create' ) && isset( $_POST[ 'mailbox_username' ] ) ) { // TODO: check max. creation number in single domain props require_permission( 'edit-email-all' ); $_POST[ 'mailbox_username' ] = luser_input( $_POST[ 'mailbox_username' ], 64 ); $mailbox = ( new MailboxFullAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'mailbox_username', ] ) ->whereDomainName( $domain_name ) ->whereStr( 'mailbox_username', $_POST[ 'mailbox_username' ] ) ->queryRow(); if( !$mailbox ) { insert_row( 'mailbox', [ new DBCol( 'mailbox_username', $_POST[ 'mailbox_username' ], 's' ), new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ), ] ); } $mailbox = ( new MailboxFullAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', 'mailbox_username', ] ) ->whereDomainName( $domain_name ) ->whereStr( 'mailbox_username', $_POST[ 'mailbox_username' ] ) ->queryRow(); if( $mailbox ) { http_redirect( $mailbox->getMailboxPermalink( true ) ); } } // spawn header Header::spawn( [ + 'uid' => false, 'title-prefix' => __( "Mailbox" ), 'title' => $mailbox ? $mailbox->getMailboxAddress() : __( "create" ), 'breadcrumb' => [ new MenuEntry( null, $domain->getDomainPermalink(), $domain->getDomainName() ), ], ] ); // spawn the page content template( 'mailbox', [ 'mailbox' => $mailbox, 'mailbox_password' => $mailbox_password, 'domain' => $domain, ] ); // spawn the footer Footer::spawn(); diff --git a/www/mailforward.php b/www/mailforward.php index 92b3485..ad2e2a6 100644 --- a/www/mailforward.php +++ b/www/mailforward.php @@ -1,182 +1,183 @@ . /* * This is the single e-mail forwarding edit page */ // load framework require '../load.php'; // wanted informations $domain = null; $mailforwardfrom = null; // URL paramenters (maximum both domain and mailforward source, minimum just domain) list( $domain_name, $mailforwardfrom_username ) = url_parts( 2, 1 ); // eventually retrieve mailforward from database if( $mailforwardfrom_username ) { $mailforwardfrom = ( new MailforwardfromAPI ) ->select( [ 'domain.domain_ID', 'domain_name', 'mailforwardfrom.mailforwardfrom_ID', 'mailforwardfrom_username', ] ) ->whereDomainName( $domain_name ) ->whereMailforwardfromUsername( $mailforwardfrom_username ) ->whereDomainIsEditable() ->queryRow(); // 404 $mailforwardfrom or PageNotFound::spawn(); // recycle the mailforward object that has domain informations $domain = $mailforwardfrom; } // eventually retrieve domain from database if( ! $domain ) { $domain = ( new DomainAPI() ) ->select( [ 'domain.domain_ID', 'domain.domain_name', ] ) ->whereDomainName( $domain_name ) ->whereDomainIsEditable() ->queryRow(); // 404 $domain or PageNotFound::spawn(); } // save destination action if( is_action( 'mailforward-save' ) ) { // save source only during creation if( ! $mailforwardfrom ) { // sanitize if( ! isset( $_POST[ 'mailforwardfrom_username' ] ) ) { BadRequest::spawn( __( "missing parameter" ) ); } $username = luser_input( $_POST[ 'mailforwardfrom_username' ], 128 ); if( ! validate_mailbox_username( $username ) ) { BadRequest::spawn( __( "invalid mailbox name" ) ); } // check existence $mailforwardfrom_exists = ( new MailforwardfromAPI ) ->select( 1 ) ->whereDomain( $domain ) ->whereMailforwardfromUsername( $username ) ->queryRow(); // die if exists if( $mailforwardfrom_exists ) { BadRequest::spawn( __( "e-mail forwarding already existing" ) ); } // insert as new row insert_row( 'mailforwardfrom', [ new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ), new DBCol( 'mailforwardfrom_username', $username, 's' ), ] ); // POST/redirect/GET http_redirect( Mailforwardfrom::permalink( $domain->getDomainName(), $username, true ), 303 ); } } // delete action if( $mailforwardfrom ) { // action fired when deleting a whole mailforward if( is_action( 'mailforward-delete' ) ) { // drop th query( sprintf( "DELETE FROM %s WHERE domain_ID = %d AND mailforwardfrom_username = '%s'", T( 'mailforwardfrom' ), $mailforwardfrom->getDomainID(), $mailforwardfrom->getMailforwardfromUsername() ) ); // POST/redirect/GET http_redirect( $domain->getDomainPermalink( true ), 303 ); } // action fired when adding/removing a mailforward if( ( is_action( 'mailforwardto-add' ) || is_action( 'mailforwardto-remove' ) ) && isset( $_POST[ 'address' ] ) ) { $address = require_email( $_POST[ 'address' ] ); if( $address === $mailforwardfrom->getMailforwardfromAddress() ) { BadRequest::spawn( __( "do not try to create a loop" ) ); } $existing_address = ( new MailforwardtoAPI() ) ->whereMailforwardfrom( $mailforwardfrom ) ->whereMailforwardtoAddress( $address ) ->queryRow(); // action fired when removing a mailforward if( is_action( 'mailforwardto-remove' ) && $existing_address ) { query( sprintf( "DELETE FROM %s WHERE mailforwardfrom_ID = %d and mailforwardto_address = '%s'", T( 'mailforwardto' ), $mailforwardfrom->getMailforwardfromID(), esc_sql( $address ) ) ); } // action fired when adding a mailforward if( is_action( 'mailforwardto-add' ) && ! $existing_address ) { insert_row( 'mailforwardto', [ new DBCol( 'mailforwardfrom_ID', $mailforwardfrom->getMailforwardfromID(), 'd' ), new DBCol( 'mailforwardto_address', $address, 's' ), ] ); } } } // spawn header Header::spawn( [ + 'uid' => false, 'title-prefix' => __( "E-mail forwarding" ), 'title' => $mailforwardfrom ? $mailforwardfrom->getMailforwardfromAddress() : __( "create" ), 'breadcrumb' => [ new MenuEntry( null, $domain->getDomainPermalink(), $domain->getDomainName() ), ], ] ); // spawn the page content template( 'mailforward', [ 'domain' => $domain, 'mailforwardfrom' => $mailforwardfrom, ] ); // spawn the footer Footer::spawn();