Storage utilities
Storage is a utility with various methods for managing files in the application's storage.
Getting the path from storage
You can use the constant $file = INPHINIT_SYSTEM . '/storage/myfile.txt';, but for convenience, the Storage::path($path) method allows you to retrieve the path while avoiding issues with ..—for example:
use Inphinit\Experimental\Utility\Storage;
// Output: /foo/bar/baz/my-app/system/storage/myfile.txt
echo Storage::path('myfile.txt');
// Output: /foo/bar/baz/my-app/system/storage/foo/bar/baz/file.data
echo Storage::path('foo/bar/baz/file.data');
If a value containing .. is passed, an exception will be thrown, preventing issues, as in the example:
echo Storage::path('../file.data');
Output:
Fatal error: Uncaught Error: Class "Storage" not found in /home/websites/myapp/system/dev.php:68
Stack trace:
#0 /home/websites/myapp/system/vendor\inphinit\framework\src\Inphinit\App.php(218): {closure:/home/websites/myapp/system/dev.php:66}()
#1 /home/websites/myapp/index.php(10): Inphinit\App->exec()
#2 {main}
thrown in /home/websites/myapp/system/dev.php on line 68
Using this method is ideal for dynamic values, making it possible to handle the error:
$input = get_user_path();
try {
$absolute_path = Storage::path($input);
} catch (\Exception $ex) {
echo 'Failed: ', $ex->getMessage();
exit;
}
Creating a directory in storage
Although using the native mkdir() function is quite simple in practice, using a shortcut makes working with the application's storage easier. Usage examples:
use Inphinit\Experimental\Utility\Storage;
// It will recursively create a folder with the same permissions as the system/storage folder
Storage::mkdir('foo/bar/baz');
For application data that is not stored, changing permissions is not ideal, but there are exceptions; therefore, the following can be used:
use Inphinit\Experimental\Utility\Storage;
// It will create a folder recursively, with all folders having the same permission
Storage::mkdir('foo/bar/baz', 0755);
Changing Modification and Access times
With the native touch($filename, $mtime, $atime) function, if null is passed as the value for $mtime or $atime,
the file's modification and access times are updated to the current system time (equal or close to time()). This can be inconvenient
when the goal is to change only one of the values, leading to usage patterns such as:
// change only access time
touch($file, filemtime($file), $new_access);
// change only modified time
touch($file, $new_modified, fileatime($file));
To facilitate this usage for storage and also allow the use of DateTime for better readability during development, while also enabling better control over the time zone, you can use:
use Inphinit\Experimental\Utility\Storage;
// Changes only the touch time
Storage::modified($file, new DateTime('2008-11-25'));
Changing only the file access time:
use Inphinit\Experimental\Utility\Storage;
// Changes only the access time
Storage::access($file, new DateTime('2014-10-12'));
It is also possible to use a Unix timestamp:
// Changes the access time to approximately one hour ago
Storage::access($file, time() - 3600);
// Changes the modification time to approximately two hours ago
Storage::modified($file, time() - 7200);
Using DateTimeImmutable
For the sake of backward compatibility, only DateTime and int values are accepted,
but it is still possible to use DateTimeImmutable by using the getTimestamp() method, as shown in the example:
$tz = new DateTimeZone('Pacific/Nauru');
$dt = new DateTimeImmutable('now', $tz);
Storage::access($file, $dt->getTimestamp());
Cleaning up old files
To clean up old files based on a cutoff date, you can use the following method:
use Inphinit\Experimental\Utility\Storage;
// Removes files within system/storage/foo/bar/baz/ that are older than one hour.
Storage::clear('foo/bar/baz', 3600);
Note that, by default, the method will only delete (or attempt to delete) 100 files at a time to avoid accidentally consuming too much time, but this can be adjusted:
use Inphinit\Experimental\Utility\Storage;
// Removes up to 500 files within system/storage/foo/bar/baz/ that are older than one hour.
Storage::clear('foo/bar/baz', 3600, 500);
It is also possible to filter file types by name, as in the example:
use Inphinit\Experimental\Utility\Storage;
Storage::clear('foo/bar/baz', 3600, 100, function ($name) {
// It will delete only those whose names begin with ~myprefix_
return strpos($name, '~myprefix_') === 0;
});
If the function in the fourth parameter returns true, the file will be selected for removal; any value other than true
will cause the file to be ignored.