From ea4602abc72271a023ead315358503037c2051ea Mon Sep 17 00:00:00 2001 From: hackerESQ Date: Sun, 26 Jan 2025 22:56:05 -0600 Subject: [PATCH] wip --- .../ApiControllers/PortfolioController.php | 9 +- .../ApiControllers/TransactionController.php | 34 +++++ app/Http/Controllers/PortfolioController.php | 5 +- ...tfolioRequest.php => PortfolioRequest.php} | 13 +- ...olioRequest.php => TransactionRequest.php} | 13 +- composer.lock | 119 ++++++++++++++---- storage/app/.gitignore | 1 - 7 files changed, 157 insertions(+), 37 deletions(-) rename app/Http/Requests/{StorePortfolioRequest.php => PortfolioRequest.php} (63%) rename app/Http/Requests/{UpdatePortfolioRequest.php => TransactionRequest.php} (63%) diff --git a/app/Http/ApiControllers/PortfolioController.php b/app/Http/ApiControllers/PortfolioController.php index 54e83ec..dd487b0 100644 --- a/app/Http/ApiControllers/PortfolioController.php +++ b/app/Http/ApiControllers/PortfolioController.php @@ -8,8 +8,7 @@ use App\Models\Portfolio; use Illuminate\Support\Facades\Gate; use HackerEsq\FilterModels\FilterModels; use App\Http\Resources\PortfolioResource; -use App\Http\Requests\StorePortfolioRequest; -use App\Http\Requests\UpdatePortfolioRequest; +use App\Http\Requests\PortfolioRequest; use App\Http\ApiControllers\Controller as ApiController; class PortfolioController extends ApiController @@ -25,7 +24,7 @@ class PortfolioController extends ApiController return PortfolioResource::collection($filters->paginated()); } - public function store(StorePortfolioRequest $request) + public function store(PortfolioRequest $request) { $portfolio = Portfolio::create($request->validated()); @@ -39,7 +38,7 @@ class PortfolioController extends ApiController return PortfolioResource::make($portfolio); } - public function update(UpdatePortfolioRequest $request, Portfolio $portfolio) + public function update(PortfolioRequest $request, Portfolio $portfolio) { Gate::authorize('fullAccess', $portfolio); @@ -52,6 +51,8 @@ class PortfolioController extends ApiController { Gate::authorize('fullAccess', $portfolio); + $portfolio->delete(); + return response()->noContent(); } } \ No newline at end of file diff --git a/app/Http/ApiControllers/TransactionController.php b/app/Http/ApiControllers/TransactionController.php index 68b8597..3441df0 100644 --- a/app/Http/ApiControllers/TransactionController.php +++ b/app/Http/ApiControllers/TransactionController.php @@ -4,7 +4,9 @@ namespace App\Http\ApiControllers; use App\Models\Transaction; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; use HackerEsq\FilterModels\FilterModels; +use App\Http\Requests\TransactionRequest; use App\Http\Resources\TransactionResource; use App\Http\ApiControllers\Controller as ApiController; @@ -19,4 +21,36 @@ class TransactionController extends ApiController return TransactionResource::collection($filters->paginated()); } + + public function store(TransactionRequest $request) + { + $transaction = Transaction::create($request->validated()); + + return TransactionResource::make($transaction); + } + + public function show(Transaction $transaction) + { + Gate::authorize('readOnly', $transaction); + + return TransactionResource::make($transaction); + } + + public function update(TransactionRequest $request, Transaction $transaction) + { + Gate::authorize('fullAccess', $transaction); + + $transaction->update($request->validated()); + + return TransactionResource::make($transaction); + } + + public function destroy(Transaction $transaction) + { + Gate::authorize('fullAccess', $transaction); + + $transaction->delete(); + + return response()->noContent(); + } } \ No newline at end of file diff --git a/app/Http/Controllers/PortfolioController.php b/app/Http/Controllers/PortfolioController.php index 3f04d12..efa9980 100644 --- a/app/Http/Controllers/PortfolioController.php +++ b/app/Http/Controllers/PortfolioController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers; use App\Models\Holding; use App\Models\Portfolio; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Gate; class PortfolioController extends Controller { @@ -22,9 +23,7 @@ class PortfolioController extends Controller */ public function show(Request $request, Portfolio $portfolio) { - if ($request->user()->cannot('readOnly', $portfolio)) { - abort(403); - } + Gate::authorize('readOnly', $portfolio); $portfolio->load(['transactions', 'holdings']); diff --git a/app/Http/Requests/StorePortfolioRequest.php b/app/Http/Requests/PortfolioRequest.php similarity index 63% rename from app/Http/Requests/StorePortfolioRequest.php rename to app/Http/Requests/PortfolioRequest.php index 86b0eef..772c6b2 100644 --- a/app/Http/Requests/StorePortfolioRequest.php +++ b/app/Http/Requests/PortfolioRequest.php @@ -4,7 +4,7 @@ namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; -class StorePortfolioRequest extends FormRequest +class PortfolioRequest extends FormRequest { /** @@ -14,10 +14,17 @@ class StorePortfolioRequest extends FormRequest */ public function rules(): array { - return [ - 'title' => ['required', 'string', 'max:255'], + + $rules = [ + 'title' => ['required', 'string', 'min:5', 'max:255'], 'notes' => ['sometimes', 'nullable', 'string'], 'wishlist' => ['sometimes', 'nullable', 'boolean'], ]; + + if (!is_null($this->portfolio)) { + $rules['title'][0] = 'sometimes'; + } + + return $rules; } } diff --git a/app/Http/Requests/UpdatePortfolioRequest.php b/app/Http/Requests/TransactionRequest.php similarity index 63% rename from app/Http/Requests/UpdatePortfolioRequest.php rename to app/Http/Requests/TransactionRequest.php index 6840a5a..2d7d43c 100644 --- a/app/Http/Requests/UpdatePortfolioRequest.php +++ b/app/Http/Requests/TransactionRequest.php @@ -4,7 +4,7 @@ namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; -class UpdatePortfolioRequest extends FormRequest +class TransactionRequest extends FormRequest { /** @@ -14,10 +14,17 @@ class UpdatePortfolioRequest extends FormRequest */ public function rules(): array { - return [ - 'title' => ['sometimes', 'string', 'max:255'], + + $rules = [ + 'title' => ['required', 'string', 'min:5', 'max:255'], 'notes' => ['sometimes', 'nullable', 'string'], 'wishlist' => ['sometimes', 'nullable', 'boolean'], ]; + + if (!is_null($this->portfolio)) { + $rules['title'][0] = 'sometimes'; + } + + return $rules; } } diff --git a/composer.lock b/composer.lock index c7d511f..053e659 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e8ee89ca51e5e67c7c812a39455132da", + "content-hash": "7b8a88dbb7545ee8284282a6dda2ab3f", "packages": [ { "name": "aws/aws-crt-php", @@ -491,6 +491,85 @@ ], "time": "2024-02-09T16:56:22+00:00" }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, { "name": "composer/semver", "version": "3.4.3", @@ -1063,7 +1142,7 @@ "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/investbrainapp/finnhub-php.git", + "url": "https://github.com/investbrainapp/finnhub-php", "reference": "1f1b35a0c0a6a68f9a791e3ac5cdb6f44ff69d80" }, "dist": { @@ -1115,9 +1194,6 @@ "rest", "sdk" ], - "support": { - "source": "https://github.com/investbrainapp/finnhub-php/tree/master" - }, "time": "2024-09-13T01:29:18+00:00" }, { @@ -1732,12 +1808,12 @@ "version": "dev-main", "source": { "type": "git", - "url": "https://github.com/hackerESQ/filter-models.git", + "url": "https://github.com/hackeresq/filter-models", "reference": "565537120ea01bd73f49051ecde90d05e4127c6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/hackerESQ/filter-models/zipball/565537120ea01bd73f49051ecde90d05e4127c6b", + "url": "https://api.github.com/repos/hackeresq/filter-models/zipball/565537120ea01bd73f49051ecde90d05e4127c6b", "reference": "565537120ea01bd73f49051ecde90d05e4127c6b", "shasum": "" }, @@ -1760,10 +1836,6 @@ } }, "description": "Simple package to filter your Laravel models with query parameters", - "support": { - "source": "https://github.com/hackerESQ/filter-models/tree/main", - "issues": "https://github.com/hackerESQ/filter-models/issues" - }, "time": "2025-01-25T04:44:58+00:00" }, { @@ -4745,19 +4817,20 @@ }, { "name": "phpoffice/phpspreadsheet", - "version": "1.29.8", + "version": "1.29.9", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "089ffdfc04b5fcf25a3503d81a4e589f247e20e3" + "reference": "ffb47b639649fc9c8a6fa67977a27b756592ed85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/089ffdfc04b5fcf25a3503d81a4e589f247e20e3", - "reference": "089ffdfc04b5fcf25a3503d81a4e589f247e20e3", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/ffb47b639649fc9c8a6fa67977a27b756592ed85", + "reference": "ffb47b639649fc9c8a6fa67977a27b756592ed85", "shasum": "" }, "require": { + "composer/pcre": "^3.3", "ext-ctype": "*", "ext-dom": "*", "ext-fileinfo": "*", @@ -4844,9 +4917,9 @@ ], "support": { "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues", - "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.8" + "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.9" }, - "time": "2025-01-12T03:16:27+00:00" + "time": "2025-01-26T04:55:00+00:00" }, { "name": "phpoption/phpoption", @@ -8866,16 +8939,16 @@ }, { "name": "filp/whoops", - "version": "2.16.0", + "version": "2.17.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2" + "reference": "075bc0c26631110584175de6523ab3f1652eb28e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/befcdc0e5dce67252aa6322d82424be928214fa2", - "reference": "befcdc0e5dce67252aa6322d82424be928214fa2", + "url": "https://api.github.com/repos/filp/whoops/zipball/075bc0c26631110584175de6523ab3f1652eb28e", + "reference": "075bc0c26631110584175de6523ab3f1652eb28e", "shasum": "" }, "require": { @@ -8925,7 +8998,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.16.0" + "source": "https://github.com/filp/whoops/tree/2.17.0" }, "funding": [ { @@ -8933,7 +9006,7 @@ "type": "github" } ], - "time": "2024-09-25T12:00:00+00:00" + "time": "2025-01-25T12:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", diff --git a/storage/app/.gitignore b/storage/app/.gitignore index 5d91b1f..8f4803c 100644 --- a/storage/app/.gitignore +++ b/storage/app/.gitignore @@ -1,4 +1,3 @@ * !public/ !.gitignore -!market_data_seed.csv