diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php index d83c713aa1..4603e9497d 100644 --- a/app/Api/V1/Controllers/Controller.php +++ b/app/Api/V1/Controllers/Controller.php @@ -67,6 +67,7 @@ abstract class Controller extends BaseController protected bool $convertToPrimary = false; protected TransactionCurrency $primaryCurrency; + /** @deprecated use Request classes */ protected ParameterBag $parameters; @@ -100,7 +101,7 @@ abstract class Controller extends BaseController /** * @deprecated use Request classes - * Method to grab all parameters from the URL. + * Method to grab all parameters from the URL */ private function getParameters(): ParameterBag { diff --git a/app/Api/V1/Controllers/Models/Account/ShowController.php b/app/Api/V1/Controllers/Models/Account/ShowController.php index ab0e510911..e756551e19 100644 --- a/app/Api/V1/Controllers/Models/Account/ShowController.php +++ b/app/Api/V1/Controllers/Models/Account/ShowController.php @@ -70,7 +70,7 @@ class ShowController extends Controller */ public function index(ShowRequest $request): JsonResponse { - $manager = $this->getManager(); + $manager = $this->getManager(); [ 'types' => $types, 'page' => $page, @@ -81,37 +81,37 @@ class ShowController extends Controller 'end' => $end, 'date' => $date, ] - = $request->attributes->all(); + = $request->attributes->all(); // get list of accounts. Count it and split it. $this->repository->resetAccountOrder(); - $collection = $this->repository->getAccountsByType($types, $sort); - $count = $collection->count(); + $collection = $this->repository->getAccountsByType($types, $sort); + $count = $collection->count(); // continue sort: // TODO if the user sorts on DB dependent field there must be no slice before enrichment, only after. // TODO still need to figure out how to do this easily. - $accounts = $collection->slice($offset, $limit); + $accounts = $collection->slice($offset, $limit); // enrich /** @var User $admin */ - $admin = auth()->user(); - $enrichment = new AccountEnrichment(); + $admin = auth()->user(); + $enrichment = new AccountEnrichment(); $enrichment->setSort($sort); $enrichment->setDate($date); $enrichment->setStart($start); $enrichment->setEnd($end); $enrichment->setUser($admin); - $accounts = $enrichment->enrich($accounts); + $accounts = $enrichment->enrich($accounts); // make paginator: - $paginator = new LengthAwarePaginator($accounts, $count, $limit, $page); - $paginator->setPath(route('api.v1.accounts.index') . $this->buildParams()); + $paginator = new LengthAwarePaginator($accounts, $count, $limit, $page); + $paginator->setPath(route('api.v1.accounts.index').$this->buildParams()); /** @var AccountTransformer $transformer */ $transformer = app(AccountTransformer::class); - $resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY); + $resource = new FractalCollection($accounts, $transformer, self::RESOURCE_KEY); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); @@ -128,23 +128,23 @@ class ShowController extends Controller // get list of accounts. Count it and split it. $this->repository->resetAccountOrder(); $account->refresh(); - $manager = $this->getManager(); - [$start, $end, $date,] = $request->attributes->all(); + $manager = $this->getManager(); + [$start, $end, $date] = $request->attributes->all(); // enrich /** @var User $admin */ - $admin = auth()->user(); - $enrichment = new AccountEnrichment(); + $admin = auth()->user(); + $enrichment = new AccountEnrichment(); $enrichment->setDate($date); $enrichment->setStart($start); $enrichment->setEnd($end); $enrichment->setUser($admin); - $account = $enrichment->enrichSingle($account); + $account = $enrichment->enrichSingle($account); /** @var AccountTransformer $transformer */ - $transformer = app(AccountTransformer::class); - $resource = new Item($account, $transformer, self::RESOURCE_KEY); + $transformer = app(AccountTransformer::class); + $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/UserGroup/IndexController.php b/app/Api/V1/Controllers/Models/UserGroup/IndexController.php index cda1faa21a..5cdbb9023f 100644 --- a/app/Api/V1/Controllers/Models/UserGroup/IndexController.php +++ b/app/Api/V1/Controllers/Models/UserGroup/IndexController.php @@ -56,8 +56,8 @@ class IndexController extends Controller { $administrations = $this->repository->get(); [ - 'page' => $page, - 'limit' => $limit, + 'page' => $page, + 'limit' => $limit, 'offset' => $offset, ] = $request->attributes->all(); $count = $administrations->count(); diff --git a/app/Api/V1/Requests/AggregateFormRequest.php b/app/Api/V1/Requests/AggregateFormRequest.php index 9e9fbf7e92..85579fffc3 100644 --- a/app/Api/V1/Requests/AggregateFormRequest.php +++ b/app/Api/V1/Requests/AggregateFormRequest.php @@ -25,8 +25,8 @@ namespace FireflyIII\Api\V1\Requests; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Log; use Illuminate\Validation\Validator; +use RuntimeException; abstract class AggregateFormRequest extends ApiRequest { @@ -44,20 +44,20 @@ abstract class AggregateFormRequest extends ApiRequest // instantiate all subrequests and share current requests' bags with them foreach ($this->getRequests() as $config) { - $requestClass = is_array($config) ? array_shift($config) : $config; + $requestClass = is_array($config) ? array_shift($config) : $config; if (!is_a($requestClass, Request::class, true)) { - throw new \RuntimeException('getRequests() must return class-strings of subclasses of Request'); + throw new RuntimeException('getRequests() must return class-strings of subclasses of Request'); } - $instance = $this->requests[] = new $requestClass(); - $instance->request = $this->request; - $instance->query = $this->query; + $instance = $this->requests[] = new $requestClass(); + $instance->request = $this->request; + $instance->query = $this->query; $instance->attributes = $this->attributes; - $instance->cookies = $this->cookies; - $instance->files = $this->files; - $instance->server = $this->server; - $instance->headers = $this->headers; + $instance->cookies = $this->cookies; + $instance->files = $this->files; + $instance->server = $this->server; + $instance->headers = $this->headers; if ($instance instanceof ApiRequest) { $instance->handleConfig(is_array($config) ? $config : []); @@ -70,9 +70,9 @@ abstract class AggregateFormRequest extends ApiRequest // check all subrequests for rules and combine them return array_reduce( $this->requests, - static fn (array $rules, FormRequest $request) => - $rules + - (method_exists($request, 'rules') + static fn (array $rules, FormRequest $request) => $rules + + ( + method_exists($request, 'rules') ? $request->rules() : [] ), diff --git a/app/Api/V1/Requests/ApiRequest.php b/app/Api/V1/Requests/ApiRequest.php index e5ee028d8d..0d2a343f81 100644 --- a/app/Api/V1/Requests/ApiRequest.php +++ b/app/Api/V1/Requests/ApiRequest.php @@ -23,11 +23,9 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests; -use FireflyIII\Exceptions\ValidationException; use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ConvertsDataTypes; use Illuminate\Foundation\Http\FormRequest; -use Illuminate\Validation\Validator; class ApiRequest extends FormRequest { @@ -38,7 +36,7 @@ class ApiRequest extends FormRequest public function handleConfig(array $config): void { - if (in_array('required', $config)) { + if (in_array('required', $config, true)) { $this->required = 'required'; } } diff --git a/app/Api/V1/Requests/DateRangeRequest.php b/app/Api/V1/Requests/DateRangeRequest.php index a5c2a22443..27d6bc7baa 100644 --- a/app/Api/V1/Requests/DateRangeRequest.php +++ b/app/Api/V1/Requests/DateRangeRequest.php @@ -23,10 +23,6 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests; -use FireflyIII\Exceptions\ValidationException; -use FireflyIII\Support\Request\ChecksLogin; -use FireflyIII\Support\Request\ConvertsDataTypes; -use Illuminate\Foundation\Http\FormRequest; use Illuminate\Validation\Validator; class DateRangeRequest extends ApiRequest @@ -34,8 +30,8 @@ class DateRangeRequest extends ApiRequest public function rules(): array { return [ - 'start' => sprintf('date|after:1970-01-02|before:2038-01-17|before:end|required_with:end|' , $this->required), - 'end' => sprintf('date|after:1970-01-02|before:2038-01-17|after:start|required_with:start|' , $this->required), + 'start' => sprintf('date|after:1970-01-02|before:2038-01-17|before:end|required_with:end|', $this->required), + 'end' => sprintf('date|after:1970-01-02|before:2038-01-17|after:start|required_with:start|', $this->required), ]; } diff --git a/app/Api/V1/Requests/DateRequest.php b/app/Api/V1/Requests/DateRequest.php index 5a87fb3086..ad9372fee9 100644 --- a/app/Api/V1/Requests/DateRequest.php +++ b/app/Api/V1/Requests/DateRequest.php @@ -30,7 +30,7 @@ class DateRequest extends ApiRequest public function rules(): array { return [ - 'date' => 'date|after:1970-01-02|before:2038-01-17|' . $this->required, + 'date' => 'date|after:1970-01-02|before:2038-01-17|'.$this->required, ]; } diff --git a/app/Api/V1/Requests/Models/Account/AccountTypeApiRequest.php b/app/Api/V1/Requests/Models/Account/AccountTypeApiRequest.php index fb2348017a..e24f6da655 100644 --- a/app/Api/V1/Requests/Models/Account/AccountTypeApiRequest.php +++ b/app/Api/V1/Requests/Models/Account/AccountTypeApiRequest.php @@ -48,7 +48,7 @@ class AccountTypeApiRequest extends ApiRequest $type = $this->convertString('type', 'all'); $this->attributes->add([ - 'type' => $type, + 'type' => $type, 'types' => $this->mapAccountTypes($type), ]); } diff --git a/app/Api/V1/Requests/PaginationRequest.php b/app/Api/V1/Requests/PaginationRequest.php index cf88f238e7..93374a2d84 100644 --- a/app/Api/V1/Requests/PaginationRequest.php +++ b/app/Api/V1/Requests/PaginationRequest.php @@ -23,11 +23,11 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Requests; -use FireflyIII\Models\Account; use FireflyIII\Rules\IsValidSortInstruction; use FireflyIII\Support\Facades\Preferences; use FireflyIII\User; use Illuminate\Validation\Validator; +use RuntimeException; class PaginationRequest extends ApiRequest { @@ -40,11 +40,10 @@ class PaginationRequest extends ApiRequest $this->sortClass = $config['sort_class'] ?? null; if (!$this->sortClass) { - throw new \RuntimeException('PaginationRequest requires a sort_class config'); + throw new RuntimeException('PaginationRequest requires a sort_class config'); } } - public function rules(): array { return [ @@ -62,7 +61,7 @@ class PaginationRequest extends ApiRequest return; } - $limit = $this->convertInteger('limit'); + $limit = $this->convertInteger('limit'); if (0 === $limit) { // get default for user: /** @var User $user */ @@ -70,10 +69,10 @@ class PaginationRequest extends ApiRequest $limit = (int)Preferences::getForUser($user, 'listPageSize', 50)->data; } - $page = $this->convertInteger('page'); - $page = min(max(1, $page), 2 ** 16); + $page = $this->convertInteger('page'); + $page = min(max(1, $page), 2 ** 16); $offset = ($page - 1) * $limit; - $sort = $this->sortClass ? $this->convertSortParameters('sort', $this->sortClass) : $this->get('sort'); + $sort = $this->sortClass ? $this->convertSortParameters('sort', $this->sortClass) : $this->get('sort'); $this->attributes->set('limit', $limit); $this->attributes->set('sort', $sort); diff --git a/app/Http/Controllers/Rule/SelectController.php b/app/Http/Controllers/Rule/SelectController.php index c16572851b..458d866378 100644 --- a/app/Http/Controllers/Rule/SelectController.php +++ b/app/Http/Controllers/Rule/SelectController.php @@ -72,8 +72,8 @@ class SelectController extends Controller { // Get parameters specified by the user /** @var User $user */ - $user = auth()->user(); - $accounts = implode(',', $request->get('accounts')); + $user = auth()->user(); + $accounts = implode(',', $request->get('accounts')); // create new rule engine: $newRuleEngine = app(RuleEngineInterface::class); $newRuleEngine->setUser($user); @@ -94,7 +94,7 @@ class SelectController extends Controller // set rules: $newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->fire(); - $resultCount = $newRuleEngine->getResults(); + $resultCount = $newRuleEngine->getResults(); session()->flash('success', trans_choice('firefly.applied_rule_selection', $resultCount, ['title' => $rule->title])); @@ -104,7 +104,7 @@ class SelectController extends Controller /** * View to select transactions by a rule. */ - public function selectTransactions(Rule $rule): Factory | RedirectResponse | View + public function selectTransactions(Rule $rule): Factory|RedirectResponse|View { if (false === $rule->active) { session()->flash('warning', trans('firefly.cannot_fire_inactive_rules')); @@ -126,14 +126,14 @@ class SelectController extends Controller public function testTriggers(TestRuleFormRequest $request): JsonResponse { // build fake rule - $rule = new Rule(); + $rule = new Rule(); /** @var \Illuminate\Database\Eloquent\Collection $triggers */ - $triggers = new Collection(); - $rule->strict = '1' === $request->get('strict'); + $triggers = new Collection(); + $rule->strict = '1' === $request->get('strict'); // build trigger array from response - $textTriggers = $this->getValidTriggerList($request); + $textTriggers = $this->getValidTriggerList($request); // warn if nothing. if (0 === count($textTriggers)) { @@ -141,10 +141,10 @@ class SelectController extends Controller } foreach ($textTriggers as $textTrigger) { - $needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true; - $trigger = new RuleTrigger(); - $trigger->trigger_type = $textTrigger['type']; - $trigger->trigger_value = $textTrigger['value']; + $needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true; + $trigger = new RuleTrigger(); + $trigger->trigger_type = $textTrigger['type']; + $trigger->trigger_value = $textTrigger['value']; if (false === $needsContext) { $trigger->trigger_value = 'true'; } @@ -159,22 +159,22 @@ class SelectController extends Controller // create new rule engine: /** @var RuleEngineInterface $newRuleEngine */ - $newRuleEngine = app(RuleEngineInterface::class); + $newRuleEngine = app(RuleEngineInterface::class); // set rules: $newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->setRefreshTriggers(false); - $collection = $newRuleEngine->find(); - $collection = $collection->slice(0, 20); + $collection = $newRuleEngine->find(); + $collection = $collection->slice(0, 20); // Warn the user if only a subset of transactions is returned - $warning = ''; + $warning = ''; if (0 === count($collection)) { $warning = (string)trans('firefly.warning_no_matching_transactions'); } // Return json response - $view = 'ERROR, see logs.'; + $view = 'ERROR, see logs.'; try { $view = view('list.journals-array-tiny', ['groups' => $collection])->render(); @@ -197,7 +197,7 @@ class SelectController extends Controller */ public function testTriggersByRule(Rule $rule): JsonResponse { - $triggers = $rule->ruleTriggers; + $triggers = $rule->ruleTriggers; if (0 === count($triggers)) { return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); @@ -207,16 +207,16 @@ class SelectController extends Controller // set rules: $newRuleEngine->setRules(new Collection()->push($rule)); - $collection = $newRuleEngine->find(); - $collection = $collection->slice(0, 20); + $collection = $newRuleEngine->find(); + $collection = $collection->slice(0, 20); - $warning = ''; + $warning = ''; if (0 === count($collection)) { $warning = (string)trans('firefly.warning_no_matching_transactions'); } // Return json response - $view = 'ERROR, see logs.'; + $view = 'ERROR, see logs.'; try { $view = view('list.journals-array-tiny', ['groups' => $collection])->render(); diff --git a/composer.lock b/composer.lock index 26c250c50c..8ea016fcc7 100644 --- a/composer.lock +++ b/composer.lock @@ -11333,11 +11333,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.30", + "version": "2.1.31", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a4a7f159927983dd4f7c8020ed227d80b7f39d7d", - "reference": "a4a7f159927983dd4f7c8020ed227d80b7f39d7d", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ead89849d879fe203ce9292c6ef5e7e76f867b96", + "reference": "ead89849d879fe203ce9292c6ef5e7e76f867b96", "shasum": "" }, "require": { @@ -11382,7 +11382,7 @@ "type": "github" } ], - "time": "2025-10-02T16:07:52+00:00" + "time": "2025-10-10T14:14:11+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", diff --git a/config/firefly.php b/config/firefly.php index 66670ca4cd..09649ade7b 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -79,7 +79,7 @@ return [ // see cer.php for exchange rates feature flag. ], 'version' => 'develop/2025-10-10', - 'build_time' => 1760095871, + 'build_time' => 1760115185, 'api_version' => '2.1.0', // field is no longer used. 'db_version' => 28, // field is no longer used. diff --git a/package-lock.json b/package-lock.json index c95f60d7b8..7e058505f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4075,9 +4075,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.8.15", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.15.tgz", - "integrity": "sha512-qsJ8/X+UypqxHXN75M7dF88jNK37dLBRW7LeUzCPz+TNs37G8cfWy9nWzS+LS//g600zrt2le9KuXt0rWfDz5Q==", + "version": "2.8.16", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz", + "integrity": "sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -7088,9 +7088,9 @@ } }, "node_modules/i18next": { - "version": "25.5.3", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.5.3.tgz", - "integrity": "sha512-joFqorDeQ6YpIXni944upwnuHBf5IoPMuqAchGVeQLdWC2JOjxgM9V8UGLhNIIH/Q8QleRxIi0BSRQehSrDLcg==", + "version": "25.6.0", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.0.tgz", + "integrity": "sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw==", "funding": [ { "type": "individual",