Skip to content

Commit

Permalink
Merge pull request #3 from kbond/named-temp-files
Browse files Browse the repository at this point in the history
feat: allow creating "named" temp files
  • Loading branch information
kbond authored Feb 24, 2023
2 parents 8b077e6 + 7bbf3de commit 3eba8c1
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 4 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fixcs:
name: Run php-cs-fixer
needs: sync-with-template
if: (github.event_name == 'push' || github.event_name == 'schedule') && !startsWith(github.ref, 'refs/tags')
if: (github.event_name == 'push' || github.event_name == 'schedule') && !startsWith(github.ref, 'refs/tags') && github.repository_owner == 'zenstruck'
runs-on: ubuntu-latest
steps:
- uses: zenstruck/.github@php-cs-fixer
Expand All @@ -33,7 +33,7 @@ jobs:

sync-with-template:
name: Sync meta files
if: (github.event_name == 'push' || github.event_name == 'schedule') && !startsWith(github.ref, 'refs/tags')
if: (github.event_name == 'push' || github.event_name == 'schedule') && !startsWith(github.ref, 'refs/tags') && github.repository_owner == 'zenstruck'
runs-on: ubuntu-latest
steps:
- uses: zenstruck/.github@sync-with-template
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ $file = TempFile::new();
// create empty file with random filename, with extension (in /tmp)
$file = TempFile::withExtension('txt');

// create file with specific filename (in /tmp)
$file = TempFile::withName('my-file.txt'); // creates empty file
$file = TempFile::withName('my-file.txt', 'some content'); // creates file with string content
$file = TempFile::withName('my-file.txt', \fopen('some/file.txt', 'r')); // creates file with resource as content
$file = TempFile::withName('my-file.txt', new \SplFileInfo('some/file.txt')); // creates file from existing file (existing file is copied)

// create for existing file
$file = TempFile::new('some/file.txt'); // note: will be deleted at the end of the script

Expand All @@ -40,6 +46,7 @@ $file = TempFile::for(new \SplFileInfo('some/file.txt'));
$image = TempFile::image(); // temporary 10x10 image with 'jpg' as the extension
$image = TempFile::image(100, 50); // customize the dimensions
$image = TempFile::image(type: 'gif'); // customize the image type
$image = TempFile::image(name: 'my-image.png'); // customize the file name
```

### Using `TempFile`'s
Expand Down
33 changes: 31 additions & 2 deletions src/TempFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,31 @@ public static function new(?string $filename = null): self
return new self($filename);
}

/**
* @param string $name Name for the file (must contain no directory separators)
* @param string|resource|\SplFileInfo|null $content
*/
public static function withName(string $name, mixed $content = null): self
{
if (\str_contains($name, '/')) {
throw new \InvalidArgumentException('File name cannot contain directory separator.');
}

$filename = \sprintf('%s/%s', \sys_get_temp_dir(), $name);

if ($content instanceof \SplFileInfo) {
@\copy($content, $filename) ?: throw new \RuntimeException('Unable to copy file.');

return new self($filename);
}

if (false === @\file_put_contents($filename, $content ?? '')) {
throw new \RuntimeException('Unable to write to file.');
}

return new self($filename);
}

public static function withExtension(string $extension): self
{
$original = self::tempFile();
Expand Down Expand Up @@ -78,10 +103,14 @@ public static function for(mixed $what, ?string $extension = null): self
*
* @source /~https://github.com/laravel/framework/blob/183d38f18c0ea9fe13b6d10a6d8360be881d096c/src/Illuminate/Http/Testing/FileFactory.php#L68
*/
public static function image(int $width = 10, int $height = 10, string $type = 'jpg'): self
public static function image(int $width = 10, int $height = 10, string $type = 'jpg', ?string $name = null): self
{
if ($name) {
$type = \pathinfo($name, \PATHINFO_EXTENSION) ?: throw new \InvalidArgumentException('File name must include an extension.');
}

$type = \mb_strtolower($type);
$file = self::withExtension($type);
$file = $name ? self::withName($name) : self::withExtension($type);

if (false === $image = @\imagecreatetruecolor($width, $height)) {
throw new \RuntimeException('Error creating temporary image.');
Expand Down
93 changes: 93 additions & 0 deletions tests/TempFileTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,41 @@ public function can_create_image_with_dimensions(): void
$this->assertSame('png', $file->getExtension());
}

/**
* @test
*/
public function can_create_image_with_name(): void
{
$imageSize = \getimagesize($file = TempFile::image(5, 6, name: 'some-image.png'));

$this->assertFileExists($file);
$this->assertSame(\sys_get_temp_dir().'/some-image.png', (string) $file);
$this->assertSame(5, $imageSize[0]);
$this->assertSame(6, $imageSize[1]);
$this->assertSame('image/png', $imageSize['mime']);
$this->assertSame('png', $file->getExtension());
}

/**
* @test
*/
public function image_name_requires_extension(): void
{
$this->expectException(\InvalidArgumentException::class);

TempFile::image(name: 'some-image');
}

/**
* @test
*/
public function image_name_cannot_contain_directory_separator(): void
{
$this->expectException(\InvalidArgumentException::class);

TempFile::image(name: 'some/dir/image.png');
}

/**
* @test
*/
Expand All @@ -207,4 +242,62 @@ public function cannot_create_image_for_invalid_type(): void

TempFile::image(type: 'invalid');
}

/**
* @test
*/
public function can_create_named_temp_file(): void
{
$file = TempFile::withName('some-file.txt');

$this->assertFileExists($file);
$this->assertSame(\sys_get_temp_dir().'/some-file.txt', (string) $file);
$this->assertSame('', \file_get_contents($file));

TempFile::purge();

$this->assertFileDoesNotExist($file);
}

/**
* @test
*/
public function can_create_named_temp_file_with_string_content(): void
{
$file = TempFile::withName('some-file.txt', 'content');

$this->assertFileExists($file);
$this->assertSame(\sys_get_temp_dir().'/some-file.txt', (string) $file);
$this->assertSame('content', \file_get_contents($file));

TempFile::purge();

$this->assertFileDoesNotExist($file);
}

/**
* @test
*/
public function can_create_named_temp_file_with_spl_file(): void
{
$file = TempFile::withName('some-file.txt', new \SplFileInfo(__FILE__));

$this->assertFileExists($file);
$this->assertSame(\sys_get_temp_dir().'/some-file.txt', (string) $file);
$this->assertFileEquals($file, __FILE__);

TempFile::purge();

$this->assertFileDoesNotExist($file);
}

/**
* @test
*/
public function name_cannot_contain_directory_separator(): void
{
$this->expectException(\InvalidArgumentException::class);

TempFile::withName('some/dir/some-file.txt');
}
}

0 comments on commit 3eba8c1

Please sign in to comment.