Skip to content

Commit

Permalink
refactor: differentiate between kilo/kibibytes and mega/mebibytes
Browse files Browse the repository at this point in the history
  • Loading branch information
ThomasMeschke committed Nov 18, 2024
1 parent fff0c87 commit 857da2a
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 4 deletions.
43 changes: 40 additions & 3 deletions system/Files/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,39 @@ public function getSize()
return $this->size ?? ($this->size = parent::getSize());
}

/**
* Retrieve the file size by unit, calculated in IEC standards with 1024 as base value.
*
* @return false|int|string
*/
public function getSizeByUnitBinary(FileSizeUnit $unit = FileSizeUnit::B, int $precision = 3)
{
return $this->getSizeByUnitInternal(1024, $unit, $precision);
}

/**
* Retrieve the file size by unit, calculated in metric standards with 1000 as base value.
*
* @return false|int|string
*/
public function getSizeByUnitMetric(FileSizeUnit $unit = FileSizeUnit::B, int $precision = 3)
{
return $this->getSizeByUnitInternal(1000, $unit, $precision);
}

/**
* Retrieve the file size by unit.
*
* @deprecated Use getSizeByUnitBinary or getSizeByUnitMetric instead
*
* @return false|int|string
*/
public function getSizeByUnit(string $unit = 'b')
{
return match (strtolower($unit)) {
'kb' => number_format($this->getSize() / 1024, 3),
'mb' => number_format(($this->getSize() / 1024) / 1024, 3),
default => $this->getSize(),
'kb' => $this->getSizeByUnitBinary(FileSizeUnit::KB),
'mb' => $this->getSizeByUnitBinary(FileSizeUnit::MB),
default => $this->getSizeByUnitBinary(FileSizeUnit::B)
};
}

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

return $destination;
}

protected function getSizeByUnitInternal(int $fileSizeBase, FileSizeUnit $unit, int $precision)

Check failure on line 215 in system/Files/File.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Method CodeIgniter\Files\File::getSizeByUnitInternal() has no return type specified.
{
$exponent = $unit->value;
$divider = pow($fileSizeBase, $exponent);

$size = $this->getSize() / $divider;

if($unit !== FileSizeUnit::B)
{
$size = number_format($size, $precision);
}

return $size;
}
}
23 changes: 23 additions & 0 deletions system/Files/FileSizeUnit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

/**
* This file is part of CodeIgniter 4 framework.
*
* (c) CodeIgniter Foundation <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace CodeIgniter\Files;

enum FileSizeUnit : int
{
case B = 0;
case KB = 1;
case MB = 2;
case GB = 3;
case TB = 4;
}
54 changes: 54 additions & 0 deletions tests/system/Files/FileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,42 @@ public function testGetSizeReturnsBytes(): void
$this->assertSame($size, $file->getSizeByUnit('b'));
}

/**
* @dataProvider provideGetSizeData
*/
public function testGetSizeBinary(FileSizeUnit $unit): void
{
$divider = pow(1024, $unit->value);
$file = new File(SYSTEMPATH . 'Common.php');
$size = number_format(filesize(SYSTEMPATH . 'Common.php') / $divider, 3);
$this->assertSame($size, $file->getSizeByUnitBinary($unit));
}

public function testGetSizeBinaryBytes(): void
{
$file = new File(SYSTEMPATH . 'Common.php');
$size = filesize(SYSTEMPATH . 'Common.php');
$this->assertSame($size, $file->getSizeByUnitBinary(FileSizeUnit::B));
}

/**
* @dataProvider provideGetSizeData
*/
public function testGetSizeMetric(FileSizeUnit $unit): void
{
$divider = pow(1000, $unit->value);
$file = new File(SYSTEMPATH . 'Common.php');
$size = number_format(filesize(SYSTEMPATH . 'Common.php') / $divider, 3);
$this->assertSame($size, $file->getSizeByUnitMetric($unit));
}

public function testGetSizeMetricBytes(): void
{
$file = new File(SYSTEMPATH . 'Common.php');
$size = filesize(SYSTEMPATH . 'Common.php');
$this->assertSame($size, $file->getSizeByUnitMetric(FileSizeUnit::B));
}

public function testThrowsExceptionIfNotAFile(): void
{
$this->expectException(FileNotFoundException::class);
Expand All @@ -135,4 +171,22 @@ public function testGetDestination(): void
unlink(SYSTEMPATH . 'Common_Copy.php');
unlink(SYSTEMPATH . 'Common_Copy_5.php');
}

public static function provideGetSizeData()

Check failure on line 175 in tests/system/Files/FileTest.php

View workflow job for this annotation

GitHub Actions / PHP Static Analysis

Method CodeIgniter\Files\FileTest::provideGetSizeData() has no return type specified.
{
return [
'returns KB binary' => [
FileSizeUnit::KB
],
'returns MB binary' => [
FileSizeUnit::KB
],
'returns GB binary' => [
FileSizeUnit::KB
],
'returns TB binary' => [
FileSizeUnit::KB
],
];
}
}
3 changes: 3 additions & 0 deletions user_guide_src/source/changelogs/v4.6.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ Deprecations
- The properties ``$arguments`` and ``$argumentsClass`` of ``Filters`` have
been deprecated. No longer used.
- The ``Filters::getArguments()`` method has been deprecated. No longer used.
- **File:**
- The function ``getSizeByUnit`` of ``File`` has been deprecated.
Use either ``getSizeByUnitBinary`` or ``getSizeByUnitMetric`` instead.

**********
Bugs Fixed
Expand Down
28 changes: 27 additions & 1 deletion user_guide_src/source/libraries/files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,40 @@ A ``RuntimeException`` will be thrown if the file does not exist or an error occ
getSizeByUnit()
===============

.. deprecated:: 4.6.0

Returns the size of the file default in bytes. You can pass in either ``'kb'`` or ``'mb'`` as the first parameter to get
the results in kilobytes or megabytes, respectively:
the results in kibibytes or mebibytes, respectively:

.. literalinclude:: files/005.php
:lines: 2-

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

getSizeByUnitBinary()
===============

Returns the size of the file default in bytes. You can pass in different FileSizeUnit values as the first parameter to get
the results in kibibytes, mebibytes etc. respectively. You can pass in a precision value as the second parameter to define
the amount of decimal places.

.. literalinclude:: files/017.php
:lines: 2-

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

getSizeByUnitMetric()
===============

Returns the size of the file default in bytes. You can pass in different FileSizeUnit values as the first parameter to get
the results in kilobytes, megabytes etc. respectively. You can pass in a precision value as the second parameter to define
the amount of decimal places.

.. literalinclude:: files/018.php
:lines: 2-

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

getMimeType()
=============

Expand Down
5 changes: 5 additions & 0 deletions user_guide_src/source/libraries/files/017.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

$bytes = $file->getSizeByUnitBinary(); // 256901
$kibibytes = $file->getSizeByUnitBinary(FileSizeUnit::KB); // 250.880
$mebibytes = $file->getSizeByUnitBinary(FileSizeUnit::MB); // 0.245
5 changes: 5 additions & 0 deletions user_guide_src/source/libraries/files/018.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

$bytes = $file->getSizeByUnitMetric(); // 256901
$kilobytes = $file->getSizeByUnitMetric(FileSizeUnit::KB); // 256.901
$megabytes = $file->getSizeByUnitMetric(FileSizeUnit::MB); // 0.256

0 comments on commit 857da2a

Please sign in to comment.