From 07a1875b4a17eeff58cded8ecf9558351d39c4a4 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Thu, 2 Nov 2023 15:37:21 +0500 Subject: [PATCH 1/3] complete mvp local temporary url feature --- .github/ISSUE_TEMPLATE/config.yml | 6 +- CHANGELOG.md | 2 +- LICENSE.md | 2 +- README.md | 56 +--- composer.json | 31 +- config/local-temporary-url.php | 7 + config/skeleton.php | 6 - configure.php | 266 ------------------ database/factories/ModelFactory.php | 19 -- .../migrations/create_skeleton_table.php.stub | 19 -- phpstan.neon.dist | 1 - phpunit.xml.dist | 6 +- resources/views/.gitkeep | 0 routes/routes.php | 13 + src/Commands/SkeletonCommand.php | 19 -- src/Facades/Skeleton.php | 16 -- src/LocalTemporaryUrlServiceProvider.php | 34 +++ src/Skeleton.php | 7 - src/SkeletonServiceProvider.php | 25 -- tests/ExampleTest.php | 5 - tests/Pest.php | 2 +- tests/TemporaryUrlTest.php | 24 ++ tests/TestCase.php | 22 +- 23 files changed, 126 insertions(+), 462 deletions(-) create mode 100644 config/local-temporary-url.php delete mode 100644 config/skeleton.php delete mode 100644 configure.php delete mode 100644 database/factories/ModelFactory.php delete mode 100644 database/migrations/create_skeleton_table.php.stub delete mode 100644 resources/views/.gitkeep create mode 100644 routes/routes.php delete mode 100644 src/Commands/SkeletonCommand.php delete mode 100644 src/Facades/Skeleton.php create mode 100644 src/LocalTemporaryUrlServiceProvider.php delete mode 100755 src/Skeleton.php delete mode 100644 src/SkeletonServiceProvider.php delete mode 100644 tests/ExampleTest.php create mode 100644 tests/TemporaryUrlTest.php diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 96701be..0e8ee1a 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,11 +1,11 @@ blank_issues_enabled: false contact_links: - name: Ask a question - url: https://github.com/:vendor_name/:package_name/discussions/new?category=q-a + url: https://github.com/abrardev/laravel-local-temporary-url/discussions/new?category=q-a about: Ask the community for help - name: Request a feature - url: https://github.com/:vendor_name/:package_name/discussions/new?category=ideas + url: https://github.com/abrardev/laravel-local-temporary-url/discussions/new?category=ideas about: Share ideas for new features - name: Report a security issue - url: https://github.com/:vendor_name/:package_name/security/policy + url: https://github.com/abrardev/laravel-local-temporary-url/security/policy about: Learn how to notify us for sensitive bugs diff --git a/CHANGELOG.md b/CHANGELOG.md index 87b3242..b910ac8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,3 @@ # Changelog -All notable changes to `:package_name` will be documented in this file. +All notable changes to `laravel-local-temporary-url` will be documented in this file. diff --git a/LICENSE.md b/LICENSE.md index 58c9ad4..a2a321a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) :vendor_name +Copyright (c) abrardev Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 375da96..e77c6d0 100644 --- a/README.md +++ b/README.md @@ -1,68 +1,40 @@ -# :package_description - -[![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) -[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain) -[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain) -[![Total Downloads](https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) - ---- -This repo can be used to scaffold a Laravel package. Follow these steps to get started: - -1. Press the "Use this template" button at the top of this repo to create a new repo with the contents of this skeleton. -2. Run "php ./configure.php" to run a script that will replace all placeholders throughout all the files. -3. Have fun creating your package. -4. If you need help creating a package, consider picking up our Laravel Package Training video course. ---- - -This is where your description should go. Limit it to a paragraph or two. Consider adding a small example. - -## Support us - -[](https://spatie.be/github-ad-click/:package_name) - -We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us). - -We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). +![Logo](https://banners.beyondco.de/Laravel%20Local%20Disk%20Temporary%20URL%20.png?theme=light&packageManager=composer+require&packageName=abrardev%2Flaravel-local-temporary-url&pattern=floorTile&style=style_1&description=Quickly+add+support+for+temporary+url+for+local+filesystem+drivers&md=1&showWatermark=0&fontSize=100px&images=link) ## Installation You can install the package via composer: ```bash -composer require :vendor_slug/:package_slug -``` - -You can publish and run the migrations with: - -```bash -php artisan vendor:publish --tag=":package_slug-migrations" -php artisan migrate +composer require abrardev/laravel-local-temporary-url ``` You can publish the config file with: ```bash -php artisan vendor:publish --tag=":package_slug-config" +php artisan vendor:publish --tag="local-temporary-url-config" ``` This is the contents of the published config file: ```php return [ + 'disk' => ['local'], + + 'middleware' => ['web', 'signed'] ]; ``` -Optionally, you can publish the views using +## Usage -```bash -php artisan vendor:publish --tag=":package_slug-views" -``` +### Configuration +This package needs zero configuration, just install and it's good to go. However, if your local disk is different or you want to add another disk, you can configure it. You can add multiple local disks in the config using the `disk` key.
-## Usage +The package applies `web` and `signed` middleware on routes by default, however, you can configure middleware(s) using the `middleware` key. +### Generate Temporary URL +You can use the same syntax used for S3 disk. ```php -$variable = new VendorName\Skeleton(); -echo $variable->echoPhrase('Hello, VendorName!'); +Storage::disk('local')->temporaryUrl('file.txt', now()->addMinutes(5)); ``` ## Testing @@ -85,7 +57,7 @@ Please review [our security policy](../../security/policy) on how to report secu ## Credits -- [:author_name](https://github.com/:author_username) +- [Abrar Ahmad](https://github.com/abrardev99) - [All Contributors](../../contributors) ## License diff --git a/composer.json b/composer.json index c8ba78b..0317f90 100644 --- a/composer.json +++ b/composer.json @@ -1,22 +1,22 @@ { - "name": ":vendor_slug/:package_slug", - "description": ":package_description", + "name": "abrardev/laravel-local-temporary-url", + "description": "Quickly add support for temporary url for local filesystem drivers", "keywords": [ - ":vendor_name", + "abrardev", "laravel", - ":package_slug" + "laravel-local-temporary-url" ], - "homepage": "https://github.com/:vendor_slug/:package_slug", + "homepage": "https://github.com/abrardev99/laravel-local-temporary-url", "license": "MIT", "authors": [ { - "name": ":author_name", - "email": "author@domain.com", + "name": "Abrar Ahmad", + "email": "abrar.dev99@gmail.com", "role": "Developer" } ], "require": { - "php": "^8.1", + "php": "^8.0", "spatie/laravel-package-tools": "^1.14.0", "illuminate/contracts": "^10.0" }, @@ -30,24 +30,23 @@ "pestphp/pest-plugin-laravel": "^2.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-phpunit": "^1.0", - "spatie/laravel-ray": "^1.26" + "phpstan/phpstan-phpunit": "^1.0" }, "autoload": { "psr-4": { - "VendorName\\Skeleton\\": "src/", - "VendorName\\Skeleton\\Database\\Factories\\": "database/factories/" + "Abrardev\\LocalTemporaryUrl\\": "src/", + "Abrardev\\LocalTemporaryUrl\\Database\\Factories\\": "database/factories/" } }, "autoload-dev": { "psr-4": { - "VendorName\\Skeleton\\Tests\\": "tests/", + "Abrardev\\LocalTemporaryUrl\\Tests\\": "tests/", "Workbench\\App\\": "workbench/app/" } }, "scripts": { "post-autoload-dump": "@composer run prepare", - "clear": "@php vendor/bin/testbench package:purge-skeleton --ansi", + "clear": "@php vendor/bin/testbench package:purge-laravel-local-temporary-url --ansi", "prepare": "@php vendor/bin/testbench package:discover --ansi", "build": [ "@composer run prepare", @@ -73,10 +72,10 @@ "extra": { "laravel": { "providers": [ - "VendorName\\Skeleton\\SkeletonServiceProvider" + "Abrardev\\LocalTemporaryUrl\\LocalTemporaryUrlServiceProvider" ], "aliases": { - "Skeleton": "VendorName\\Skeleton\\Facades\\Skeleton" + "LocalTemporaryUrl": "Abrardev\\LocalTemporaryUrl\\Facades\\LocalTemporaryUrl" } } }, diff --git a/config/local-temporary-url.php b/config/local-temporary-url.php new file mode 100644 index 0000000..d22945c --- /dev/null +++ b/config/local-temporary-url.php @@ -0,0 +1,7 @@ + ['local'], + + 'middleware' => ['web', 'signed'], +]; diff --git a/config/skeleton.php b/config/skeleton.php deleted file mode 100644 index 7e74186..0000000 --- a/config/skeleton.php +++ /dev/null @@ -1,6 +0,0 @@ - $version) { - if (in_array($name, $names, true)) { - unset($data['require-dev'][$name]); - } - } - - file_put_contents(__DIR__.'/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); -} - -function remove_composer_script($scriptName) -{ - $data = json_decode(file_get_contents(__DIR__.'/composer.json'), true); - - foreach ($data['scripts'] as $name => $script) { - if ($scriptName === $name) { - unset($data['scripts'][$name]); - break; - } - } - - file_put_contents(__DIR__.'/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); -} - -function remove_readme_paragraphs(string $file): void -{ - $contents = file_get_contents($file); - - file_put_contents( - $file, - preg_replace('/.*/s', '', $contents) ?: $contents - ); -} - -function safeUnlink(string $filename) -{ - if (file_exists($filename) && is_file($filename)) { - unlink($filename); - } -} - -function determineSeparator(string $path): string -{ - return str_replace('/', DIRECTORY_SEPARATOR, $path); -} - -function replaceForWindows(): array -{ - return preg_split('/\\r\\n|\\r|\\n/', run('dir /S /B * | findstr /v /i .git\ | findstr /v /i vendor | findstr /v /i '.basename(__FILE__).' | findstr /r /i /M /F:/ ":author :vendor :package VendorName skeleton migration_table_name vendor_name vendor_slug author@domain.com"')); -} - -function replaceForAllOtherOSes(): array -{ - return explode(PHP_EOL, run('grep -E -r -l -i ":author|:vendor|:package|VendorName|skeleton|migration_table_name|vendor_name|vendor_slug|author@domain.com" --exclude-dir=vendor ./* ./.github/* | grep -v '.basename(__FILE__))); -} - -$gitName = run('git config user.name'); -$authorName = ask('Author name', $gitName); - -$gitEmail = run('git config user.email'); -$authorEmail = ask('Author email', $gitEmail); - -$usernameGuess = explode(':', run('git config remote.origin.url'))[1]; -$usernameGuess = dirname($usernameGuess); -$usernameGuess = basename($usernameGuess); -$authorUsername = ask('Author username', $usernameGuess); - -$vendorName = ask('Vendor name', $authorUsername); -$vendorSlug = slugify($vendorName); -$vendorNamespace = str_replace('-', '', ucwords($vendorName)); -$vendorNamespace = ask('Vendor namespace', $vendorNamespace); - -$currentDirectory = getcwd(); -$folderName = basename($currentDirectory); - -$packageName = ask('Package name', $folderName); -$packageSlug = slugify($packageName); -$packageSlugWithoutPrefix = remove_prefix('laravel-', $packageSlug); - -$className = title_case($packageName); -$className = ask('Class name', $className); -$variableName = lcfirst($className); -$description = ask('Package description', "This is my package {$packageSlug}"); - -$usePhpStan = confirm('Enable PhpStan?', true); -$useLaravelPint = confirm('Enable Laravel Pint?', true); -$useDependabot = confirm('Enable Dependabot?', true); -$useLaravelRay = confirm('Use Ray for debugging?', true); -$useUpdateChangelogWorkflow = confirm('Use automatic changelog updater workflow?', true); - -writeln('------'); -writeln("Author : {$authorName} ({$authorUsername}, {$authorEmail})"); -writeln("Vendor : {$vendorName} ({$vendorSlug})"); -writeln("Package : {$packageSlug} <{$description}>"); -writeln("Namespace : {$vendorNamespace}\\{$className}"); -writeln("Class name : {$className}"); -writeln('---'); -writeln('Packages & Utilities'); -writeln('Use Laravel/Pint : '.($useLaravelPint ? 'yes' : 'no')); -writeln('Use Larastan/PhpStan : '.($usePhpStan ? 'yes' : 'no')); -writeln('Use Dependabot : '.($useDependabot ? 'yes' : 'no')); -writeln('Use Ray App : '.($useLaravelRay ? 'yes' : 'no')); -writeln('Use Auto-Changelog : '.($useUpdateChangelogWorkflow ? 'yes' : 'no')); -writeln('------'); - -writeln('This script will replace the above values in all relevant files in the project directory.'); - -if (! confirm('Modify files?', true)) { - exit(1); -} - -$files = (str_starts_with(strtoupper(PHP_OS), 'WIN') ? replaceForWindows() : replaceForAllOtherOSes()); - -foreach ($files as $file) { - replace_in_file($file, [ - ':author_name' => $authorName, - ':author_username' => $authorUsername, - 'author@domain.com' => $authorEmail, - ':vendor_name' => $vendorName, - ':vendor_slug' => $vendorSlug, - 'VendorName' => $vendorNamespace, - ':package_name' => $packageName, - ':package_slug' => $packageSlug, - ':package_slug_without_prefix' => $packageSlugWithoutPrefix, - 'Skeleton' => $className, - 'skeleton' => $packageSlug, - 'migration_table_name' => title_snake($packageSlug), - 'variable' => $variableName, - ':package_description' => $description, - ]); - - match (true) { - str_contains($file, determineSeparator('src/Skeleton.php')) => rename($file, determineSeparator('./src/'.$className.'.php')), - str_contains($file, determineSeparator('src/SkeletonServiceProvider.php')) => rename($file, determineSeparator('./src/'.$className.'ServiceProvider.php')), - str_contains($file, determineSeparator('src/Facades/Skeleton.php')) => rename($file, determineSeparator('./src/Facades/'.$className.'.php')), - str_contains($file, determineSeparator('src/Commands/SkeletonCommand.php')) => rename($file, determineSeparator('./src/Commands/'.$className.'Command.php')), - str_contains($file, determineSeparator('database/migrations/create_skeleton_table.php.stub')) => rename($file, determineSeparator('./database/migrations/create_'.title_snake($packageSlugWithoutPrefix).'_table.php.stub')), - str_contains($file, determineSeparator('config/skeleton.php')) => rename($file, determineSeparator('./config/'.$packageSlugWithoutPrefix.'.php')), - str_contains($file, 'README.md') => remove_readme_paragraphs($file), - default => [], - }; -} - -if (! $useLaravelPint) { - safeUnlink(__DIR__.'/.github/workflows/fix-php-code-style-issues.yml'); - safeUnlink(__DIR__.'/pint.json'); -} - -if (! $usePhpStan) { - safeUnlink(__DIR__.'/phpstan.neon.dist'); - safeUnlink(__DIR__.'/phpstan-baseline.neon'); - safeUnlink(__DIR__.'/.github/workflows/phpstan.yml'); - - remove_composer_deps([ - 'phpstan/extension-installer', - 'phpstan/phpstan-deprecation-rules', - 'phpstan/phpstan-phpunit', - 'nunomaduro/larastan', - ]); - - remove_composer_script('phpstan'); -} - -if (! $useDependabot) { - safeUnlink(__DIR__.'/.github/dependabot.yml'); - safeUnlink(__DIR__.'/.github/workflows/dependabot-auto-merge.yml'); -} - -if (! $useLaravelRay) { - remove_composer_deps(['spatie/laravel-ray']); -} - -if (! $useUpdateChangelogWorkflow) { - safeUnlink(__DIR__.'/.github/workflows/update-changelog.yml'); -} - -confirm('Execute `composer install` and run tests?') && run('composer install && composer test'); - -confirm('Let this script delete itself?', true) && unlink(__FILE__); diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php deleted file mode 100644 index c51604f..0000000 --- a/database/factories/ModelFactory.php +++ /dev/null @@ -1,19 +0,0 @@ -id(); - - // add fields - - $table->timestamps(); - }); - } -}; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index a91953b..e005ac7 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -6,7 +6,6 @@ parameters: paths: - src - config - - database tmpDir: build/phpstan checkOctaneCompatibility: true checkModelProperties: true diff --git a/phpunit.xml.dist b/phpunit.xml.dist index e953c0e..9f6b823 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -16,10 +16,14 @@ backupStaticProperties="false" > - + tests + + + + diff --git a/resources/views/.gitkeep b/resources/views/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/routes/routes.php b/routes/routes.php new file mode 100644 index 0000000..b4cccbf --- /dev/null +++ b/routes/routes.php @@ -0,0 +1,13 @@ +download($path); + }) + ->where('path', '.*') + ->middleware(config('local-temporary-url.middleware')) + ->name("$disk.temp"); +} diff --git a/src/Commands/SkeletonCommand.php b/src/Commands/SkeletonCommand.php deleted file mode 100644 index 3e5f628..0000000 --- a/src/Commands/SkeletonCommand.php +++ /dev/null @@ -1,19 +0,0 @@ -comment('All done'); - - return self::SUCCESS; - } -} diff --git a/src/Facades/Skeleton.php b/src/Facades/Skeleton.php deleted file mode 100644 index 1fa9076..0000000 --- a/src/Facades/Skeleton.php +++ /dev/null @@ -1,16 +0,0 @@ -name('laravel-local-temporary-url') + ->hasConfigFile() + ->hasRoute('routes'); + } + + public function boot() + { + parent::boot(); + + foreach (config('local-temporary-url.disk') as $disk) { + Storage::disk($disk)->buildTemporaryUrlsUsing(function ($path, $expiration, $options) use ($disk) { + return URL::temporarySignedRoute( + "$disk.temp", + $expiration, + array_merge($options, ['path' => $path]) + ); + }); + } + } +} diff --git a/src/Skeleton.php b/src/Skeleton.php deleted file mode 100755 index 66fab60..0000000 --- a/src/Skeleton.php +++ /dev/null @@ -1,7 +0,0 @@ -name('skeleton') - ->hasConfigFile() - ->hasViews() - ->hasMigration('create_skeleton_table') - ->hasCommand(SkeletonCommand::class); - } -} diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php deleted file mode 100644 index 5d36321..0000000 --- a/tests/ExampleTest.php +++ /dev/null @@ -1,5 +0,0 @@ -toBeTrue(); -}); diff --git a/tests/Pest.php b/tests/Pest.php index 7fe1500..e5433a2 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -1,5 +1,5 @@ in(__DIR__); diff --git a/tests/TemporaryUrlTest.php b/tests/TemporaryUrlTest.php new file mode 100644 index 0000000..e68ea4c --- /dev/null +++ b/tests/TemporaryUrlTest.php @@ -0,0 +1,24 @@ +put($path, 'Hello world'); + + $url = Storage::disk('local2')->temporaryUrl($path, now()->addSecond()); + + expect($url)->toBeUrl(); + + get($url) + ->assertOk() + ->assertDownload('file.txt'); + + // wait for 2 second to mimic we passed given seconds. + sleep(2); + + get($url)->assertForbidden(); +}); diff --git a/tests/TestCase.php b/tests/TestCase.php index d04fb0c..86ac2d9 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,36 +1,30 @@ 'VendorName\\Skeleton\\Database\\Factories\\'.class_basename($modelName).'Factory' - ); } protected function getPackageProviders($app) { + return [ - SkeletonServiceProvider::class, + LocalTemporaryUrlServiceProvider::class, ]; } - public function getEnvironmentSetUp($app) + protected function getEnvironmentSetUp($app) { - config()->set('database.default', 'testing'); + Storage::fake('local2'); - /* - $migration = include __DIR__.'/../database/migrations/create_skeleton_table.php.stub'; - $migration->up(); - */ + config()->set('local-temporary-url.disk', ['local', 'local2']); } } From 3c3b0cbfb102a5e123b39f77cdde61631ac2a8a6 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Thu, 2 Nov 2023 15:40:14 +0500 Subject: [PATCH 2/3] use php 8.1 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0317f90..1c11895 100644 --- a/composer.json +++ b/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "spatie/laravel-package-tools": "^1.14.0", "illuminate/contracts": "^10.0" }, From b256f2666f0b0cced37244f19e14a2b66b277531 Mon Sep 17 00:00:00 2001 From: Abrar Ahmad Date: Thu, 2 Nov 2023 15:43:40 +0500 Subject: [PATCH 3/3] remove toBeUrl expectation --- tests/TemporaryUrlTest.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/TemporaryUrlTest.php b/tests/TemporaryUrlTest.php index e68ea4c..9425057 100644 --- a/tests/TemporaryUrlTest.php +++ b/tests/TemporaryUrlTest.php @@ -11,8 +11,6 @@ $url = Storage::disk('local2')->temporaryUrl($path, now()->addSecond()); - expect($url)->toBeUrl(); - get($url) ->assertOk() ->assertDownload('file.txt');