GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — stable-3.1 ( e32e88...0c840f )
by
unknown
05:07
created

m_quota::hook_menu()   C

Complexity

Conditions 8
Paths 8

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 2 Features 0
Metric Value
cc 8
eloc 18
c 3
b 2
f 0
nc 8
nop 0
dl 0
loc 27
rs 5.3846
1
<?php
2
3
/*
4
  ----------------------------------------------------------------------
5
  AlternC - Web Hosting System
6
  Copyright (C) 2000-2012 by the AlternC Development Team.
7
  https://alternc.org/
8
  ----------------------------------------------------------------------
9
  LICENSE
10
11
  This program is free software; you can redistribute it and/or
12
  modify it under the terms of the GNU General Public License (GPL)
13
  as published by the Free Software Foundation; either version 2
14
  of the License, or (at your option) any later version.
15
16
  This program is distributed in the hope that it will be useful,
17
  but WITHOUT ANY WARRANTY; without even the implied warranty of
18
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
  GNU General Public License for more details.
20
21
  To read the license please visit http://www.gnu.org/copyleft/gpl.html
22
  ----------------------------------------------------------------------
23
  Purpose of file: Manage user quota
24
  ----------------------------------------------------------------------
25
 */
26
27
/**
28
 * Class for hosting quotas management
29
 *
30
 * This class manages services' quotas for each user of AlternC.
31
 * The available quotas for each service is stored in the system.quotas
32
 * mysql table. The used value is computed by the class using a
33
 * callback function <code>alternc_quota_check($uid)</code> that
34
 * may by exported by each service class.<br>
35
 * each class may also export a function <code>alternc_quota_names()</code>
36
 * that returns an array with the quotas names managed by this class.
37
 *
38
 */
39
class m_quota {
40
41
    var $disk = Array();  /* disk resource for which we will manage quotas */
42
    var $disk_quota_enable;
43
    var $quotas;
44
    var $clquota; // Which class manage which quota.
45
46
    /* ----------------------------------------------------------------- */
47
48
    /**
49
     * Constructor
50
     */
51
    function m_quota() {
52
        $this->disk_quota_enable = variable_get('disk_quota_enable', 1, 'Are disk quota enabled for this server', array('desc' => 'Enabled', 'type' => 'boolean'));
53
        if ($this->disk_quota_enable) {
54
            $this->disk = Array("web" => "web");
55
        }
56
    }
57
58
    private function dummy_for_translation() {
59
        _("quota_web");
60
    }
61
62
    function hook_menu() {
63
        $obj = array(
64
            'title' => _("Show my quotas"),
65
            'ico' => 'images/quota.png',
66
            'link' => 'toggle',
67
            'pos' => 110,
68
            'divclass' => 'menu-quota',
69
            'links' => array(),
70
        );
71
72
        $q = $this->getquota();
73
74
	foreach ($q as $key=>$value)
75
	if (($key=="web")||(isset($value['in_menu'])&&$value['in_menu'])) {
76
		if (!isset($q[$key]["u"]) || empty($q[$key]["t"])) {
77
        	        continue;
78
		}
79
	            
80
		$usage_percent = (int) ($q[$key]["u"] / $q[$key]["t"] * 100);
81
		$obj['links'][] = array('txt' => _("quota_" . $key) . " " . sprintf(_("%s%% of %s"), $usage_percent, format_size($q[$key]["t"] * 1024)), 'url' => 'quota_show.php');
82
		$obj['links'][] = array('txt' => 'progressbar', 'total' => $q[$key]["t"], 'used' => $q[$key]["u"]);
83
	}
84
85
        // do not return menu item if there is no quota
86
	if (!count($obj['links'])) return false;
87
        return $obj;
88
    }
89
90
    function hook_homepageblock() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
91
	return (object)Array(
92
		'pos' => 20,
93
		'call'=> function() {
94
			define("QUOTASONE","1");
95
		},
96
		'include' => "quotas_oneuser.php"
97
	);
98
    }
99
100
    /* ----------------------------------------------------------------- */
101
102
    /** Check if a user can use a ressource.
103
     * @param string $ressource the ressource name (a named quota)
104
     * @Return TRUE if the user can create a ressource (= is there any quota left ?)
105
     * @return boolean
106
     */
107
    function cancreate($ressource = "") {
108
        $t = $this->getquota($ressource);
109
        return $t["u"] < $t["t"];
110
    }
111
112
    /* ----------------------------------------------------------------- */
113
114
    /** List the quota-managed services in the server
115
     * @Return array the quota names and description (translated)
116
     */
117
    function qlist() {
118
        $qlist = array();
119
        reset($this->disk);
120
        while (list($key, $val) = each($this->disk)) {
121
            $qlist[$key] = _("quota_" . $key); // those are specific disks quotas.
122
        }
123
124
        foreach ($this->getquota() as $qq) {
125
            if (isset($qq['name'])) {
126
                $qlist[$qq['name']] = $qq['description'];
127
            }
128
        }
129
        return $qlist;
130
    }
131
132
    /**
133
     * Synchronise the quotas of the users with the quota of the
134
     * user's profile.
135
     * If the user have a greater quota than the profile, no change.
136
     * If the quota entry doesn't exist for the user, create it with
137
     * the defaults value.
138
     */
139
    function synchronise_user_profile() {
140
        global $db, $err;
141
        $err->log("quota", "synchronise_user_profile");
142
        $q = "insert into quotas select m.uid as uid, d.quota as name, d.value as total from membres m, defquotas d left join quotas q on q.name=d.quota  where m.type=d.type  ON DUPLICATE KEY UPDATE total = greatest(d.value, quotas.total);";
143
        if (!$db->query($q)) {
144
            return false;
145
        }
146
        return true;
147
    }
148
149
    /*
150
     * Create default quota in the profile
151
     * when a new quota appear
152
     *
153
     */
154
155
    function create_missing_quota_profile() {
156
        global $db, $quota, $err;
157
        $err->log("quota", "create_missing_quota_profile");
158
        $qt = $quota->getquota('', true);
159
        $type = $quota->listtype();
160
        foreach ($type as $t) {
161
            foreach ($qt as $q => $vv) {
162
                $db->query("INSERT IGNORE defquotas (value,quota,type) VALUES (0, ?, ?);", array($q, $t));
163
            }
164
        }
165
        return true;
166
    }
167
168
    /* ----------------------------------------------------------------- */
169
170
    /** Return a ressource usage (u) and total quota (t)
171
     * @param string $ressource ressource to get quota of
172
     * @Return array the quota used and total for this ressource (or for all ressource if unspecified)
173
     */
174
    function getquota($ressource = "", $recheck = false) {
175
        global $db, $err, $cuid, $get_quota_cache, $hooks, $mem;
176
        $err->log("quota", "getquota", $ressource);
177
        if ($recheck) { // rebuilding quota
178
            $get_quota_cache = null;
179
            $this->quotas = array();
180
        }
181
        if (!empty($get_quota_cache[$cuid])) {
182
            // This function is called many time each webpage, so I cache the result
183
            $this->quotas = $get_quota_cache[$cuid];
184
        } else {
185
            $res = $hooks->invoke("hook_quota_get");
186
            foreach ($res as $r) {
187
                $this->quotas[$r['name']] = $r;
188
                $this->quotas[$r['name']]['u'] = $r['used']; // retrocompatibilité
189
                $this->quotas[$r['name']]['t'] = 0; // Default quota = 0
190
            }
191
            reset($this->disk);
192
193
            if (!empty($this->disk)) { // Check if there are some disk quota to check
194
                // Look if there are some cached value
195
                $disk_cached = $mem->session_tempo_params_get('quota_cache_disk');
196
197
                while (list($key, $val) = each($this->disk)) {
198
                    $a = array();
199
                    if (
200
                            isset($disk_cached[$val]) && !empty($disk_cached[$val]) && $disk_cached[$val]['uid'] == $cuid && $disk_cached[$val]['timestamp'] > ( time() - (90) ) // Cache, en seconde
201
                    ) {
202
                        // If there is a cached value
203
                        $a = $disk_cached[$val];
204
                    } else {
205
                        exec("/usr/lib/alternc/quota_get " . intval($cuid), $ak);
206
                        $a['u'] = intval($ak[0]);
207
                        $a['t'] = @intval($ak[1]);
208
                        $a['timestamp'] = time();
209
                        $a['uid'] = $cuid;
210
                        $disk_cached = $mem->session_tempo_params_set('quota_cache_disk', array($val => $a));
211
                    }
212
                    $this->quotas[$val] = array("name" => "$val", 'description' => _("quota_" . $val), "t" => $a['t'], "u" => $a['u']);
213
                }
214
            }
215
216
            // Get the allowed quota from database.
217
            $db->query("select name, total from quotas where uid= ? ;", array($cuid));
218
            while ($db->next_record()) {
219
                $this->quotas[$db->f('name')]['t'] = $db->f('total');
220
            }
221
222
            $get_quota_cache[$cuid] = $this->quotas;
223
        }
224
225
        if ($ressource) {
226
            if (isset($this->quotas[$ressource])) {
227
                return $this->quotas[$ressource];
228
            } else {
229
                return 0;
230
            }
231
        } else {
232
            return $this->quotas;
233
        }
234
    }
235
236
    /* ----------------------------------------------------------------- */
237
238
    /** Set the quota for a user (and for a ressource)
239
     * @param string $ressource ressource to set quota of
240
     * @param integer size of the quota (available or used)
241
     */
242
    function setquota($ressource, $size) {
243
        global $err, $db, $cuid;
244
        $err->log("quota", "setquota", $ressource . "/" . $size);
245
        if (floatval($size) == 0) {
246
            $size = "0";
247
        }
248
        if (isset($this->disk[$ressource])) {
249
            // It's a disk resource, update it with shell command
250
            exec("sudo /usr/lib/alternc/quota_edit " . intval($cuid) . " " . intval($size) . " &> /dev/null &");
251
            // Now we check that the value has been written properly : 
252
            $a = array();
253
            exec("sudo /usr/lib/alternc/quota_get " . intval($cuid) . " &> /dev/null &", $a);
254
            if (!isset($a[1]) || $size != $a[1]) {
255
                $err->raise("quota", _("Error writing the quota entry!"));
256
                return false;
257
            }
258
        }
259
        // We check that this ressource exists for this client :
260
        $db->query("SELECT * FROM quotas WHERE uid= ? AND name= ? ", array($cuid, $ressource));
261
        if ($db->num_rows()) {
262
            $db->query("UPDATE quotas SET total= ? WHERE uid= ? AND name= ?;", array($size, $cuid, $ressource));
263
        } else {
264
            $db->query("INSERT INTO quotas (uid,name,total) VALUES (?, ?, ?);", array($cuid, $ressource, $size));
265
        }
266
        return true;
267
    }
268
269
    /* ----------------------------------------------------------------- */
270
271
    /**
272
     * Erase all quota information about the user.
273
     */
274
    function delquotas() {
275
        global $db, $err, $cuid;
276
        $err->log("quota", "delquota");
277
        $db->query("DELETE FROM quotas WHERE uid= ?;", array($cuid));
278
        return true;
279
    }
280
281
    /* ----------------------------------------------------------------- */
282
283
    /** Get the default quotas as an associative array
284
     * @return array the array of the default quotas
285
     */
286
    function getdefaults() {
287
        global $db;
288
        $c = array();
289
290
        $db->query("SELECT type,quota FROM defquotas WHERE type='default'");
291
        if (!$db->next_record()) {
292
            $this->addtype('default');
293
        }
294
        $db->query("SELECT value,quota,type FROM defquotas ORDER BY type,quota");
295
        while ($db->next_record()) {
296
            $type = $db->f("type");
297
            $c[$type][$db->f("quota")] = $db->f("value");
298
        }
299
        return $c;
300
    }
301
302
    /* ----------------------------------------------------------------- */
303
304
    /** Set the default quotas
305
     * @param array associative array of quota (key=>val)
306
     */
307
    function setdefaults($newq) {
308
        global $db;
309
        $qlist = $this->qlist();
310
311
        foreach ($newq as $type => $quotas) {
312
            foreach ($quotas as $qname => $value) {
313
                if (array_key_exists($qname, $qlist)) {
314
                    if (!$db->query("REPLACE INTO defquotas (value,quota,type) VALUES ( ?, ?, ?); ", array($value, $qname, $type))) {
315
                        return false;
316
                    }
317
                }
318
            }
319
        }
320
        return true;
321
    }
322
323
    /* ----------------------------------------------------------------- */
324
325
    /** Add an account type for quotas
326
     * @param string $type account type to be added
327
     * @return boolean true if all went ok
328
     */
329
    function addtype($type) {
330
        global $db, $err;
331
        $qlist = $this->qlist();
332
        if (empty($type)) {
333
            return false;
334
        }
335
        $type = strtolower($type);
336
        if (!preg_match("#^[a-z0-9]*$#", $type)) {
337
            $err->raise("quota", "Type can only contains characters a-z and 0-9");
338
            return false;
339
        }
340
        while (list($key, $val) = each($qlist)) {
341
            if (!$db->query("INSERT IGNORE INTO defquotas (quota,type) VALUES(?, ?);", array($key, $type)) || $db->affected_rows() == 0) {
342
                return false;
343
            }
344
        }
345
        return true;
346
    }
347
348
    /* ----------------------------------------------------------------- */
349
350
    /** List for quotas
351
     * @return array
352
     */
353
    function listtype() {
354
        global $db;
355
        $db->query("SELECT distinct(type) FROM defquotas ORDER by type");
356
        $t = array();
357
        while ($db->next_record()) {
358
            $t[] = $db->f("type");
359
        }
360
        return $t;
361
    }
362
363
    /* ----------------------------------------------------------------- */
364
365
    /** Delete an account type for quotas
366
     * @param string $type account type to be deleted
367
     * @return boolean true if all went ok
368
     */
369
    function deltype($type) {
370
        global $db;
371
372
        if ($db->query("UPDATE membres SET type='default' WHERE type= ? ;", array($type)) &&
373
                $db->query("DELETE FROM defquotas WHERE type= ?;", array($type))) {
374
            return true;
375
        } else {
376
            return false;
377
        }
378
    }
379
380
    /* ----------------------------------------------------------------- */
381
382
    /** Create default quotas entries for a new user.
383
     * The user we are talking about is in the global $cuid.
384
     */
385
    function addquotas() {
386
        global $db, $err, $cuid;
387
        $err->log("quota", "addquota");
388
        $ql = $this->qlist();
389
        reset($ql);
390
391
        $db->query("SELECT type,quota FROM defquotas WHERE type='default'");
392
        if (!$db->next_record()) {
393
            $this->addtype('default');
394
        }
395
        $db->query("SELECT type FROM membres WHERE uid= ?;", array($cuid));
396
        $db->next_record();
397
        $t = $db->f("type");
398
399
        foreach ($ql as $res => $val) {
400
            $db->query("SELECT value FROM defquotas WHERE quota= ? AND type= ? ;", array($res, $t));
401
            $q = $db->next_record() ? $db->f("value") : 0;
402
            $this->setquota($res, $q);
403
        }
404
        return true;
405
    }
406
407
    /* ----------------------------------------------------------------- */
408
409
    /** Return a quota value with its unit (when it is a space quota)
410
     * in MB, GB, TB ...
411
     * @param string $type The quota type
412
     * @param integer $value The quota value
413
     * @return string a quota value with its unit.
414
     */
415
    function display_val($type, $value) {
416
        switch ($type) {
417
            case 'bw_web':
418
                return format_size($value);
419
            case 'web':
420
                return format_size($value * 1024);
421
            default:
422
                return $value;
423
        }
424
    }
425
426
    /* get size_xx function (filled by spoolsize.php) */
427
428
    function _get_sum_sql($sql) {
429
        global $db;
430
        $db->query($sql);
431
        if ($db->num_rows() == 0) {
432
            return -1;
433
        } else {
434
            $db->next_record();
435
            $r = $db->Record;
436
            return $r['sum'];
437
        }
438
    }
439
440
    function _get_count_sql($sql) {
441
        global $db;
442
        $db->query($sql);
443
        if ($db->num_rows() == 0) {
444
            return 0;
445
        } else {
446
            $db->next_record();
447
            $r = $db->Record;
448
            return $r['count'];
449
        }
450
    }
451
452
    function _get_size_and_record_sql($sql) {
453
        global $db;
454
        $db->query($sql);
455
        if ($db->num_rows() == 0) {
456
            return array();
457
        } else {
458
            $ret = array();
459
            while ($db->next_record()) {
460
                $ret[] = $db->Record;
461
            }
462
            return $ret;
463
        }
464
    }
465
466
    /* sum of websites sizes from all users */
467
468
    function get_size_web_sum_all() {
469
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_web;");
470
    }
471
472
    /* sum of websites sizes from one user */
473
474
    function get_size_web_sum_user($u) {
475
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_web WHERE uid='$u';");
476
    }
477
478
    /* sum of mailbox sizes from all domains */
479
480
    function get_size_mail_sum_all() {
481
        return $this->_get_sum_sql("SELECT SUM(bytes) AS sum FROM mailbox;");
482
    }
483
484
    /* sum of mailbox sizes for one domain */
485
486
    function get_size_mail_sum_domain($dom) {
487
        global $mail;
488
        return $mail->get_total_size_for_domain($dom);
489
    }
490
491
    /* count of mailbox sizes from all domains */
492
493
    function get_size_mail_count_all() {
494
        return $this->_get_count_sql("SELECT COUNT(*) AS count FROM mailbox;");
495
    }
496
497
    /* count of mailbox for one domain */
498
499
    function get_size_mail_count_domain($dom) {
500
        return $this->_get_count_sql("SELECT COUNT(*) AS count FROM dovecot_view WHERE user LIKE '%@{$dom}'");
501
    }
502
503
    /* get list of mailbox alias and size for one domain */
504
505
    function get_size_mail_details_domain($dom) {
506
        return $this->_get_size_and_record_sql("SELECT user as alias,quota_dovecot as size FROM dovecot_view WHERE user LIKE '%@{$dom}' ORDER BY alias;");
507
    }
508
509
    /* sum of mailman lists sizes from all domains */
510
511
    function get_size_mailman_sum_all() {
512
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman;");
513
    }
514
515
    /* sum of mailman lists sizes for one domain */
516
517
    function get_size_mailman_sum_domain($dom) {
518
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman WHERE list LIKE '%@{$dom}'");
519
    }
520
521
    /* sum of mailman lists for one user */
522
523
    function get_size_mailman_sum_user($u) {
524
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_mailman WHERE uid = '{$u}'");
525
    }
526
527
    /* count of mailman lists sizes from all domains */
528
529
    function get_size_mailman_count_all() {
530
        return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_mailman;");
531
    }
532
533
    /* count of mailman lists for one user */
534
535
    function get_size_mailman_count_user($u) {
536
        return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_mailman WHERE uid = '{$u}'");
537
    }
538
539
    /* get list of mailman list and size for one user */
540
541
    function get_size_mailman_details_user($u) {
542
        return $this->_get_size_and_record_sql("SELECT s.size,CONCAT(m.list,'@',m.domain) as list FROM size_mailman s LEFT JOIN mailman m ON s.list=m.name WHERE s.uid='{$u}' ORDER BY s.list ASC");
543
    }
544
545
    /* sum of databases sizes from all users */
546
547
    function get_size_db_sum_all() {
548
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_db;");
549
    }
550
551
    /* sum of databases sizes for one user */
552
553
    function get_size_db_sum_user($u) {
554
        return $this->_get_sum_sql("SELECT SUM(size) AS sum FROM size_db WHERE db = '{$u}' OR db LIKE '{$u}\_%'");
555
    }
556
557
    /* count of databases from all users */
558
559
    function get_size_db_count_all() {
560
        return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_db;");
561
    }
562
563
    /* count of databases for one user */
564
565
    function get_size_db_count_user($u) {
566
        return $this->_get_count_sql("SELECT COUNT(*) AS count FROM size_db WHERE db = '{$u}' OR db LIKE '{$u}\_%'");
567
    }
568
569
    /* get list of databases name and size for one user */
570
571
    function get_size_db_details_user($u) {
572
        return $this->_get_size_and_record_sql("SELECT db,size FROM size_db WHERE db='{$u}' OR db LIKE '{$u}\_%';");
573
    }
574
575
    /* Return appropriate value and unit of a size given in Bytes (e.g. 1024 Bytes -> return 1 KB) */
576
577
    function get_size_unit($size) {
578
        $units = array(1073741824 => _("GB"), 1048576 => _("MB"), 1024 => _("KB"), 0 => _("B"));
579
        foreach ($units as $value => $unit) {
580
            if ($size >= $value) {
581
                $size=$size/($value?$value:1);
582
                return array('size' => $size, 'unit' => $unit);
583
            }
584
        }
585
    }
586
587
    // Affiche des barres de progression
588
    // color_type :
589
    //   0 = Pas de changement de couleur
590
    //   1 = Progression du vert vers le rouge en fonction du porcentage
591
    //   2 = Progression du rouge vers le vert en fonction du porcentage
592
    function quota_displaybar($usage, $color_type = 1) {
593
        if ($color_type == 1) {
594
            $csscolor = " background-color:" . PercentToColor($usage);
595
        } elseif ($color_type == 2) {
596
            $csscolor = " background-color:" . PercentToColor(100 - $usage);
597
        } else {
598
            $csscolor = "";
599
        }
600
601
602
        echo '<div class="progress-bar">';
603
        echo '<div class="barre" style="width:' . $usage . '%;' . $csscolor . '" ></div>';
604
        echo '<div class="txt">' . $usage . '%</div>';
605
        echo '</div>';
606
    }
607
608
    /* ==== Hook functions ==== */
609
610
    /* ----------------------------------------------------------------- */
611
612
    /** Hook function call when a user is deleted
613
     * AlternC's standard function called when a user is deleted
614
     * globals $cuid is the appropriate user
615
     */
616
    function hook_admin_del_member() {
617
        $this->delquotas();
618
    }
619
620
    /* ----------------------------------------------------------------- */
621
622
    /** Hook function called when a user is created
623
     * This function initialize the user's quotas.
624
     * globals $cuid is the appropriate user
625
     */
626
    function hook_admin_add_member() {
627
        global $err;
628
        $err->log("quota", "hook_admin_add_member");
629
        $this->addquotas();
630
        $this->getquota('', true); // actualise quota
631
    }
632
633
    /* ----------------------------------------------------------------- */
634
635
    /** Exports all the quota related information for an account.
636
     * @access private
637
     * EXPERIMENTAL function ;) 
638
     */
639
    function alternc_export_conf() {
640
        global $err;
641
        $err->log("quota", "export");
642
        $str = "  <quota>";
643
644
        $q = $this->getquota();
645
        foreach ($q as $k => $v) {
646
            $str.=" <$k>\n";
647
            $str.="   <used>" . ($v["u"]) . "</used>\n";
648
            $str.="   <total>" . ($v["t"]) . "</total>\n";
649
            $str.=" </$k>\n";
650
        }
651
        $str.="</quota>\n";
652
        return $str;
653
    }
654
655
}
656
657
/* Class m_quota */
658
659