Skip to content

Instantly share code, notes, and snippets.

@jrobinsonc
Last active January 5, 2021 14:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrobinsonc/b666ca42ba2d415ab7f3e72e1326e5e1 to your computer and use it in GitHub Desktop.
Save jrobinsonc/b666ca42ba2d415ab7f3e72e1326e5e1 to your computer and use it in GitHub Desktop.
<?php
namespace App\Helpers;
use App\Helpers\StorageHelper;
use RuntimeException;
use InvalidArgumentException;
class FileHelper
{
protected $storage;
protected $filePath;
/**
* @param string $filePath
* @param string|\App\Helpers\StorageHelper $storage
* @throws \InvalidArgumentException
*/
public function __construct(string $filePath, $storage = null)
{
$this->filePath = $filePath;
$this->storage = $storage;
if (empty($this->filePath)) {
throw new InvalidArgumentException('File path is empty.');
}
if (is_string($this->storage)) {
$this->storage = new StorageHelper($this->storage);
}
if ($this->storage instanceof StorageHelper === false) {
throw new InvalidArgumentException('Invalid storage provided.');
}
}
/**
* @return \Illuminate\Filesystem\FilesystemAdapter
*/
public function diskInstance()
{
return $this->storage->diskInstance();
}
/**
* @todo This should be moved to the StorageHelper.
* @return self
*/
public function getBackupFile()
{
return new static(
$this->path() . '.bak',
$this->storage
);
}
/**
* Delete backup
*
* @todo This should be moved to the StorageHelper.
* @return bool
* @throws \RuntimeException
*/
public function deleteBackup()
{
$backupFile = $this->getBackupFile();
if (! $backupFile->exists()) {
return false;
}
if (! $backupFile->delete()) {
throw new RuntimeException('Backup could not be deleted: ' . $backupFile->path());
}
return true;
}
/**
* Restore backup
*
* @todo This should be moved to the StorageHelper.
* @return bool
* @throws \RuntimeException
*/
public function restoreBackup()
{
$backupFile = $this->getBackupFile();
if (! $backupFile->exists()) {
return false;
}
$backupRestored = $backupFile->moveTo($this->path());
if ($backupRestored === false) {
throw new RuntimeException('Backup could not be restored for ' . $this->path());
}
return true;
}
/**
* Create backup
*
* @todo This should be moved to the StorageHelper.
* @return static
* @throws \RuntimeException
*/
public function createBackup()
{
$backupFile = $this->getBackupFile();
if ($backupFile->exists() && ! $backupFile->delete()) {
throw new RuntimeException('Previous backup could not be deleted: ' . $backupFile->path());
}
$backupCreated = $this->copyTo($backupFile->path());
if ($backupCreated === false) {
throw new RuntimeException('Backup could not be created for ' . $this->path());
}
return $backupFile;
}
/**
* @param bool $withTimestamp
* @return string
*/
public function getUrl(bool $withTimestamp = false)
{
$diskInstance = $this->diskInstance();
$url = $diskInstance->url($this->filePath);
if ($withTimestamp) {
$url = sprintf('%s?v=%s', $url, $diskInstance->lastModified($this->filePath));
}
return $url;
}
/**
* @return bool
*/
public function delete()
{
return $this->diskInstance()->delete($this->filePath);
}
/**
* @return string
*/
public function get()
{
return $this->diskInstance()->get($this->filePath);
}
/**
* @return bool
*/
public function exists()
{
return $this->diskInstance()->exists($this->filePath);
}
/**
* Returns the full path of the file
*
* @return string
*/
public function path()
{
return $this->diskInstance()->path($this->filePath);
}
/**
* Moves the file to a new location
*
* It also updates the current file path of the instance.
*
* @param string $to Destination of the file.
* @param bool $overwrite Overwrite the file if it already exists.
* @return bool
*/
public function moveTo($to, $overwrite = false)
{
if ($overwrite && $this->diskInstance()->exists($to)) {
$this->diskInstance()->delete($to);
}
$moved = $this->diskInstance()->move($this->filePath, $to);
if (! $moved) {
return false;
}
$this->filePath = $to;
return true;
}
/**
* @param string $dirPath Directory's path where the file should get moved.
* @param bool $safeName Rename the file with safe characters.
* @param bool $overwrite Overwrite the file if it already exists.
* @return bool
*/
public function moveToDir($dirPath, $safeName = false, $overwrite = false)
{
$dirPath = rtrim($dirPath, DIRECTORY_SEPARATOR);
if ($safeName) {
$this->rename($this->getSafeName());
}
$baseName = pathinfo($this->path(), PATHINFO_BASENAME);
return $this->moveTo(
sprintf('%2$s%1$s%3$s', DIRECTORY_SEPARATOR, $dirPath, $baseName),
$overwrite
);
}
/**
* @param string $to
* @return self|bool Returns the instance of the final file or FALSE if the file was not copied.
*/
public function copyTo($to)
{
$copied = $this->diskInstance()->copy($this->filePath, $to);
if (! $copied) {
return false;
}
return new static(
$to,
$this->storage
);
}
/**
* Renames the file
*
* It also updates the instance with the new name.
*
* @param string $newName New name for the file. The extension MUST NOT be in the parameter.
* @return bool
*/
public function rename($newName)
{
$pathInfo = pathinfo($this->path());
return $this->moveTo(
sprintf('%2$s%1$s%3$s.%4$s', DIRECTORY_SEPARATOR, $pathInfo['dirname'], $newName, $pathInfo['extension'])
);
}
/**
* @param string|resource $contents
* @param mixed $options
* @return bool
*/
public function put($contents, $options = [])
{
return $this->diskInstance()->put($this->filePath, $contents, $options);
}
/**
* Returns the basename (including extension) with non-safe characters removed.
*
* @return string
*/
public function getSafeName()
{
$basename = pathinfo($this->path(), PATHINFO_BASENAME);
return preg_replace('/[^A-z0-9\._-]+/', '-', $basename);
}
/**
* @param resource $resource
* @param array $options
* @return bool
*/
public function writeStream($resource, array $options = [])
{
return $this->diskInstance()->writeStream($this->filePath, $resource, $options);
}
/**
* @return resource|null
*/
public function readStream()
{
return $this->diskInstance()->readStream($this->filePath);
}
}
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\Storage as StorageFacade;
use App\Helpers\FileHelper;
use Illuminate\Support\Traits\ForwardsCalls;
class StorageHelper
{
use ForwardsCalls;
protected $storage;
protected $diskInstance;
/**
* @param string $storage Optional
*/
public function __construct(string $storage = null)
{
$this->storage = $storage ?? config('filesystems.default');
}
public function __call($method, $parameters)
{
return $this->forwardCallTo($this->diskInstance(), $method, $parameters);
}
/**
* @return \Illuminate\Filesystem\FilesystemAdapter
*/
public function diskInstance()
{
if (is_null($this->diskInstance)) {
$this->diskInstance = StorageFacade::disk($this->storage);
}
return $this->diskInstance;
}
public function getFile($filePath)
{
return new FileHelper($filePath, $this);
}
}
<?php
namespace App\Helpers;
use BadMethodCallException;
use Illuminate\Support\Traits\ForwardsCalls;
/**
* StorageLayer
*
* @deprecated 1.3 Use FileHelper and StorageHelper instead.
*/
class StorageLayer
{
use ForwardsCalls;
protected $file;
/**
* StorageLayer constructor
*
* @param string $filePath
* @param string $storage Check config/filesystems.php.
*/
public function __construct(string $filePath, string $storage = null)
{
$this->file = new FileHelper($filePath, $storage);
}
public function __call($method, $parameters)
{
if (method_exists($this->file, $method)) {
return $this->forwardCallTo($this->file, $method, $parameters);
}
throw new BadMethodCallException(sprintf(
'Call to undefined method %s::%s()', static::class, $method
));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment