diff options
| author | lsces <lester@lsces.co.uk> | 2025-08-29 09:50:44 +0100 |
|---|---|---|
| committer | lsces <lester@lsces.co.uk> | 2025-08-29 09:50:44 +0100 |
| commit | 24ac90ba2d2e8911b8b51d251541565f202dd9ce (patch) | |
| tree | 998a5e4a84dc2008d7fe68123a8fc164e7ce5204 /includes | |
| parent | ef37929a5577234fc2a350b6207260c52d5835cd (diff) | |
| download | quota-24ac90ba2d2e8911b8b51d251541565f202dd9ce.tar.gz quota-24ac90ba2d2e8911b8b51d251541565f202dd9ce.tar.bz2 quota-24ac90ba2d2e8911b8b51d251541565f202dd9ce.zip | |
Refactor for PHP8.4, namespace and Smarty5
Diffstat (limited to 'includes')
| -rw-r--r-- | includes/bit_setup_inc.php | 20 | ||||
| -rw-r--r-- | includes/calculate_quota_inc.php | 31 | ||||
| -rw-r--r-- | includes/classes/LibertyQuota.php | 248 | ||||
| -rw-r--r-- | includes/quota_inc.php | 39 |
4 files changed, 332 insertions, 6 deletions
diff --git a/includes/bit_setup_inc.php b/includes/bit_setup_inc.php index 1ec36f8..5cf8fbb 100644 --- a/includes/bit_setup_inc.php +++ b/includes/bit_setup_inc.php @@ -1,10 +1,18 @@ <?php global $gBitSystem, $gBitSmarty; -$registerHash = array( +$pRegisterHash = [ 'package_name' => 'quota', - 'package_path' => dirname( dirname( __FILE__ ) ).'/', - 'homeable' => TRUE, -); -$gBitSystem->registerPackage( $registerHash ); -?> + 'package_path' => dirname( dirname( __FILE__ ) ) . '/', + 'homeable' => true, +]; + +// fix to quieten down VS Code which can't see the dynamic creation of these ... +define( 'QUOTA_PKG_NAME', $pRegisterHash['package_name'] ); +define( 'QUOTA_PKG_URL', BIT_ROOT_URL . basename( $pRegisterHash['package_path'] ) . '/' ); +define( 'QUOTA_PKG_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/' ); +define( 'QUOTA_PKG_INCLUDE_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/includes/'); +define( 'QUOTA_PKG_CLASS_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/includes/classes/'); +define( 'QUOTA_PKG_ADMIN_PATH', BIT_ROOT_PATH . basename( $pRegisterHash['package_path'] ) . '/admin/'); + +$gBitSystem->registerPackage( $pRegisterHash ); diff --git a/includes/calculate_quota_inc.php b/includes/calculate_quota_inc.php new file mode 100644 index 0000000..de4940e --- /dev/null +++ b/includes/calculate_quota_inc.php @@ -0,0 +1,31 @@ +<?php +/** + * @version $Revision$ + * @package quota + * + * settings that are useful to know about at upload time + */ + +/** + * quota setup + */ + +use Bitweaver\KernelTools; +use Bitweaver\Quota\LibertyQuota; + +$quota = new LibertyQuota(); +if( !$gBitUser->isAdmin() && !$quota->isUserUnderQuota( $gBitUser->mUserId ) ) { + $gBitSystem->display( 'bitpackage:quota/over_quota.tpl', KernelTools::tra( 'You are over your quota.' ) , [ 'display_mode' => 'display' ]); + die; +} + +if( !$gBitUser->isAdmin() ) { + // Prevent people from uploading more than their quota + $q = $quota->getUserQuota( $gBitUser->mUserId ); + $u = $quota->getUserUsage( $gBitUser->mUserId ); + $gBitSmarty->assign( 'quotaMessage', KernelTools::tra( 'Your remaining disk quota is' ).' '.round( ( $q - $u ) / 1000000, 2 ).' '.KernelTools::tra( 'Megabytes' ) ); + $qMegs = round( $q / 1000000 ); + if( $qMegs < $uploadMax ) { + $uploadMax = $qMegs; + } +} diff --git a/includes/classes/LibertyQuota.php b/includes/classes/LibertyQuota.php new file mode 100644 index 0000000..4feb6a4 --- /dev/null +++ b/includes/classes/LibertyQuota.php @@ -0,0 +1,248 @@ +<?php +/** + * $Header$ + * + * Copyright (c) 2004 bitweaver.org + * Copyright (c) 2003 tikwiki.org + * Copyright (c) 2002-2003, Luis Argerich, Garland Foster, Eduardo Polidor, et. al. + * All Rights Reserved. See below for details and a complete list of authors. + * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See http://www.gnu.org/copyleft/lesser.html for details + * + * $Id$ + * @package quota + */ + +/** + * required setup + */ + +namespace Bitweaver\Quota; +use Bitweaver\BitBase; +use Bitweaver\Liberty\LibertyBase; + +/** + * Quota class to illustrate best practices when creating a new bitweaver package that + * builds on core bitweaver functionality, such as the Liberty CMS engine + * + * @package quota + * @subpackage LibertyQuota + * + * created 2004/8/15 + * + * @author spider <spider@steelsun.com> + * + * @version $Revision$ + */ +class LibertyQuota extends LibertyBase { + /** + * Primary key for our mythical Quota class object & table + * @public + */ + public $mQuotaId; + + /** + * During initialisation, be sure to call our base constructors + **/ + public function __construct( $pQuotaId=NULL, $pContentId=NULL ) { + $this->mQuotaId = $pQuotaId; + parent::__construct(); + } + + + /** + * Any method named Store inherently implies data will be written to the database + * @param array pParamHash be sure to pass by reference in case we need to make modifcations to the hash + **/ + public function store( &$pParamHash ) { + if( $this->verify( $pParamHash ) ) { + $this->mDb->StartTrans(); + $table = BIT_DB_PREFIX."quotas"; + if( $this->mQuotaId ) { + $result = $this->mDb->associateUpdate( $table, $pParamHash['quota_store'], [ "quota_id" => $pParamHash['quota_id'] ] ); + } else { + $this->mQuotaId = $this->mDb->GenID( 'quota_id_seq' ); + $pParamHash['quota_store']['quota_id'] = $this->mQuotaId; + $result = $this->mDb->associateInsert( $table, $pParamHash['quota_store'] ); + } + $this->load(); + $this->mDb->CompleteTrans(); + } + return( count( $this->mErrors ) == 0 ); + } + + /** + * Make sure the data is safe to store + * @param array pParamHash be sure to pass by reference in case we need to make modifcations to the hash + **/ + public function verify( &$pParamHash ) { + if( isset( $pParamHash['description'] ) ) { + // insure we don't have column overflow, etc. + $pParamHash['quota_store']['description'] = trim( $pParamHash['description'], 0, 160 ); + } + if( !empty( $pParamHash['title'] ) ) { + // insure we don't have column overflow, etc. + $pParamHash['quota_store']['title'] = substr( trim( $pParamHash['title'] ), 0, 160 ); + } else { + $this->mErrors['title'] = "Your quota needs a title"; + } + + if( empty( $pParamHash['disk_usage'] ) || !is_numeric( $pParamHash['disk_usage'] ) ) { + $this->mErrors['disk_usage'] = "Invalid disk usage quantity"; + } else { + $pParamHash['quota_store']['disk_usage'] = $pParamHash['disk_usage'] * 1000000; + } + + if( empty( $pParamHash['monthly_transfer'] ) || !is_numeric( $pParamHash['monthly_transfer'] ) ) { + $this->mErrors['monthly_transfer'] = "Invalid disk usage quantity"; + } else { + $pParamHash['quota_store']['monthly_transfer'] = $pParamHash['monthly_transfer'] * 1000000; + } + + return( count( $this->mErrors ) == 0 ); + } + + /** + * Load the data from the database + * @param array pParamHash be sure to pass by reference in case we need to make modifcations to the hash + **/ + public function load() { + if( $this->mQuotaId ) { + // LibertyContent::load() assumes you have joined already, and will not execute any sql! + // This is a significant performance optimization + $query = "SELECT qo.* FROM `".BIT_DB_PREFIX."quotas` qo WHERE qo.`quota_id`=?"; + $result = $this->mDb->query( $query, [ $this->mQuotaId ] ); + if ( $result && $result->numRows() ) { + $this->mInfo = $result->fields; + $query = "SELECT ug.`group_id`, ug.* FROM `".BIT_DB_PREFIX."users_groups` ug INNER JOIN `".BIT_DB_PREFIX."quotas_group_map` qgm ON( ug.`group_id`=qgm.`group_id` ) WHERE qgm.`quota_id`=?"; + if( $rs = $this->mDb->query( $query, [ $this->mQuotaId ] ) ) { + $this->mInfo['quota_groups'] = $rs->fields; + } + } + } + return count( $this->mInfo ) == 0; + } + + /** + * + **/ + public function getList() { + $query = "SELECT qo.`quota_id`, qo.* FROM `".BIT_DB_PREFIX."quotas` qo"; + $ret = $this->mDb->getAssoc($query); + return $ret; + } + + /** + * + **/ + function getQuotaMenu( $pName='quota_menu', $pSelectId=NULL ) { + $query = "SELECT qo.`title`, qo.`quota_id` FROM `".BIT_DB_PREFIX."quotas` qo"; + if( $rs = $this->mDb->query($query) ) { + $ret = $rs->GetMenu2( $pName, $pSelectId ); + } + return ( $ret ); + } + + function getQuotaGroups() { + $sql = "SELECT ug.`group_id`, ug.*, qgm.`quota_id` + FROM `".BIT_DB_PREFIX."users_groups` ug LEFT OUTER JOIN `".BIT_DB_PREFIX."quotas_group_map` qgm ON( qgm.`group_id`=ug.`group_id` ) + WHERE ug.`user_id`=".ROOT_USER_ID." + ORDER BY ug.`group_name` ASC"; + return $this->mDb->getAssoc( $sql ); + } + + + + /** + * + **/ + function assignQuotaToGroup( $pQuotaId, $pGroupId ) { + if( is_numeric( $pQuotaId ) && is_numeric( $pGroupId ) ) { + $hasRow = $this->mDb->getOne( 'SELECT `quota_id` FROM `'.BIT_DB_PREFIX.'quotas_group_map` WHERE `group_id`=?', [ $pGroupId ] ); + if( $hasRow ) { + $query = 'UPDATE `'.BIT_DB_PREFIX.'quotas_group_map` SET `quota_id`=? WHERE `group_id`=?'; + $rs = $this->mDb->query( $query, [ $pQuotaId, $pGroupId ] ); + } else { + $query = 'INSERT INTO `'.BIT_DB_PREFIX.'quotas_group_map` (`quota_id`, `group_id`) VALUES (?,?)'; + $rs = $this->mDb->query( $query, [ $pQuotaId, $pGroupId ] ); + } + } elseif( is_numeric( $pGroupId ) && empty( $pQuotaId ) ) { + $query = 'DELETE FROM `'.BIT_DB_PREFIX.'quotas_group_map` WHERE `group_id`=?'; + $rs = $this->mDb->query( $query, [ $pGroupId ] ); + } + } + + + /** + * returns the quota and consumption if a user is under usage level + **/ + function isUserUnderQuota( $pUserId ) { + $ret = FALSE; + if( is_numeric( $pUserId ) ) { + $query = 'SELECT MAX(qo.`disk_usage`) AS `disk_usage` + FROM `'.BIT_DB_PREFIX.'users_users` uu + INNER JOIN `'.BIT_DB_PREFIX.'users_groups_map` ugm ON ( ugm.`user_id`=uu.`user_id` ) + INNER JOIN `'.BIT_DB_PREFIX.'quotas_group_map` qgm ON( qgm.`group_id`=ugm.`group_id` ) + INNER JOIN `'.BIT_DB_PREFIX.'quotas` qo ON( qo.`quota_id`=qgm.`quota_id` ) + WHERE uu.`user_id`=?'; + if( $rs = $this->mDb->query( $query, [ $pUserId ] ) ) { + $diskQuota = $rs->fields['disk_usage']; + $diskConsumed = $this->getUserUsage( $pUserId ); + if( $diskQuota == NULL || $diskQuota > $diskConsumed ) { + $ret = [ $diskQuota, $diskConsumed ]; + } + } + } + return $ret; + } + + + /** + * Given a user_id, this will return the max quota for the given user. If the user belongs to more than one group, it will chose the max values + * @param integer pUserId user_id of the user for usage to be calculated for + * @return integer an integer of the total bytes used + */ + public function getUserQuota( $pUserId ) { + $ret = 0; + if( is_numeric( $pUserId ) ) { + $query = 'SELECT MAX(qo.`disk_usage`) AS `disk_usage` + FROM `'.BIT_DB_PREFIX.'users_users` uu + INNER JOIN `'.BIT_DB_PREFIX.'users_groups_map` ugm ON ( ugm.`user_id`=uu.`user_id` ) + INNER JOIN `'.BIT_DB_PREFIX.'quotas_group_map` qgm ON( qgm.`group_id`=ugm.`group_id` ) + INNER JOIN `'.BIT_DB_PREFIX.'quotas` qo ON( qo.`quota_id`=qgm.`quota_id` ) + WHERE uu.`user_id`=?'; + $ret = $this->mDb->getOne( $query, [ $pUserId ] ); + } + return $ret; + } + + /** + * Given a user_id, this will return this disk space used for the given user + * @param integer pUserId user_id of the user for usage to be calculated for + * @return integer an integer of the total bytes used + */ + public function getUserUsage( $pUserId ) { + $ret = 0; + if( is_numeric( $pUserId ) ) { + // INNER JOIN on attachments so orphans are not counted + $ret = $this->mDb->getOne( "SELECT SUM(`file_size`) FROM `".BIT_DB_PREFIX."liberty_files` lf INNER JOIN `".BIT_DB_PREFIX."liberty_attachments` la ON (lf.`file_id`=la.`foreign_id`) WHERE lf.`user_id`=?", array( $pUserId ) ); + } + return $ret; + } + + /** + * Generates the URL to the quota page + * @return string the link to display the page. + */ + public function getDisplayUrl() { + $ret = NULL; + if( BitBase::verifyId( $this->mQuotaId ) ) { + $ret = QUOTA_PKG_URL."index.php?quota_id=".$this->mQuotaId; + } + return $ret; + } + + public function isValid() { + return @BitBase::verifyId( $this->mQuotaId ); + } + +} diff --git a/includes/quota_inc.php b/includes/quota_inc.php new file mode 100644 index 0000000..23125d1 --- /dev/null +++ b/includes/quota_inc.php @@ -0,0 +1,39 @@ +<?php +/** + * @version $Revision$ + * @package quota + * + * settings that are useful to know about at upload time + */ + +/** + * quota setup + */ + +use Bitweaver\Quota\LibertyQuota; + +global $gBitSmarty, $assignUser, $gBitUser; + +if( empty( $pQuotaUserId ) ) { + if( !empty( $assignUser->mUserId ) ) { + $pQuotaUserId = $assignUser->mUserId; + } else { + $pQuotaUserId = $gBitUser->mUserId; + } +} + +$quota = new LibertyQuota(); +$diskUsage = $quota->getUserUsage( $pQuotaUserId ); +$diskQuota = $quota->getUserQuota( $pQuotaUserId ); + +$quotaPercent = $diskQuota != 0 ? round( ( $diskUsage / $diskQuota ) * 100, 0 ) : 0; + +if( $quotaPercent > 100 ) { + $errors['disk_quota'] = "You are over your disk quota."; + $gBitSmarty->assign( 'errors', $errors ); + $quotaPercent = 100; +} + +$gBitSmarty->assign( 'usage', round( $diskUsage / 1000000, 2 ) ); +$gBitSmarty->assign( 'quota', round( $diskQuota / 1000000, 2 ) ); +$gBitSmarty->assign( 'quotaPercent', $quotaPercent ); |
