diff --git a/include/class-Log.php b/include/class-Log.php index 2bbc586..1a9dfd9 100644 --- a/include/class-Log.php +++ b/include/class-Log.php @@ -1,216 +1,268 @@ . // make sure that this class is loaded at startup class_exists( User::class ); class_exists( Domain::class ); class_exists( Mailbox::class ); +class_exists( Mailforwardfrom::class ); trait LogTrait { /** * Get the log actor name * * @return string */ public function getLogActorFirm() { return User::firm( $this->get( 'actor_uid' ) ); } /** * Get the action family * * @return string */ public function getLogFamily() { return $this->get( 'log_family' ); } /** * Get the action */ public function getLogAction() { return $this->get( 'log_action' ); } /** * Get the action */ public function getLogDate() { return $this->get( 'log_timestamp' ); } /** * Get the log message * * @param array $args Arguments * @return self */ public function getLogMessage( $args ) { $family = $this->getLogFamily(); $action = $this->getLogAction(); // trigger the right message family switch( $family ) { case 'domain': return self::domainMessage( $action, $this, $args ); case 'mailbox': return self::mailboxMessage( $action, $this, $args ); + case 'mailforward': + return self::mailforwardMessage( $action, $this, $args ); } return self::unknownAction( $family, $action ); } /** * Get the log message alongside the date and the actor name * * @param array $args Arguments * @return self */ public function getLogMessageWithDateAndUser( $args ) { $actor = $args['actor'] ?? $this; // create the Actor firm from the passed User object or from the Log $actor_firm = $actor instanceof User ? $actor->getUserFirm() : $actor->getLogActorFirm(); return sprintf( "%s - %s %s", $this->getLogDate()->format( __( "Y-m-d H:i" ) ), $actor_firm, $this->getLogMessage( $args ) ); } protected function normalizeLog() { $this->datetimes( 'log_timestamp' ); } } /** * A generic log of an action * * Something happened. Dunno what. */ class Log extends Queried { use LogTrait; use UserTrait; use DomainTrait; use MailboxTrait; + use MailforwardfromTrait; public function __construct() { $this->normalizeLog(); } /** * Database table name */ const T = 'log'; /** * Generate a Domain-related message * * @param string $action The related action name * @param object $log * @param array $args Arguments * @return string Message */ public static function domainMessage( $action, $log, $args ) { /** * You can pass some objects to build the message: * * A complete 'actor' User object * A complete 'domain' Domain object */ $domain = $args['domain'] ?? $log; $plan = $args['plan'] ?? $log; switch( $action ) { // an administrator has changed the Plan for a Domain case 'plan.change': return sprintf( __( "changed the Plan for %s to %s" ), $domain->getDomainFirm(), esc_html( $plan->getPlanName() ) ); } // default dummy message return self::unknownAction( 'domain', $action ); } /** * Generate a Mailbox-related message * * @param string $action The related action name * @param object $log * @param array $args Arguments * @return string Message */ public static function mailboxMessage( $action, $log, $args ) { /** * You can pass some objects to build the message: * * A complete 'actor' User object * A complete 'domain' Domain object * A complete 'mailbox' Mailbox object */ $actor = $args['actor'] ?? $log; $domain = $args['domain'] ?? $log; $mailbox = $args['mailbox'] ?? $log; $mailbox_firm = Mailbox::firm( $domain->getDomainName(), $mailbox->getMailboxUsername() ); // trigger the right action message switch( $action ) { // the mailbox was created case 'create': return sprintf( __( "created the mailbox %s" ), $mailbox_firm ); + // the description was changed case 'description.change': return sprintf( __( "edited description of %s" ), $mailbox_firm ); } // default dummy message return self::unknownAction( 'mailbox', $action ); } + /** + * Generate a Mailforward-related message + * + * @param string $action The related action name + * @param object $log + * @param array $args Arguments + * @return string Message + */ + public static function mailforwardMessage( $action, $log, $args ) { + + /** + * You can pass some objects to build the message: + * + * A complete 'domain' Domain object + * A complete 'mailbox' Mailbox object + */ + $domain = $args['domain'] ?? $log; + $mailforward = $args['mailforward'] ?? $log; + + $firm = Mailforwardfrom::firm( + $domain->getDomainName(), + $mailforward->getMailforwardfromUsername() + ); + + // trigger the right action message + switch( $action ) { + + // a Mailforward destination was added + case 'add.destination': + return sprintf( + __( "added a destination for %s" ), + $firm + ); + + // a Mailforward destination was removed + case 'remove.destination': + return sprintf( + __( "removed a destination for %s" ), + $firm + ); + } + + // default dummy message + return self::unknownAction( 'mailforward', $action ); + + } + private static function unknownAction( $family, $action ) { return esc_html( sprintf( __( "misterious action about %s (%s)" ), $family, $action ) ); } } diff --git a/include/class-QueryLog.php b/include/class-QueryLog.php index 1ad52b8..ad60dcf 100644 --- a/include/class-QueryLog.php +++ b/include/class-QueryLog.php @@ -1,200 +1,203 @@ . // make sure that this class is loaded class_exists( MailboxAPI::class ); /** * Methods of a QueryLog object */ trait QueryLogTrait { /** * Filter to a specific log family * * @param string $family * @return self */ public function whereLogFamily( $family ) { return $this->whereStr( 'log_family', $family ); } /** * Filter to a specific actor * * The actor is the user who performed the action. * * @param object $user Actor * @return self */ public function whereLogActor( $user ) { return $this->whereLogActorID( $user->getUserID() ); } /** * Filter to a specific marionette User ID * * The marionette is the user touched by the actor. * * @param string $id User ID * @return self */ public function whereLogMarionette( $id ) { return $this->whereLogMarionetteID( $user->getUserID() ); } /** * Filter to a certain actor ID * * The actor is the user who performed the action. * * @param string $id User ID * @return self */ public function whereLogActorID( $id ) { return $this->whereInt( 'actor_ID', $id ); } /** * Filter to a specific marionette User ID * * The marionette is the user touched by the actor. * * @param string $id User ID * @return self */ public function whereLogMarionetteID( $id ) { return $this->whereInt( 'marionette_ID', $id ); } /** * Order by the log timestamp * * @param string $dir Direction * @return self */ public function orderByLogTimestamp( $dir = 'DESC' ) { return $this->orderBy( 'log_timestamp', $dir ); } /** * Join with the tables that are necessary to build the log message * * @param array $skip_join Array of entities to do not join * @return self */ public function joinLogMessageTables( $skip_join = [] ) { // as default nothing is skipped $skip_actor = $skip_join['actor'] ?? false; $skip_marionette = $skip_join['marionette'] ?? false; $skip_domain = $skip_join['domain'] ?? false; $skip_mailbox = $skip_join['mailbox'] ?? false; $skip_plan = $skip_join['plan'] ?? false; $skip_mailforwardfrom = $skip_join['mailforwardfrom'] ?? false; // inner join with the User table to retrieve the actor (the user who has done the action) if( !$skip_actor ) { // type, table, first column, second column, table alias $this->joinOn( 'INNER', 'user', 'actor_ID', 'actor.user_ID', 'actor' ); $this->select( [ 'actor_ID', 'actor.user_uid AS actor_uid', ] ); } // left join with the User table to retrieve the marionette (the user affected by this action) if( !$skip_marionette ) { // type, table, first column, second column, table alias $this->joinOn( 'LEFT', 'user', 'marionette_ID', 'marionette.user_ID', 'marionette' ); $this->select( [ 'marionette_ID', 'marionette.user_uid AS marionette_uid', ] ); } // left join with the Domain table if( !$skip_domain ) { // type, table, first column, second column $this->joinOn( 'LEFT', 'domain', 'domain.domain_ID', 'log.domain_ID' ); $this->select( [ 'domain.domain_ID', 'domain_name', ] ); } // left join with the Mailbox table if( !$skip_mailbox ) { // type, table, first column, second column $this->joinOn( 'LEFT', 'mailbox', 'mailbox.mailbox_ID', 'log.mailbox_ID' ); $this->select( [ 'mailbox_username', ] ); } // left join with the Mailforwardfrom table if( !$skip_mailforwardfrom ) { // type, table, first column, second column $this->joinOn( 'LEFT', 'mailforwardfrom', 'mailforwardfrom.mailforwardfrom_ID', 'log.mailforwardfrom_ID' ); + $this->select( [ + 'mailforwardfrom_username', + ] ); } // left join with the Plan table if( !$skip_plan ) { // type, table, first column, second column $this->joinOn( 'LEFT', 'plan', 'plan.plan_ID', 'log.plan_ID' ); $this->select( [ 'plan_name', ] ); } return $this; } } /** * Query the `log` database table */ class QueryLog extends Query { use QueryLogTrait; use MailboxAPITrait; /** * Univoque Domain ID column name */ const DOMAIN_ID = 'log.domain_ID'; /** * Univoque column name to the Mailbox ID * * @var string */ protected $MAILBOX_ID = 'log.mailbox_ID'; /** * Constructor * * @param object $db Database */ public function __construct( $db = null ) { parent::__construct( $db, Log::class ); // default table $this->from( Log::T ); } }