summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
authorlsces <lester@lsces.co.uk>2025-08-29 09:50:44 +0100
committerlsces <lester@lsces.co.uk>2025-08-29 09:50:44 +0100
commit24ac90ba2d2e8911b8b51d251541565f202dd9ce (patch)
tree998a5e4a84dc2008d7fe68123a8fc164e7ce5204 /includes
parentef37929a5577234fc2a350b6207260c52d5835cd (diff)
downloadquota-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.php20
-rw-r--r--includes/calculate_quota_inc.php31
-rw-r--r--includes/classes/LibertyQuota.php248
-rw-r--r--includes/quota_inc.php39
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 );