From fdba28fad7b503948ce4505e0a8426e2c1ffc654 Mon Sep 17 00:00:00 2001 From: James Cole Date: Wed, 3 Feb 2021 14:57:37 +0100 Subject: [PATCH] Experimental refactor of API code. --- .../Models/Account/DestroyController.php | 77 ++++++++++++++++ .../Account/ListController.php} | 85 ++---------------- .../Models/Account/StoreController.php | 87 ++++++++++++++++++ .../Models/Account/UpdateController.php | 88 +++++++++++++++++++ app/Rules/UniqueAccountNumber.php | 5 +- routes/api.php | 16 ++-- 6 files changed, 273 insertions(+), 85 deletions(-) create mode 100644 app/Api/V1/Controllers/Models/Account/DestroyController.php rename app/Api/V1/Controllers/{AccountController.php => Models/Account/ListController.php} (75%) create mode 100644 app/Api/V1/Controllers/Models/Account/StoreController.php create mode 100644 app/Api/V1/Controllers/Models/Account/UpdateController.php diff --git a/app/Api/V1/Controllers/Models/Account/DestroyController.php b/app/Api/V1/Controllers/Models/Account/DestroyController.php new file mode 100644 index 0000000000..aa8815c204 --- /dev/null +++ b/app/Api/V1/Controllers/Models/Account/DestroyController.php @@ -0,0 +1,77 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers\Models\Account; + +use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Models\Account; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Http\Api\AccountFilter; +use FireflyIII\Support\Http\Api\TransactionFilter; +use Illuminate\Http\JsonResponse; + +/** + * Class DestroyController + */ +class DestroyController extends Controller +{ + use AccountFilter, TransactionFilter; + + public const RESOURCE_KEY = 'accounts'; + + private AccountRepositoryInterface $repository; + + + /** + * AccountController constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser(auth()->user()); + + return $next($request); + } + ); + } + + /** + * Remove the specified resource from storage. + * + * @param Account $account + * + * @codeCoverageIgnore + * @return JsonResponse + */ + public function destroy(Account $account): JsonResponse + { + $this->repository->destroy($account, null); + + return response()->json([], 204); + } +} diff --git a/app/Api/V1/Controllers/AccountController.php b/app/Api/V1/Controllers/Models/Account/ListController.php similarity index 75% rename from app/Api/V1/Controllers/AccountController.php rename to app/Api/V1/Controllers/Models/Account/ListController.php index e22a69f0e3..139b8b8996 100644 --- a/app/Api/V1/Controllers/AccountController.php +++ b/app/Api/V1/Controllers/Models/Account/ListController.php @@ -21,10 +21,9 @@ declare(strict_types=1); -namespace FireflyIII\Api\V1\Controllers; +namespace FireflyIII\Api\V1\Controllers\Models\Account; -use FireflyIII\Api\V1\Requests\AccountStoreRequest; -use FireflyIII\Api\V1\Requests\AccountUpdateRequest; +use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Models\Account; use FireflyIII\Repositories\Account\AccountRepositoryInterface; @@ -44,9 +43,9 @@ use League\Fractal\Resource\Collection as FractalCollection; use League\Fractal\Resource\Item; /** - * Class AccountController. + * Class ListController */ -class AccountController extends Controller +class ListController extends Controller { use AccountFilter, TransactionFilter; @@ -54,7 +53,6 @@ class AccountController extends Controller private AccountRepositoryInterface $repository; - /** * AccountController constructor. * @@ -65,11 +63,8 @@ class AccountController extends Controller parent::__construct(); $this->middleware( function ($request, $next) { - /** @var User $user */ - $user = auth()->user(); - // @var AccountRepositoryInterface repository $this->repository = app(AccountRepositoryInterface::class); - $this->repository->setUser($user); + $this->repository->setUser(auth()->user()); return $next($request); } @@ -85,7 +80,7 @@ class AccountController extends Controller public function attachments(Account $account): JsonResponse { $manager = $this->getManager(); - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $collection = $this->repository->getAttachments($account); $count = $collection->count(); @@ -105,21 +100,6 @@ class AccountController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } - /** - * Remove the specified resource from storage. - * - * @param Account $account - * - * @codeCoverageIgnore - * @return JsonResponse - */ - public function delete(Account $account): JsonResponse - { - $this->repository->destroy($account, null); - - return response()->json([], 204); - } - /** * Display a listing of the resource. * @@ -136,7 +116,7 @@ class AccountController extends Controller // types to get, page size: $types = $this->mapAccountTypes($this->parameters->get('type')); - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; // get list of accounts. Count it and split it. $collection = $this->repository->getAccountsByType($types); @@ -147,7 +127,6 @@ class AccountController extends Controller $paginator = new LengthAwarePaginator($accounts, $count, $pageSize, $this->parameters->get('page')); $paginator->setPath(route('api.v1.accounts.index') . $this->buildParams()); - /** @var AccountTransformer $transformer */ $transformer = app(AccountTransformer::class); $transformer->setParameters($this->parameters); @@ -158,7 +137,6 @@ class AccountController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } - /** * List all piggies. * @@ -173,7 +151,7 @@ class AccountController extends Controller $manager = $this->getManager(); // types to get, page size: - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; // get list of budgets. Count it and split it. $collection = $this->repository->getPiggyBanks($account); @@ -214,28 +192,6 @@ class AccountController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } - /** - * Store a new instance. - * - * @param AccountStoreRequest $request - * - * @return JsonResponse - */ - public function store(AccountStoreRequest $request): JsonResponse - { - $data = $request->getAllAccountData(); - $account = $this->repository->store($data); - $manager = $this->getManager(); - - /** @var AccountTransformer $transformer */ - $transformer = app(AccountTransformer::class); - $transformer->setParameters($this->parameters); - - $resource = new Item($account, $transformer, self::RESOURCE_KEY); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); - } - /** * Show all transaction groups related to the account. * @@ -248,7 +204,7 @@ class AccountController extends Controller */ public function transactions(Request $request, Account $account): JsonResponse { - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; $type = $request->get('type') ?? 'default'; $this->parameters->set('type', $type); @@ -285,27 +241,4 @@ class AccountController extends Controller return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); } - - /** - * Update account. - * - * @param AccountUpdateRequest $request - * @param Account $account - * - * @return JsonResponse - */ - public function update(AccountUpdateRequest $request, Account $account): JsonResponse - { - $data = $request->getUpdateData(); - $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); - $this->repository->update($account, $data); - $manager = $this->getManager(); - - /** @var AccountTransformer $transformer */ - $transformer = app(AccountTransformer::class); - $transformer->setParameters($this->parameters); - $resource = new Item($account, $transformer, self::RESOURCE_KEY); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); - } } diff --git a/app/Api/V1/Controllers/Models/Account/StoreController.php b/app/Api/V1/Controllers/Models/Account/StoreController.php new file mode 100644 index 0000000000..5609fda218 --- /dev/null +++ b/app/Api/V1/Controllers/Models/Account/StoreController.php @@ -0,0 +1,87 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers\Models\Account; + +use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\AccountStoreRequest; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Http\Api\AccountFilter; +use FireflyIII\Support\Http\Api\TransactionFilter; +use FireflyIII\Transformers\AccountTransformer; +use Illuminate\Http\JsonResponse; +use League\Fractal\Resource\Item; + +/** + * Class StoreController + */ +class StoreController extends Controller +{ + use AccountFilter, TransactionFilter; + + public const RESOURCE_KEY = 'accounts'; + + private AccountRepositoryInterface $repository; + + + /** + * AccountController constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser(auth()->user()); + + return $next($request); + } + ); + } + + /** + * Store a new instance. + * + * @param AccountStoreRequest $request + * + * @return JsonResponse + */ + public function store(AccountStoreRequest $request): JsonResponse + { + $data = $request->getAllAccountData(); + $account = $this->repository->store($data); + $manager = $this->getManager(); + + /** @var AccountTransformer $transformer */ + $transformer = app(AccountTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new Item($account, $transformer, self::RESOURCE_KEY); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } + +} diff --git a/app/Api/V1/Controllers/Models/Account/UpdateController.php b/app/Api/V1/Controllers/Models/Account/UpdateController.php new file mode 100644 index 0000000000..f4a73a978e --- /dev/null +++ b/app/Api/V1/Controllers/Models/Account/UpdateController.php @@ -0,0 +1,88 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers\Models\Account; + +use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\AccountUpdateRequest; +use FireflyIII\Models\Account; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Http\Api\AccountFilter; +use FireflyIII\Support\Http\Api\TransactionFilter; +use FireflyIII\Transformers\AccountTransformer; +use Illuminate\Http\JsonResponse; +use League\Fractal\Resource\Item; + +/** + * Class UpdateController + */ +class UpdateController extends Controller +{ + use AccountFilter, TransactionFilter; + + public const RESOURCE_KEY = 'accounts'; + + private AccountRepositoryInterface $repository; + + + /** + * AccountController constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser(auth()->user()); + + return $next($request); + } + ); + } + + /** + * Update account. + * + * @param AccountUpdateRequest $request + * @param Account $account + * + * @return JsonResponse + */ + public function update(AccountUpdateRequest $request, Account $account): JsonResponse + { + $data = $request->getUpdateData(); + $data['type'] = config('firefly.shortNamesByFullName.' . $account->accountType->type); + $this->repository->update($account, $data); + $manager = $this->getManager(); + + /** @var AccountTransformer $transformer */ + $transformer = app(AccountTransformer::class); + $transformer->setParameters($this->parameters); + $resource = new Item($account, $transformer, self::RESOURCE_KEY); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } +} diff --git a/app/Rules/UniqueAccountNumber.php b/app/Rules/UniqueAccountNumber.php index 256c073489..2051b65ff3 100644 --- a/app/Rules/UniqueAccountNumber.php +++ b/app/Rules/UniqueAccountNumber.php @@ -47,6 +47,7 @@ class UniqueAccountNumber implements Rule */ public function __construct(?Account $account, ?string $expectedType) { + Log::debug('Constructed UniqueAccountNumber'); $this->account = $account; $this->expectedType = $expectedType; // a very basic fix to make sure we get the correct account type: @@ -59,6 +60,7 @@ class UniqueAccountNumber implements Rule if ('asset' === $expectedType) { $this->expectedType = AccountType::ASSET; } + Log::debug(sprintf('Expected type is "%s"', $this->expectedType)); } /** @@ -106,7 +108,7 @@ class UniqueAccountNumber implements Rule return false; } } - + Log::debug('Account number is valid.'); return true; } @@ -122,6 +124,7 @@ class UniqueAccountNumber implements Rule ::leftJoin('accounts','accounts.id','=','account_meta.account_id') ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') ->where('accounts.user_id', auth()->user()->id) + ->where('account_types.type', $type) ->where('account_meta.name','=','account_number') ->where('account_meta.data',json_encode($accountNumber)); diff --git a/routes/api.php b/routes/api.php index 6f6f334cdf..79717a1b39 100644 --- a/routes/api.php +++ b/routes/api.php @@ -44,15 +44,15 @@ Route::group( static function () { // Accounts API routes: - Route::get('', ['uses' => 'AccountController@index', 'as' => 'index']); - Route::post('', ['uses' => 'AccountController@store', 'as' => 'store']); - Route::get('{account}', ['uses' => 'AccountController@show', 'as' => 'show']); - Route::put('{account}', ['uses' => 'AccountController@update', 'as' => 'update']); - Route::delete('{account}', ['uses' => 'AccountController@delete', 'as' => 'delete']); + Route::get('', ['uses' => 'Models\Account\ListController@index', 'as' => 'index']); + Route::post('', ['uses' => 'Models\Account\StoreController@store', 'as' => 'store']); + Route::get('{account}', ['uses' => 'Models\Account\ListController@show', 'as' => 'show']); + Route::put('{account}', ['uses' => 'Models\Account\UpdateController@update', 'as' => 'update']); + Route::delete('{account}', ['uses' => 'Models\Account\DestroyController@destroy', 'as' => 'delete']); - Route::get('{account}/piggy_banks', ['uses' => 'AccountController@piggyBanks', 'as' => 'piggy_banks']); - Route::get('{account}/transactions', ['uses' => 'AccountController@transactions', 'as' => 'transactions']); - Route::get('{account}/attachments', ['uses' => 'AccountController@attachments', 'as' => 'attachments']); + Route::get('{account}/piggy_banks', ['uses' => 'Models\Account\ListController@piggyBanks', 'as' => 'piggy_banks']); + Route::get('{account}/transactions', ['uses' => 'Models\Account\ListController@transactions', 'as' => 'transactions']); + Route::get('{account}/attachments', ['uses' => 'Models\Account\ListController@attachments', 'as' => 'attachments']); } );