diff --git a/cli/update-mailbox-quotas.php b/cli/update-mailbox-quotas.php index 4d39d9e..e038f34 100755 --- a/cli/update-mailbox-quotas.php +++ b/cli/update-mailbox-quotas.php @@ -1,91 +1,92 @@ #!/usr/bin/php . require __DIR__ . '/../load.php'; /** * Script to update Mailbox quotas * */ // get every active domain $domains = ( new DomainAPI() ) ->select( [ 'domain.domain_ID', 'domain_name', ] ) ->whereDomainIsActive() ->queryGenerator(); // for each active domain foreach( $domains as $domain ) { $domain_name = $domain->getDomainName(); // validate domain name if( strpos( $domain_name, __ ) !== false ) { error( "domain '$domain_name' is bad" ); continue; } // get every active mailbox of this domain $mailboxes = ( new MailboxAPI() ) ->select( [ 'mailbox_ID', 'mailbox_username', ] ) ->whereDomain( $domain ) ->whereMailboxIsActive() ->queryGenerator(); query( 'START TRANSACTION' ); // for each mailboxes foreach( $mailboxes as $mailbox ) { $mailbox_username = $mailbox->getMailboxUsername(); // validate mailbox name if( strpos( $mailbox_username, __ ) !== false ) { error( "$domain_name.$mailbox_username is bad" ); continue; } + // calculate the quota size $bytes = 0; - $expected_path = MAILBOX_BASE_PATH . __ . $domain_name . __ . $mailbox_username; if( file_exists( $expected_path ) ) { $bytes_raw = system( sprintf( "du --summarize -- %s | cut -f1", escapeshellarg( $expected_path ) ) ); $bytes = (int) $bytes_raw; } - ( new MailboxQuotaAPI() ) + // store the value + ( new MailboxSizeAPI() ) ->insertRow( [ 'mailbox_ID' => $mailbox->getMailboxID(), - 'mailboxquota_bytes' => $bytes, - new DBCol( 'mailboxquota_date', 'NOW()', '-' ), + 'mailboxsize_bytes' => $bytes, + new DBCol( 'mailboxsize_date', 'NOW()', '-' ), ] ); } query( 'COMMIT' ); } diff --git a/documentation/database/patches/patch-0001-add-denormalized-mailbox-lastquotabytes.sql b/documentation/database/patches/patch-0001-add-denormalized-mailbox-lastquotabytes.sql new file mode 100644 index 0000000..efd9c05 --- /dev/null +++ b/documentation/database/patches/patch-0001-add-denormalized-mailbox-lastquotabytes.sql @@ -0,0 +1,5 @@ +RENAME TABLE `{$prefix}mailboxquota` TO `{$prefix}mailboxsize`; +ALTER TABLE `{$prefix}mailboxsize` CHANGE `mailboxquota_date` `mailboxsize_date` DATETIME NOT NULL; +ALTER TABLE `{$prefix}mailboxsize` CHANGE `mailboxquota_bytes` `mailboxsize_bytes` INT(10) UNSIGNED NOT NULL; +ALTER TABLE `{$prefix}mailboxsize` ADD `mailboxsize_ID` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT FIRST, ADD PRIMARY KEY (`mailboxsize_ID`); + diff --git a/include/class-MailboxQuota.php b/include/class-MailboxSize.php similarity index 61% rename from include/class-MailboxQuota.php rename to include/class-MailboxSize.php index 3606efe..a1cd41a 100644 --- a/include/class-MailboxQuota.php +++ b/include/class-MailboxSize.php @@ -1,83 +1,83 @@ . // load dependent traits class_exists( 'Mailbox' ); /** - * Methods for a MailboxQuota class + * Methods for a MailboxSize class */ -trait MailboxQuotaTrait { +trait MailboxSizeTrait { /** * Get the Mailbox quota date * * @return DateTime */ - public function getMailboxQuotaDate() { - return $this->get( 'mailboxquota_date' ); + public function getMailboxSizeDate() { + return $this->get( 'mailboxsize_date' ); } /** * Get the Mailbox quota bytes * * @return int */ - public function getMailboxQuotaBytes() { - return $this->get( 'mailboxquota_bytes' ); + public function getMailboxSizeBytes() { + return $this->get( 'mailboxsize_bytes' ); } /** * Get the Mailbox quota size readable for humans * * @return string */ - public function getMailboxQuotaHumanSize() { - $size = $this->getMailboxQuotaBytes(); + public function getMailboxSizeHumanSize() { + $size = $this->getMailboxSizeBytes(); return human_filesize( $size ); } /** - * Normalize a MailboxQuota object after being retrieved from database + * Normalize a MailboxSize object after being retrieved from database */ - protected function normalizeMailboxQuota() { - $this->integers( 'mailboxquota_bytes' ); - $this->datetimes( 'mailboxquota_date' ); + protected function normalizeMailboxSize() { + $this->integers( 'mailboxsize_bytes' ); + $this->datetimes( 'mailboxsize_date' ); } } /** * Rappresentation of a Mailbox quota size */ -class MailboxQuota extends Queried { +class MailboxSize extends Queried { - use MailboxQuotaTrait; + use MailboxSizeTrait; /** * Table name */ - const T = 'mailboxquota'; + const T = 'mailboxsize'; /** * Constructor */ public function __construct() { - $this->normalizeMailboxQuota(); + $this->normalizeMailboxSize(); } } diff --git a/include/class-MailboxQuotaAPI.php b/include/class-MailboxSizeAPI.php similarity index 63% rename from include/class-MailboxQuotaAPI.php rename to include/class-MailboxSizeAPI.php index 3d5634e..60a4ab7 100644 --- a/include/class-MailboxQuotaAPI.php +++ b/include/class-MailboxSizeAPI.php @@ -1,89 +1,89 @@ . // load dependend traits class_exists( 'MailboxAPI' ); /** - * Methods for a MailboxQuotaAPI class + * Methods for a MailboxSizeAPI class */ -trait MailboxQuotaAPITrait { +trait MailboxSizeAPITrait { use MailboxAPITrait; /** * Select the MAX Mailbox quota date * * @return self */ - public function selectMaxMailboxQuotaDate() { - return $this->select( 'MAX( mailboxquota_date ) AS max_mailboxquota_date' ) - ->groupBy( 'mailboxquota_date' ); + public function selectMaxMailboxSizeDate() { + return $this->select( 'MAX( mailboxsize_date ) AS max_mailboxsize_date' ) + ->groupBy( 'mailboxsize_date' ); } /** * Assure that this is only the more updated Mailbox quota * * @return self */ - public function whereMailboxQuotaIsLast() { + public function whereMailboxSizeIsLast() { // subquery with a maximum constraint - $max = ( new MailboxQuotaAPI( null, false ) ) - ->fromCustom( DB::instance()->getTable( 'mailboxquota', 'mailboxquota_sub' ) ) - ->equals( 'mailboxquota.mailbox_ID', 'mailboxquota_sub.mailbox_ID' ) - ->selectMaxMailboxQuotaDate() + $max = ( new MailboxSizeAPI( null, false ) ) + ->fromCustom( DB::instance()->getTable( 'mailboxsize', 'mailboxsize_sub' ) ) + ->equals( 'mailboxsize.mailbox_ID', 'mailboxsize_sub.mailbox_ID' ) + ->selectMaxMailboxSizeDate() ->getQuery(); - return $this->where( sprintf( 'mailboxquota_date = (%s)', $max ) ); + return $this->where( sprintf( 'mailboxsize_date = (%s)', $max ) ); } } /** - * MailboxQuota API + * MailboxSize API */ -class MailboxQuotaAPI extends Query { +class MailboxSizeAPI extends Query { - use MailboxQuotaAPITrait; + use MailboxSizeAPITrait; /** * Univoque column name to the Mailbox ID */ - protected $MAILBOX_ID = 'mailboxquota.mailbox_ID'; + protected $MAILBOX_ID = 'mailboxsize.mailbox_ID'; /** * Constructor * * @param object $db Database * @param mixed $from Set to false to avoid to use the default FROM */ public function __construct( $db = null, $from = true ) { // set database and class name - parent::__construct( $db, MailboxQuota::class ); + parent::__construct( $db, MailboxSize::class ); /** * Set database table (sometime the standard alias it's not useful) * - * See MailboxQuotaAPI class. + * See MailboxSizeAPI class. */ if( $from ) { - $this->from( MailboxQuota::T ); + $this->from( MailboxSize::T ); } } } diff --git a/load-post.php b/load-post.php index 18d7f48..21b67df 100644 --- a/load-post.php +++ b/load-post.php @@ -1,129 +1,129 @@ . /** * This is your versioned configuration file * * It does not contains secrets. * * This file is required after loading your * unversioned configuration file: * * load.php */ // database version // // you can increase your database version if you added some patches in: // documentation/database/patches -define( 'DATABASE_VERSION', 0 ); +define( 'DATABASE_VERSION', 1 ); // include path define_default( 'INCLUDE_PATH', ABSPATH . __ . 'include' ); // template path define_default( 'TEMPLATE_PATH', ABSPATH . __ . 'template' ); // autoload classes from the /include directory spl_autoload_register( function( $name ) { // TODO: autoload classes and create DomainTrait and use in Mailbox $path = INCLUDE_PATH . __ . "class-$name.php"; if( is_file( $path ) ) { require $path; } } ); // override default user class define( 'SESSIONUSER_CLASS', 'User' ); // load common functions require INCLUDE_PATH . __ . 'functions.php'; // jquery URL // provided by the libjs-jquery package as default define_default( 'JQUERY_URL', '/javascript/jquery/jquery.min.js' ); // Bootstrap CSS/JavaScript files without trailing slash // provided by the libjs-bootstrap package as default define_default( 'BOOTSTRAP_DIR_URL', '/javascript/bootstrap' ); // path to the Net SMTP class // provided by the php-net-smtp package as default define_default( 'NET_SMTP', '/usr/share/php/Net/SMTP.php' ); // base directory for your virtualhosts // e.g. you may have /var/www/example.com/index.html // do NOT end with a slash // TODO: support multiple hosts define_default( 'VIRTUALHOSTS_DIR', '/var/www' ); // default currency simbol define_default( 'DEFAULT_CURRENCY_SYMBOL', '€' ); // register JavaScript/CSS files register_js( 'jquery', JQUERY_URL ); register_js( 'bootstrap', BOOTSTRAP_DIR_URL . '/js/bootstrap.min.js' ); register_css( 'bootstrap', BOOTSTRAP_DIR_URL . '/css/bootstrap.min.css' ); register_css( 'custom-css', ROOT . '/content/style.css' ); // GNU Gettext i18n define( 'GETTEXT_DOMAIN', 'reyboz-hosting-panel' ); define( 'GETTEXT_DIRECTORY', 'l10n' ); define( 'GETTEXT_DEFAULT_ENCODE', CHARSET ); // UTF-8 // common strings define_default( 'SITE_NAME', "KISS Libre Hosting Panel" ); define_default( 'CONTACT_EMAIL', 'support@' . DOMAIN ); define_default( 'REPO_URL', 'https://gitpull.it/project/profile/15/' ); // limit session duration to 5 minutes (60s * 100m) define_default( 'SESSION_DURATION', 6000 ); /** * Mailbox base path * * Used by CLI scripts to calculate the current quotas. * * The mailboxes should have paths like: * MAILBOX_BASE_PATH/domain_name/user_name/ */ define_default( 'MAILBOX_BASE_PATH', '/home/vmail' ); // register web pages add_menu_entries( [ new MenuEntry( 'index', '/', __( "Dashboard" ), null, 'backend' ), new MenuEntry( 'login', 'login.php', __( "Login" ) ), new MenuEntry( 'profile', 'profile.php', __( "Profile" ) ), new MenuEntry( 'logout', 'logout.php', __( "Logout" ), null, 'read' ), new MenuEntry( 'user-list', 'user-list.php', __( "Users" ), null, 'edit-user-all' ), new MenuEntry( 'password-reset', 'password-reset.php', __( "Password reset" ) ), ] ); // permissions of a normal user register_permissions( 'user', [ 'read', 'backend', ] ); // permissions of an admin inherit_permissions( 'admin', 'user', [ 'edit-user-all', 'edit-email-all', 'edit-domain-all', 'edit-plan-all', 'edit-ftp-all', ] ); diff --git a/template/mailbox-stats.php b/template/mailbox-stats.php index 2177183..d34c564 100644 --- a/template/mailbox-stats.php +++ b/template/mailbox-stats.php @@ -1,57 +1,57 @@ . /* * This is the template for some mailbox stats * * Called from: * template/mailbox.php * * Available variables: * $mailbox object * $plan object */ // avoid to be load directly defined( 'BOZ_PHP' ) or die; // calculate the quota -$quota = ( new MailboxQuotaAPI() ) - ->select( 'mailboxquota_bytes' ) +$quota = ( new MailboxSizeAPI() ) + ->select( 'mailboxsize_bytes' ) ->whereMailbox( $mailbox ) - ->whereMailboxQuotaIsLast() + ->whereMailboxSizeIsLast() ->queryRow(); ?>

- +
getMailboxQuotaHumanSize() ?>getMailboxSizeHumanSize() ?>