mirror of
				https://github.com/firefly-iii/firefly-iii.git
				synced 2025-10-31 10:47:00 +00:00 
			
		
		
		
	Clean up some code, clean routes. [skip ci]
This commit is contained in:
		
							
								
								
									
										112
									
								
								app/Api/V2/Controllers/JsonApi/AccountController.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								app/Api/V2/Controllers/JsonApi/AccountController.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | ||||
| <?php | ||||
| /* | ||||
|  * AccountController.php | ||||
|  * Copyright (c) 2024 james@firefly-iii.org. | ||||
|  * | ||||
|  * This file is part of Firefly III (https://github.com/firefly-iii). | ||||
|  * | ||||
|  * This program is free software: you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU Affero General Public License as | ||||
|  * published by the Free Software Foundation, either version 3 of the | ||||
|  * License, or (at your option) any later version. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, | ||||
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|  * GNU Affero General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU Affero General Public License | ||||
|  * along with this program.  If not, see https://www.gnu.org/licenses/. | ||||
|  */ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Api\V2\Controllers\JsonApi; | ||||
| 
 | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\JsonApi\V2\Accounts\Capabilities\AccountQuery; | ||||
| use Illuminate\Contracts\Support\Responsable; | ||||
| use Illuminate\Http\Response; | ||||
| use LaravelJsonApi\Contracts\Routing\Route; | ||||
| use LaravelJsonApi\Contracts\Store\Store as StoreContract; | ||||
| use LaravelJsonApi\Core\Responses\DataResponse; | ||||
| use LaravelJsonApi\Laravel\Http\Controllers\Actions; | ||||
| use LaravelJsonApi\Laravel\Http\Requests\ResourceQuery; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountController | ||||
|  * | ||||
|  * This class handles api/v2 requests for accounts. | ||||
|  * Most stuff is default stuff. | ||||
|  * | ||||
|  */ | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     use Actions\AttachRelationship; | ||||
|     use Actions\Destroy; | ||||
|     use Actions\DetachRelationship; | ||||
|     //use Actions\FetchMany;
 | ||||
|     use Actions\FetchOne; | ||||
|     use Actions\FetchRelated; | ||||
|     use Actions\FetchRelationship; | ||||
|     use Actions\Store; | ||||
|     use Actions\Update; | ||||
|     use Actions\UpdateRelationship; | ||||
| 
 | ||||
|     /** | ||||
|      * Fetch zero to many JSON API resources. | ||||
|      * | ||||
|      * @param Route $route | ||||
|      * @param StoreContract $store | ||||
|      * @return Responsable|Response | ||||
|      */ | ||||
|     public function index(Route $route, AccountQuery $store) | ||||
|     { | ||||
|         /** | ||||
|          * TODO Op het moment dat je een custom repositroy wil gebruiken kan je de index overrulen zoals ik hier | ||||
|          * doe. Maar je moet toch ook wel de relatie, de store kunnen overrulen? Waarom gebruikt-ie daar zijn eigen? | ||||
|          * | ||||
|          * TODO dat zit hier: https://laraveljsonapi.io/docs/3.0/resources/ | ||||
|          * | ||||
|          */ | ||||
|         $request = ResourceQuery::queryMany( | ||||
|             $resourceType = $route->resourceType() | ||||
|         ); | ||||
| 
 | ||||
|         $response = null; | ||||
| 
 | ||||
|         if (method_exists($this, 'searching')) { | ||||
|             $response = $this->searching($request); | ||||
|         } | ||||
| 
 | ||||
|         if ($response) { | ||||
|             return $response; | ||||
|         } | ||||
| 
 | ||||
|         $data = $store | ||||
|             ->queryAll($resourceType) | ||||
|             ->withRequest($request) | ||||
|             ->firstOrPaginate($request->page()); | ||||
| 
 | ||||
|         if (method_exists($this, 'searched')) { | ||||
|             $response = $this->searched($data, $request); | ||||
|         } | ||||
| 
 | ||||
|         return $response ?: DataResponse::make($data)->withQueryParameters($request); | ||||
|     } | ||||
| 
 | ||||
| //    public function readAccountBalances(AnonymousQuery $query, AccountBalanceSchema $schema, Account $account): Responsable
 | ||||
| //    {
 | ||||
| //        $schema = JsonApi::server()->schemas()->schemaFor('account-balances');
 | ||||
| //
 | ||||
| //        $models = $schema
 | ||||
| //            ->repository()
 | ||||
| //            ->queryAll()
 | ||||
| //            ->withRequest($query)
 | ||||
| //            ->withAccount($account)
 | ||||
| //            ->get()
 | ||||
| //        ;
 | ||||
| //
 | ||||
| //        return DataResponse::make($models);
 | ||||
| //    }
 | ||||
| } | ||||
| @@ -1,43 +0,0 @@ | ||||
| <?php | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| namespace FireflyIII\Http\Controllers\Api\V2\Controllers; | ||||
| 
 | ||||
| use FireflyIII\Http\Controllers\Controller; | ||||
| use FireflyIII\JsonApi\V2\AccountBalances\AccountBalanceSchema; | ||||
| use FireflyIII\Models\Account; | ||||
| use Illuminate\Contracts\Support\Responsable; | ||||
| use LaravelJsonApi\Core\Facades\JsonApi; | ||||
| use LaravelJsonApi\Core\Responses\DataResponse; | ||||
| use LaravelJsonApi\Laravel\Http\Controllers\Actions; | ||||
| use LaravelJsonApi\Laravel\Http\Requests\AnonymousQuery; | ||||
| 
 | ||||
| class AccountController extends Controller | ||||
| { | ||||
|     use Actions\AttachRelationship; | ||||
|     use Actions\Destroy; | ||||
|     use Actions\DetachRelationship; | ||||
|     use Actions\FetchMany; | ||||
|     use Actions\FetchOne; | ||||
|     use Actions\FetchRelated; | ||||
|     use Actions\FetchRelationship; | ||||
|     use Actions\Store; | ||||
|     use Actions\Update; | ||||
|     use Actions\UpdateRelationship; | ||||
| 
 | ||||
| //    public function readAccountBalances(AnonymousQuery $query, AccountBalanceSchema $schema, Account $account): Responsable
 | ||||
| //    {
 | ||||
| //        $schema = JsonApi::server()->schemas()->schemaFor('account-balances');
 | ||||
| //
 | ||||
| //        $models = $schema
 | ||||
| //            ->repository()
 | ||||
| //            ->queryAll()
 | ||||
| //            ->withRequest($query)
 | ||||
| //            ->withAccount($account)
 | ||||
| //            ->get()
 | ||||
| //        ;
 | ||||
| //
 | ||||
| //        return DataResponse::make($models);
 | ||||
| //    }
 | ||||
| } | ||||
| @@ -28,6 +28,16 @@ use FireflyIII\Support\JsonApi\Concerns\UsergroupAware; | ||||
| use LaravelJsonApi\Contracts\Store\QueriesAll; | ||||
| use LaravelJsonApi\NonEloquent\AbstractRepository; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountRepository | ||||
|  * | ||||
|  * The repository collects a single or many (account) objects from the database and returns them to the | ||||
|  * account resource. The account resource links all account properties to the JSON properties. | ||||
|  * | ||||
|  * For the queryAll thing, a separate query is constructed that does the actual querying of the database. | ||||
|  * This is necessary because the user can't just query all accounts (it would return other user's data) | ||||
|  * and because we also need to collect all kinds of metadata, like the currency and user info. | ||||
|  */ | ||||
| class AccountRepository extends AbstractRepository implements QueriesAll | ||||
| { | ||||
|     use UsergroupAware; | ||||
| @@ -39,11 +49,13 @@ class AccountRepository extends AbstractRepository implements QueriesAll | ||||
| 
 | ||||
|     public function find(string $resourceId): ?object | ||||
|     { | ||||
|         die('query single?'); | ||||
|         return Account::find((int) $resourceId); | ||||
|     } | ||||
| 
 | ||||
|     public function queryAll(): Capabilities\AccountQuery | ||||
|     { | ||||
|         die('query all?'); | ||||
|         return Capabilities\AccountQuery::make() | ||||
|             ->withUserGroup($this->userGroup) | ||||
|             ->withServer($this->server) | ||||
|   | ||||
| @@ -10,6 +10,11 @@ use LaravelJsonApi\Core\Resources\JsonApiResource; | ||||
| 
 | ||||
| /** | ||||
|  * @property Account $resource | ||||
|  * | ||||
|  * This class collects the resources attributes, the account in this case. | ||||
|  * Generally speaking, each property here is directly related to a property on the account object itself. | ||||
|  * However, many properties are collected from other sources, like the user or the currency. | ||||
|  * As a result, the account repository is where it's at, which is where the collection takes place and is optimised. | ||||
|  */ | ||||
| class AccountResource extends JsonApiResource | ||||
| { | ||||
| @@ -21,14 +26,14 @@ class AccountResource extends JsonApiResource | ||||
|     public function attributes($request): iterable | ||||
|     { | ||||
|         return [ | ||||
|             'created_at'      => $this->resource->created_at, | ||||
|             'updated_at'      => $this->resource->updated_at, | ||||
|             'name'            => $this->resource->name, | ||||
|             'iban'            => '' === $this->resource->iban ? null : $this->resource->iban, | ||||
|             'active'          => $this->resource->active, | ||||
|             'last_activity'   => $this->resource->last_activity, | ||||
|             'type'            => $this->resource->type, | ||||
|             'account_role'    => $this->resource->account_role, | ||||
|             'created_at'    => $this->resource->created_at, | ||||
|             'updated_at'    => $this->resource->updated_at, | ||||
|             'name'          => $this->resource->name, | ||||
| //            'iban'          => '' === $this->resource->iban ? null : $this->resource->iban,
 | ||||
| //            'active'        => $this->resource->active,
 | ||||
| //            'last_activity' => $this->resource->last_activity,
 | ||||
| //            'type'          => $this->resource->type,
 | ||||
| //            'account_role'  => $this->resource->account_role,
 | ||||
| 
 | ||||
|             //            'virtual_balance' => $this->resource->virtual_balance,
 | ||||
|             //            'native_balance'  => $this->resource->native_balance,
 | ||||
|   | ||||
| @@ -17,6 +17,13 @@ use LaravelJsonApi\Eloquent\Filters\WhereIdIn; | ||||
| use LaravelJsonApi\Eloquent\Pagination\PagePagination; | ||||
| use LaravelJsonApi\Eloquent\Schema; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountSchema | ||||
|  * | ||||
|  * This is the schema of all fields that an account exposes to the world. | ||||
|  * Fields do not have to have a relation to the actual model. | ||||
|  * Fields mentioned here still need to be filled in by the AccountResource. | ||||
|  */ | ||||
| class AccountSchema extends Schema | ||||
| { | ||||
|     /** | ||||
| @@ -34,18 +41,19 @@ class AccountSchema extends Schema | ||||
|             DateTime::make('created_at')->sortable()->readOnly(), | ||||
|             DateTime::make('updated_at')->sortable()->readOnly(), | ||||
|             Str::make('name')->sortable(), | ||||
|             Str::make('account_type'), | ||||
|             Str::make('virtual_balance'), | ||||
|             Str::make('iban'), | ||||
|             Boolean::make('active'), | ||||
|             Number::make('order'), | ||||
|             HasOne::make('user'), | ||||
|             HasMany::make('account_balances'), | ||||
| //            Str::make('account_type'),
 | ||||
| //            Str::make('virtual_balance'),
 | ||||
| //            Str::make('iban'),
 | ||||
| //            Boolean::make('active'),
 | ||||
| //            Number::make('order'),
 | ||||
|             HasOne::make('user')->readOnly(), | ||||
|             //HasMany::make('account_balances'),
 | ||||
|         ]; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Get the resource filters. | ||||
|      * Filters mentioned here can be used to filter the results. | ||||
|      * TODO write down exactly how this works. | ||||
|      */ | ||||
|     public function filters(): array | ||||
|     { | ||||
|   | ||||
| @@ -33,7 +33,7 @@ use LaravelJsonApi\Contracts\Store\HasPagination; | ||||
| use LaravelJsonApi\NonEloquent\Capabilities\QueryAll; | ||||
| use LaravelJsonApi\NonEloquent\Concerns\PaginatesEnumerables; | ||||
| 
 | ||||
| class AccountQuery extends QueryAll implements HasPagination | ||||
| class AccountQuery implements HasPagination | ||||
| { | ||||
|     use ExpandsQuery; | ||||
|     use FiltersPagination; | ||||
| @@ -42,32 +42,44 @@ class AccountQuery extends QueryAll implements HasPagination | ||||
|     use UsergroupAware; | ||||
|     use ValidateSortParameters; | ||||
| 
 | ||||
|     #[\Override]
 | ||||
|     public function get(): iterable | ||||
|     /** | ||||
|      * This method returns all accounts, given a bunch of filters and sort fields, together with pagination. | ||||
|      */ | ||||
|     public function queryAll(): iterable | ||||
|     { | ||||
|         // collect filters
 | ||||
|         $filters    = $this->queryParameters->filter(); | ||||
|         // collect sort options
 | ||||
|         $sort       = $this->queryParameters->sortFields(); | ||||
|         // collect pagination based on the page
 | ||||
|         $pagination = $this->filtersPagination($this->queryParameters->page()); | ||||
|         // check if we need all accounts, regardless of pagination
 | ||||
|         // This is necessary when the user wants to sort on specific params.
 | ||||
|         $needsAll   = $this->validateParams('account', $sort); | ||||
| 
 | ||||
|         // start the query
 | ||||
|         $query      = $this->userGroup->accounts(); | ||||
| 
 | ||||
|         // add pagination to the query, limiting the results.
 | ||||
|         if (!$needsAll) { | ||||
|             $query = $this->addPagination($query, $pagination); | ||||
|         } | ||||
| 
 | ||||
|         // add sort and filter parameters to the query.
 | ||||
|         $query      = $this->addSortParams($query, $sort); | ||||
|         $query      = $this->addFilterParams('account', $query, $filters); | ||||
| 
 | ||||
|         // collect the result.
 | ||||
|         $collection = $query->get(['accounts.*']); | ||||
| 
 | ||||
|         // enrich data
 | ||||
|         // enrich the collected data
 | ||||
|         $enrichment = new AccountEnrichment(); | ||||
|         $collection = $enrichment->enrich($collection); | ||||
| 
 | ||||
|         // add filters after the query
 | ||||
|         // TODO add filters after the query, if there are filters that cannot be applied to the database but only
 | ||||
|         // to the enriched results.
 | ||||
| 
 | ||||
|         // add sort after the query
 | ||||
|         // sort the data after the query, and return it right away.
 | ||||
|         return $this->sortCollection($collection, $sort); | ||||
|         //        var_dump($filters->value('name'));
 | ||||
|         //        exit;
 | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -9,6 +9,11 @@ use FireflyIII\JsonApi\V2\AccountBalances\AccountBalanceSchema; | ||||
| use FireflyIII\JsonApi\V2\Users\UserSchema; | ||||
| use LaravelJsonApi\Core\Server\Server as BaseServer; | ||||
| 
 | ||||
| /** | ||||
|  * Class Server | ||||
|  * | ||||
|  * This class serves as a generic class for the v2 API "server". | ||||
|  */ | ||||
| class Server extends BaseServer | ||||
| { | ||||
|     /** | ||||
| @@ -32,7 +37,7 @@ class Server extends BaseServer | ||||
|         return [ | ||||
|             AccountSchema::class, | ||||
|             UserSchema::class, | ||||
|             AccountBalanceSchema::class, | ||||
|             //AccountBalanceSchema::class,
 | ||||
|         ]; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace FireflyIII\Models; | ||||
| use Carbon\Carbon; | ||||
| use Eloquent; | ||||
| use FireflyIII\Support\Models\ReturnsIntegerIdTrait; | ||||
| use GeneaLabs\LaravelModelCaching\Traits\Cachable; | ||||
| use Illuminate\Database\Eloquent\Builder; | ||||
| use Illuminate\Database\Eloquent\Casts\Attribute; | ||||
| use Illuminate\Database\Eloquent\Collection; | ||||
| @@ -96,6 +97,7 @@ class Transaction extends Model | ||||
|     use HasFactory; | ||||
|     use ReturnsIntegerIdTrait; | ||||
|     use SoftDeletes; | ||||
|     use Cachable; | ||||
| 
 | ||||
|     protected $casts | ||||
|                       = [ | ||||
|   | ||||
| @@ -32,32 +32,43 @@ use FireflyIII\Repositories\UserGroups\Currency\CurrencyRepositoryInterface; | ||||
| use Illuminate\Support\Collection; | ||||
| use Illuminate\Support\Facades\Log; | ||||
| 
 | ||||
| /** | ||||
|  * Class AccountEnrichment | ||||
|  * | ||||
|  * This class "enriches" accounts and adds data from other tables and models to each account model.
 | ||||
|  */ | ||||
| class AccountEnrichment implements EnrichmentInterface | ||||
| { | ||||
|     private Collection $collection; | ||||
|     private array      $currencies; | ||||
| 
 | ||||
|     #[\Override]
 | ||||
|     /** | ||||
|      * Do the actual enrichment. | ||||
|      */ | ||||
|     public function enrich(Collection $collection): Collection | ||||
|     { | ||||
|         Log::debug(sprintf('Now doing account enrichment for %d account(s)', $collection->count())); | ||||
|         // prep local fields
 | ||||
|         $this->collection = $collection; | ||||
|         $this->currencies = []; | ||||
| 
 | ||||
|         // do everything here:
 | ||||
|         $this->getLastActivity(); | ||||
|         // $this->getMetaBalances();
 | ||||
|         $this->collectAccountTypes(); | ||||
|         $this->collectMetaData(); | ||||
| 
 | ||||
|         $this->collection->transform(function (Account $account) { | ||||
|             $account->user_array = ['id' => 1, 'bla bla' => 'bla']; | ||||
|             $account->balances   = collect([ | ||||
|                 ['balance_id' => 1, 'balance' => 5], | ||||
|                 ['balance_id' => 2, 'balance' => 5], | ||||
|                 ['balance_id' => 3, 'balance' => 5], | ||||
|             ]); | ||||
| 
 | ||||
|             return $account; | ||||
|         }); | ||||
| //        $this->collection->transform(function (Account $account) {
 | ||||
| //            $account->user_array = ['id' => 1, 'bla bla' => 'bla'];
 | ||||
| //            $account->balances   = collect([
 | ||||
| //                ['balance_id' => 1, 'balance' => 5],
 | ||||
| //                ['balance_id' => 2, 'balance' => 5],
 | ||||
| //                ['balance_id' => 3, 'balance' => 5],
 | ||||
| //            ]);
 | ||||
| //
 | ||||
| //            return $account;
 | ||||
| //        });
 | ||||
| 
 | ||||
|         return $this->collection; | ||||
|     } | ||||
|   | ||||
| @@ -1,11 +1,8 @@ | ||||
| <?php | ||||
| 
 | ||||
| return [ | ||||
|     'cache-prefix' => '', | ||||
| 
 | ||||
|     'enabled' => env('MODEL_CACHE_ENABLED', true), | ||||
| 
 | ||||
|     'cache-prefix'        => '', | ||||
|     'enabled'             => env('MODEL_CACHE_ENABLED', true), | ||||
|     'use-database-keying' => env('MODEL_CACHE_USE_DATABASE_KEYING', true), | ||||
| 
 | ||||
|     'store' => env('MODEL_CACHE_STORE'), | ||||
|     'store'               => env('MODEL_CACHE_STORE'), | ||||
| ]; | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
| 
 | ||||
| declare(strict_types=1); | ||||
| 
 | ||||
| use FireflyIII\Http\Controllers\Api\V2\Controllers\AccountController; | ||||
| use FireflyIII\Api\V2\Controllers\JsonApi\AccountController; | ||||
| use LaravelJsonApi\Laravel\Facades\JsonApiRoute; | ||||
| use LaravelJsonApi\Laravel\Http\Controllers\JsonApiController; | ||||
| use LaravelJsonApi\Laravel\Routing\Relationships; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user