Skip to content

Commit 857da2a

Browse files
committed
refactor: differentiate between kilo/kibibytes and mega/mebibytes
1 parent fff0c87 commit 857da2a

File tree

7 files changed

+157
-4
lines changed

7 files changed

+157
-4
lines changed

system/Files/File.php

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,39 @@ public function getSize()
7070
return $this->size ?? ($this->size = parent::getSize());
7171
}
7272

73+
/**
74+
* Retrieve the file size by unit, calculated in IEC standards with 1024 as base value.
75+
*
76+
* @return false|int|string
77+
*/
78+
public function getSizeByUnitBinary(FileSizeUnit $unit = FileSizeUnit::B, int $precision = 3)
79+
{
80+
return $this->getSizeByUnitInternal(1024, $unit, $precision);
81+
}
82+
83+
/**
84+
* Retrieve the file size by unit, calculated in metric standards with 1000 as base value.
85+
*
86+
* @return false|int|string
87+
*/
88+
public function getSizeByUnitMetric(FileSizeUnit $unit = FileSizeUnit::B, int $precision = 3)
89+
{
90+
return $this->getSizeByUnitInternal(1000, $unit, $precision);
91+
}
92+
7393
/**
7494
* Retrieve the file size by unit.
7595
*
96+
* @deprecated Use getSizeByUnitBinary or getSizeByUnitMetric instead
97+
*
7698
* @return false|int|string
7799
*/
78100
public function getSizeByUnit(string $unit = 'b')
79101
{
80102
return match (strtolower($unit)) {
81-
'kb' => number_format($this->getSize() / 1024, 3),
82-
'mb' => number_format(($this->getSize() / 1024) / 1024, 3),
83-
default => $this->getSize(),
103+
'kb' => $this->getSizeByUnitBinary(FileSizeUnit::KB),
104+
'mb' => $this->getSizeByUnitBinary(FileSizeUnit::MB),
105+
default => $this->getSizeByUnitBinary(FileSizeUnit::B)
84106
};
85107
}
86108

@@ -189,4 +211,19 @@ public function getDestination(string $destination, string $delimiter = '_', int
189211

190212
return $destination;
191213
}
214+
215+
protected function getSizeByUnitInternal(int $fileSizeBase, FileSizeUnit $unit, int $precision)
216+
{
217+
$exponent = $unit->value;
218+
$divider = pow($fileSizeBase, $exponent);
219+
220+
$size = $this->getSize() / $divider;
221+
222+
if($unit !== FileSizeUnit::B)
223+
{
224+
$size = number_format($size, $precision);
225+
}
226+
227+
return $size;
228+
}
192229
}

system/Files/FileSizeUnit.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* This file is part of CodeIgniter 4 framework.
7+
*
8+
* (c) CodeIgniter Foundation <[email protected]>
9+
*
10+
* For the full copyright and license information, please view
11+
* the LICENSE file that was distributed with this source code.
12+
*/
13+
14+
namespace CodeIgniter\Files;
15+
16+
enum FileSizeUnit : int
17+
{
18+
case B = 0;
19+
case KB = 1;
20+
case MB = 2;
21+
case GB = 3;
22+
case TB = 4;
23+
}

tests/system/Files/FileTest.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,42 @@ public function testGetSizeReturnsBytes(): void
113113
$this->assertSame($size, $file->getSizeByUnit('b'));
114114
}
115115

116+
/**
117+
* @dataProvider provideGetSizeData
118+
*/
119+
public function testGetSizeBinary(FileSizeUnit $unit): void
120+
{
121+
$divider = pow(1024, $unit->value);
122+
$file = new File(SYSTEMPATH . 'Common.php');
123+
$size = number_format(filesize(SYSTEMPATH . 'Common.php') / $divider, 3);
124+
$this->assertSame($size, $file->getSizeByUnitBinary($unit));
125+
}
126+
127+
public function testGetSizeBinaryBytes(): void
128+
{
129+
$file = new File(SYSTEMPATH . 'Common.php');
130+
$size = filesize(SYSTEMPATH . 'Common.php');
131+
$this->assertSame($size, $file->getSizeByUnitBinary(FileSizeUnit::B));
132+
}
133+
134+
/**
135+
* @dataProvider provideGetSizeData
136+
*/
137+
public function testGetSizeMetric(FileSizeUnit $unit): void
138+
{
139+
$divider = pow(1000, $unit->value);
140+
$file = new File(SYSTEMPATH . 'Common.php');
141+
$size = number_format(filesize(SYSTEMPATH . 'Common.php') / $divider, 3);
142+
$this->assertSame($size, $file->getSizeByUnitMetric($unit));
143+
}
144+
145+
public function testGetSizeMetricBytes(): void
146+
{
147+
$file = new File(SYSTEMPATH . 'Common.php');
148+
$size = filesize(SYSTEMPATH . 'Common.php');
149+
$this->assertSame($size, $file->getSizeByUnitMetric(FileSizeUnit::B));
150+
}
151+
116152
public function testThrowsExceptionIfNotAFile(): void
117153
{
118154
$this->expectException(FileNotFoundException::class);
@@ -135,4 +171,22 @@ public function testGetDestination(): void
135171
unlink(SYSTEMPATH . 'Common_Copy.php');
136172
unlink(SYSTEMPATH . 'Common_Copy_5.php');
137173
}
174+
175+
public static function provideGetSizeData()
176+
{
177+
return [
178+
'returns KB binary' => [
179+
FileSizeUnit::KB
180+
],
181+
'returns MB binary' => [
182+
FileSizeUnit::KB
183+
],
184+
'returns GB binary' => [
185+
FileSizeUnit::KB
186+
],
187+
'returns TB binary' => [
188+
FileSizeUnit::KB
189+
],
190+
];
191+
}
138192
}

user_guide_src/source/changelogs/v4.6.0.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,9 @@ Deprecations
277277
- The properties ``$arguments`` and ``$argumentsClass`` of ``Filters`` have
278278
been deprecated. No longer used.
279279
- The ``Filters::getArguments()`` method has been deprecated. No longer used.
280+
- **File:**
281+
- The function ``getSizeByUnit`` of ``File`` has been deprecated.
282+
Use either ``getSizeByUnitBinary`` or ``getSizeByUnitMetric`` instead.
280283

281284
**********
282285
Bugs Fixed

user_guide_src/source/libraries/files.rst

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,40 @@ A ``RuntimeException`` will be thrown if the file does not exist or an error occ
5656
getSizeByUnit()
5757
===============
5858

59+
.. deprecated:: 4.6.0
60+
5961
Returns the size of the file default in bytes. You can pass in either ``'kb'`` or ``'mb'`` as the first parameter to get
60-
the results in kilobytes or megabytes, respectively:
62+
the results in kibibytes or mebibytes, respectively:
6163

6264
.. literalinclude:: files/005.php
6365
:lines: 2-
6466

6567
A ``RuntimeException`` will be thrown if the file does not exist or an error occurs.
6668

69+
getSizeByUnitBinary()
70+
===============
71+
72+
Returns the size of the file default in bytes. You can pass in different FileSizeUnit values as the first parameter to get
73+
the results in kibibytes, mebibytes etc. respectively. You can pass in a precision value as the second parameter to define
74+
the amount of decimal places.
75+
76+
.. literalinclude:: files/017.php
77+
:lines: 2-
78+
79+
A ``RuntimeException`` will be thrown if the file does not exist or an error occurs.
80+
81+
getSizeByUnitMetric()
82+
===============
83+
84+
Returns the size of the file default in bytes. You can pass in different FileSizeUnit values as the first parameter to get
85+
the results in kilobytes, megabytes etc. respectively. You can pass in a precision value as the second parameter to define
86+
the amount of decimal places.
87+
88+
.. literalinclude:: files/018.php
89+
:lines: 2-
90+
91+
A ``RuntimeException`` will be thrown if the file does not exist or an error occurs.
92+
6793
getMimeType()
6894
=============
6995

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
$bytes = $file->getSizeByUnitBinary(); // 256901
4+
$kibibytes = $file->getSizeByUnitBinary(FileSizeUnit::KB); // 250.880
5+
$mebibytes = $file->getSizeByUnitBinary(FileSizeUnit::MB); // 0.245
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?php
2+
3+
$bytes = $file->getSizeByUnitMetric(); // 256901
4+
$kilobytes = $file->getSizeByUnitMetric(FileSizeUnit::KB); // 256.901
5+
$megabytes = $file->getSizeByUnitMetric(FileSizeUnit::MB); // 0.256

0 commit comments

Comments
 (0)