diff --git a/include/class-Mailforwardfrom.php b/include/class-Mailforwardfrom.php index f9736b0..9aa8393 100644 --- a/include/class-Mailforwardfrom.php +++ b/include/class-Mailforwardfrom.php @@ -1,127 +1,127 @@ . /** * Methods for a Mailforwardfrom class */ trait MailforwardfromTrait { /** * Get the mailforward from ID * * @return int */ public function getMailforwardfromID() { return $this->get( 'mailforwardfrom_ID' ); } /** * Get the mailforward from address * * @return string E-mail */ public function getMailforwardfromAddress() { - return sprintf( '%s@%s', + return Mailbox::address( $this->getMailforwardfromUsername(), $this->getDomainName() ); } /** * Get the mailforward from username * * @return string */ public function getMailforwardfromUsername() { return $this->get( 'mailforwardfrom_username' ); } /** * Get the mailforward permalink * * @param $absolute boolean * @return string */ public function getMailforwardfromPermalink( $absolute = false ) { return Mailforwardfrom::permalink( $this->getDomainName(), $this->getMailforwardfromUsername(), $absolute ); } /** * Normalize a Mailforwardfrom object after being retrieved from database */ protected function normalizeMailforwardfrom() { $this->integers( 'mailforwardfrom_ID' ); } } /** * An e-mail forwarding */ class Mailforwardfrom extends Queried { use MailforwardfromTrait; use DomainTrait; /** * Constructor */ public function __constructor() { $this->normalizeMailforwardfrom(); $this->normalizeDomain(); } /** * Database table name */ const T = 'mailforwardfrom'; /** * Update the related database row */ public function update( $columns ) { query_update( self::T, $columns, sprintf( "mailforwardfrom_ID = %d", $this->getMailforwardfromID() ) ); } /** * Get the mailforward permalink * * @return string */ public static function permalink( $domain, $mailforward = false, $absolute = false ) { $part = site_page( 'mailforward.php', $absolute ) . _ . $domain; if( $mailforward ) { $part .= _ . $mailforward; } return $part; } /** * Force to get a Mailforwardfrom ID, whatever is passed * * @param mixed $mailforward Mailforwardfrom object or its ID * @return int */ public static function getID( $mailforward ) { return is_object( $mailforward ) ? $mailforward->getMailforwardfromID() : (int)$mailforward; } } diff --git a/www/mailforward.php b/www/mailforward.php index 50c74f8..64cd0c3 100644 --- a/www/mailforward.php +++ b/www/mailforward.php @@ -1,197 +1,223 @@ . /* * 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 MailforwardfromQuery() ) ->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 MailforwardfromQuery() ) ->select( 1 ) ->whereDomain( $domain ) ->whereMailforwardfromUsername( $username ) ->queryRow(); // die if exists if( $mailforwardfrom_exists ) { BadRequest::spawn( __( "e-mail forwarding already existing" ) ); } query( 'START TRANSACTION' ); // insert as new row insert_row( 'mailforwardfrom', [ new DBCol( 'domain_ID', $domain->getDomainID(), 'd' ), new DBCol( 'mailforwardfrom_username', $username, 's' ), ] ); // remember this action in the registry APILog::insert( [ 'family' => 'mailforward', 'action' => 'create', + 'domain' => $domain, 'mailforwardfrom' => last_inserted_ID(), ] ); query( 'COMMIT' ); // 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 the existing one // TODO: refactor with Query builder 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( 'START TRANSACTION' ); + // TODO refactor with query builder query( sprintf( "DELETE FROM %s WHERE mailforwardfrom_ID = %d and mailforwardto_address = '%s'", T( 'mailforwardto' ), $mailforwardfrom->getMailforwardfromID(), esc_sql( $address ) ) ); + + // remember that we removed an address + APILog::insert( [ + 'family' => 'mailforward', + 'action' => 'remove.destination', + 'domain' => $domain, + 'mailforwardfrom' => $mailforwardfrom, + ] ); + + query( 'COMMIT' ); } // action fired when adding a mailforward if( is_action( 'mailforwardto-add' ) && ! $existing_address ) { + + query( 'START TRANSACTION' ); + insert_row( 'mailforwardto', [ new DBCol( 'mailforwardfrom_ID', $mailforwardfrom->getMailforwardfromID(), 'd' ), new DBCol( 'mailforwardto_address', $address, 's' ), ] ); + + // remember that we added an address + APILog::insert( [ + 'family' => 'mailforward', + 'action' => 'add.destination', + 'domain' => $domain, + 'mailforwardfrom' => $mailforwardfrom, + ] ); + + query( 'COMMIT' ); } } } // 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();