🤖 Auto commit for release 'develop' on 2025-10-10

This commit is contained in:
JC5
2025-10-10 18:55:02 +02:00
parent 83f3eddf44
commit a709e224d4
13 changed files with 79 additions and 85 deletions

View File

@@ -67,6 +67,7 @@ abstract class Controller extends BaseController
protected bool $convertToPrimary = false; protected bool $convertToPrimary = false;
protected TransactionCurrency $primaryCurrency; protected TransactionCurrency $primaryCurrency;
/** @deprecated use Request classes */ /** @deprecated use Request classes */
protected ParameterBag $parameters; protected ParameterBag $parameters;
@@ -100,7 +101,7 @@ abstract class Controller extends BaseController
/** /**
* @deprecated use Request classes * @deprecated use Request classes
* Method to grab all parameters from the URL. * Method to grab all parameters from the URL
*/ */
private function getParameters(): ParameterBag private function getParameters(): ParameterBag
{ {

View File

@@ -70,7 +70,7 @@ class ShowController extends Controller
*/ */
public function index(ShowRequest $request): JsonResponse public function index(ShowRequest $request): JsonResponse
{ {
$manager = $this->getManager(); $manager = $this->getManager();
[ [
'types' => $types, 'types' => $types,
'page' => $page, 'page' => $page,
@@ -81,37 +81,37 @@ class ShowController extends Controller
'end' => $end, 'end' => $end,
'date' => $date, 'date' => $date,
] ]
= $request->attributes->all(); = $request->attributes->all();
// get list of accounts. Count it and split it. // get list of accounts. Count it and split it.
$this->repository->resetAccountOrder(); $this->repository->resetAccountOrder();
$collection = $this->repository->getAccountsByType($types, $sort); $collection = $this->repository->getAccountsByType($types, $sort);
$count = $collection->count(); $count = $collection->count();
// continue sort: // continue sort:
// TODO if the user sorts on DB dependent field there must be no slice before enrichment, only after. // 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. // TODO still need to figure out how to do this easily.
$accounts = $collection->slice($offset, $limit); $accounts = $collection->slice($offset, $limit);
// enrich // enrich
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new AccountEnrichment(); $enrichment = new AccountEnrichment();
$enrichment->setSort($sort); $enrichment->setSort($sort);
$enrichment->setDate($date); $enrichment->setDate($date);
$enrichment->setStart($start); $enrichment->setStart($start);
$enrichment->setEnd($end); $enrichment->setEnd($end);
$enrichment->setUser($admin); $enrichment->setUser($admin);
$accounts = $enrichment->enrich($accounts); $accounts = $enrichment->enrich($accounts);
// make paginator: // make paginator:
$paginator = new LengthAwarePaginator($accounts, $count, $limit, $page); $paginator = new LengthAwarePaginator($accounts, $count, $limit, $page);
$paginator->setPath(route('api.v1.accounts.index') . $this->buildParams()); $paginator->setPath(route('api.v1.accounts.index').$this->buildParams());
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $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)); $resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); 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. // get list of accounts. Count it and split it.
$this->repository->resetAccountOrder(); $this->repository->resetAccountOrder();
$account->refresh(); $account->refresh();
$manager = $this->getManager(); $manager = $this->getManager();
[$start, $end, $date,] = $request->attributes->all(); [$start, $end, $date] = $request->attributes->all();
// enrich // enrich
/** @var User $admin */ /** @var User $admin */
$admin = auth()->user(); $admin = auth()->user();
$enrichment = new AccountEnrichment(); $enrichment = new AccountEnrichment();
$enrichment->setDate($date); $enrichment->setDate($date);
$enrichment->setStart($start); $enrichment->setStart($start);
$enrichment->setEnd($end); $enrichment->setEnd($end);
$enrichment->setUser($admin); $enrichment->setUser($admin);
$account = $enrichment->enrichSingle($account); $account = $enrichment->enrichSingle($account);
/** @var AccountTransformer $transformer */ /** @var AccountTransformer $transformer */
$transformer = app(AccountTransformer::class); $transformer = app(AccountTransformer::class);
$resource = new Item($account, $transformer, self::RESOURCE_KEY); $resource = new Item($account, $transformer, self::RESOURCE_KEY);
return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE);
} }

View File

@@ -56,8 +56,8 @@ class IndexController extends Controller
{ {
$administrations = $this->repository->get(); $administrations = $this->repository->get();
[ [
'page' => $page, 'page' => $page,
'limit' => $limit, 'limit' => $limit,
'offset' => $offset, 'offset' => $offset,
] = $request->attributes->all(); ] = $request->attributes->all();
$count = $administrations->count(); $count = $administrations->count();

View File

@@ -25,8 +25,8 @@ namespace FireflyIII\Api\V1\Requests;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use RuntimeException;
abstract class AggregateFormRequest extends ApiRequest abstract class AggregateFormRequest extends ApiRequest
{ {
@@ -44,20 +44,20 @@ abstract class AggregateFormRequest extends ApiRequest
// instantiate all subrequests and share current requests' bags with them // instantiate all subrequests and share current requests' bags with them
foreach ($this->getRequests() as $config) { 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)) { 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 = $this->requests[] = new $requestClass();
$instance->request = $this->request; $instance->request = $this->request;
$instance->query = $this->query; $instance->query = $this->query;
$instance->attributes = $this->attributes; $instance->attributes = $this->attributes;
$instance->cookies = $this->cookies; $instance->cookies = $this->cookies;
$instance->files = $this->files; $instance->files = $this->files;
$instance->server = $this->server; $instance->server = $this->server;
$instance->headers = $this->headers; $instance->headers = $this->headers;
if ($instance instanceof ApiRequest) { if ($instance instanceof ApiRequest) {
$instance->handleConfig(is_array($config) ? $config : []); $instance->handleConfig(is_array($config) ? $config : []);
@@ -70,9 +70,9 @@ abstract class AggregateFormRequest extends ApiRequest
// check all subrequests for rules and combine them // check all subrequests for rules and combine them
return array_reduce( return array_reduce(
$this->requests, $this->requests,
static fn (array $rules, FormRequest $request) => static fn (array $rules, FormRequest $request) => $rules
$rules + + (
(method_exists($request, 'rules') method_exists($request, 'rules')
? $request->rules() ? $request->rules()
: [] : []
), ),

View File

@@ -23,11 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Exceptions\ValidationException;
use FireflyIII\Support\Request\ChecksLogin; use FireflyIII\Support\Request\ChecksLogin;
use FireflyIII\Support\Request\ConvertsDataTypes; use FireflyIII\Support\Request\ConvertsDataTypes;
use Illuminate\Foundation\Http\FormRequest; use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Validator;
class ApiRequest extends FormRequest class ApiRequest extends FormRequest
{ {
@@ -38,7 +36,7 @@ class ApiRequest extends FormRequest
public function handleConfig(array $config): void public function handleConfig(array $config): void
{ {
if (in_array('required', $config)) { if (in_array('required', $config, true)) {
$this->required = 'required'; $this->required = 'required';
} }
} }

View File

@@ -23,10 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; 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; use Illuminate\Validation\Validator;
class DateRangeRequest extends ApiRequest class DateRangeRequest extends ApiRequest
@@ -34,8 +30,8 @@ class DateRangeRequest extends ApiRequest
public function rules(): array public function rules(): array
{ {
return [ return [
'start' => sprintf('date|after:1970-01-02|before:2038-01-17|before:end|required_with:end|' , $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), 'end' => sprintf('date|after:1970-01-02|before:2038-01-17|after:start|required_with:start|', $this->required),
]; ];
} }

View File

@@ -30,7 +30,7 @@ class DateRequest extends ApiRequest
public function rules(): array public function rules(): array
{ {
return [ 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,
]; ];
} }

View File

@@ -48,7 +48,7 @@ class AccountTypeApiRequest extends ApiRequest
$type = $this->convertString('type', 'all'); $type = $this->convertString('type', 'all');
$this->attributes->add([ $this->attributes->add([
'type' => $type, 'type' => $type,
'types' => $this->mapAccountTypes($type), 'types' => $this->mapAccountTypes($type),
]); ]);
} }

View File

@@ -23,11 +23,11 @@ declare(strict_types=1);
namespace FireflyIII\Api\V1\Requests; namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Models\Account;
use FireflyIII\Rules\IsValidSortInstruction; use FireflyIII\Rules\IsValidSortInstruction;
use FireflyIII\Support\Facades\Preferences; use FireflyIII\Support\Facades\Preferences;
use FireflyIII\User; use FireflyIII\User;
use Illuminate\Validation\Validator; use Illuminate\Validation\Validator;
use RuntimeException;
class PaginationRequest extends ApiRequest class PaginationRequest extends ApiRequest
{ {
@@ -40,11 +40,10 @@ class PaginationRequest extends ApiRequest
$this->sortClass = $config['sort_class'] ?? null; $this->sortClass = $config['sort_class'] ?? null;
if (!$this->sortClass) { 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 public function rules(): array
{ {
return [ return [
@@ -62,7 +61,7 @@ class PaginationRequest extends ApiRequest
return; return;
} }
$limit = $this->convertInteger('limit'); $limit = $this->convertInteger('limit');
if (0 === $limit) { if (0 === $limit) {
// get default for user: // get default for user:
/** @var User $user */ /** @var User $user */
@@ -70,10 +69,10 @@ class PaginationRequest extends ApiRequest
$limit = (int)Preferences::getForUser($user, 'listPageSize', 50)->data; $limit = (int)Preferences::getForUser($user, 'listPageSize', 50)->data;
} }
$page = $this->convertInteger('page'); $page = $this->convertInteger('page');
$page = min(max(1, $page), 2 ** 16); $page = min(max(1, $page), 2 ** 16);
$offset = ($page - 1) * $limit; $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('limit', $limit);
$this->attributes->set('sort', $sort); $this->attributes->set('sort', $sort);

View File

@@ -72,8 +72,8 @@ class SelectController extends Controller
{ {
// Get parameters specified by the user // Get parameters specified by the user
/** @var User $user */ /** @var User $user */
$user = auth()->user(); $user = auth()->user();
$accounts = implode(',', $request->get('accounts')); $accounts = implode(',', $request->get('accounts'));
// create new rule engine: // create new rule engine:
$newRuleEngine = app(RuleEngineInterface::class); $newRuleEngine = app(RuleEngineInterface::class);
$newRuleEngine->setUser($user); $newRuleEngine->setUser($user);
@@ -94,7 +94,7 @@ class SelectController extends Controller
// set rules: // set rules:
$newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->setRules(new Collection()->push($rule));
$newRuleEngine->fire(); $newRuleEngine->fire();
$resultCount = $newRuleEngine->getResults(); $resultCount = $newRuleEngine->getResults();
session()->flash('success', trans_choice('firefly.applied_rule_selection', $resultCount, ['title' => $rule->title])); 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. * 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) { if (false === $rule->active) {
session()->flash('warning', trans('firefly.cannot_fire_inactive_rules')); session()->flash('warning', trans('firefly.cannot_fire_inactive_rules'));
@@ -126,14 +126,14 @@ class SelectController extends Controller
public function testTriggers(TestRuleFormRequest $request): JsonResponse public function testTriggers(TestRuleFormRequest $request): JsonResponse
{ {
// build fake rule // build fake rule
$rule = new Rule(); $rule = new Rule();
/** @var \Illuminate\Database\Eloquent\Collection<int, RuleTrigger> $triggers */ /** @var \Illuminate\Database\Eloquent\Collection<int, RuleTrigger> $triggers */
$triggers = new Collection(); $triggers = new Collection();
$rule->strict = '1' === $request->get('strict'); $rule->strict = '1' === $request->get('strict');
// build trigger array from response // build trigger array from response
$textTriggers = $this->getValidTriggerList($request); $textTriggers = $this->getValidTriggerList($request);
// warn if nothing. // warn if nothing.
if (0 === count($textTriggers)) { if (0 === count($textTriggers)) {
@@ -141,10 +141,10 @@ class SelectController extends Controller
} }
foreach ($textTriggers as $textTrigger) { foreach ($textTriggers as $textTrigger) {
$needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true; $needsContext = config(sprintf('search.operators.%s.needs_context', $textTrigger['type'])) ?? true;
$trigger = new RuleTrigger(); $trigger = new RuleTrigger();
$trigger->trigger_type = $textTrigger['type']; $trigger->trigger_type = $textTrigger['type'];
$trigger->trigger_value = $textTrigger['value']; $trigger->trigger_value = $textTrigger['value'];
if (false === $needsContext) { if (false === $needsContext) {
$trigger->trigger_value = 'true'; $trigger->trigger_value = 'true';
} }
@@ -159,22 +159,22 @@ class SelectController extends Controller
// create new rule engine: // create new rule engine:
/** @var RuleEngineInterface $newRuleEngine */ /** @var RuleEngineInterface $newRuleEngine */
$newRuleEngine = app(RuleEngineInterface::class); $newRuleEngine = app(RuleEngineInterface::class);
// set rules: // set rules:
$newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->setRules(new Collection()->push($rule));
$newRuleEngine->setRefreshTriggers(false); $newRuleEngine->setRefreshTriggers(false);
$collection = $newRuleEngine->find(); $collection = $newRuleEngine->find();
$collection = $collection->slice(0, 20); $collection = $collection->slice(0, 20);
// Warn the user if only a subset of transactions is returned // Warn the user if only a subset of transactions is returned
$warning = ''; $warning = '';
if (0 === count($collection)) { if (0 === count($collection)) {
$warning = (string)trans('firefly.warning_no_matching_transactions'); $warning = (string)trans('firefly.warning_no_matching_transactions');
} }
// Return json response // Return json response
$view = 'ERROR, see logs.'; $view = 'ERROR, see logs.';
try { try {
$view = view('list.journals-array-tiny', ['groups' => $collection])->render(); $view = view('list.journals-array-tiny', ['groups' => $collection])->render();
@@ -197,7 +197,7 @@ class SelectController extends Controller
*/ */
public function testTriggersByRule(Rule $rule): JsonResponse public function testTriggersByRule(Rule $rule): JsonResponse
{ {
$triggers = $rule->ruleTriggers; $triggers = $rule->ruleTriggers;
if (0 === count($triggers)) { if (0 === count($triggers)) {
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]); return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
@@ -207,16 +207,16 @@ class SelectController extends Controller
// set rules: // set rules:
$newRuleEngine->setRules(new Collection()->push($rule)); $newRuleEngine->setRules(new Collection()->push($rule));
$collection = $newRuleEngine->find(); $collection = $newRuleEngine->find();
$collection = $collection->slice(0, 20); $collection = $collection->slice(0, 20);
$warning = ''; $warning = '';
if (0 === count($collection)) { if (0 === count($collection)) {
$warning = (string)trans('firefly.warning_no_matching_transactions'); $warning = (string)trans('firefly.warning_no_matching_transactions');
} }
// Return json response // Return json response
$view = 'ERROR, see logs.'; $view = 'ERROR, see logs.';
try { try {
$view = view('list.journals-array-tiny', ['groups' => $collection])->render(); $view = view('list.journals-array-tiny', ['groups' => $collection])->render();

8
composer.lock generated
View File

@@ -11333,11 +11333,11 @@
}, },
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "2.1.30", "version": "2.1.31",
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/a4a7f159927983dd4f7c8020ed227d80b7f39d7d", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/ead89849d879fe203ce9292c6ef5e7e76f867b96",
"reference": "a4a7f159927983dd4f7c8020ed227d80b7f39d7d", "reference": "ead89849d879fe203ce9292c6ef5e7e76f867b96",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@@ -11382,7 +11382,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2025-10-02T16:07:52+00:00" "time": "2025-10-10T14:14:11+00:00"
}, },
{ {
"name": "phpstan/phpstan-deprecation-rules", "name": "phpstan/phpstan-deprecation-rules",

View File

@@ -79,7 +79,7 @@ return [
// see cer.php for exchange rates feature flag. // see cer.php for exchange rates feature flag.
], ],
'version' => 'develop/2025-10-10', 'version' => 'develop/2025-10-10',
'build_time' => 1760095871, 'build_time' => 1760115185,
'api_version' => '2.1.0', // field is no longer used. 'api_version' => '2.1.0', // field is no longer used.
'db_version' => 28, // field is no longer used. 'db_version' => 28, // field is no longer used.

12
package-lock.json generated
View File

@@ -4075,9 +4075,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/baseline-browser-mapping": { "node_modules/baseline-browser-mapping": {
"version": "2.8.15", "version": "2.8.16",
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.15.tgz", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.16.tgz",
"integrity": "sha512-qsJ8/X+UypqxHXN75M7dF88jNK37dLBRW7LeUzCPz+TNs37G8cfWy9nWzS+LS//g600zrt2le9KuXt0rWfDz5Q==", "integrity": "sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"bin": { "bin": {
@@ -7088,9 +7088,9 @@
} }
}, },
"node_modules/i18next": { "node_modules/i18next": {
"version": "25.5.3", "version": "25.6.0",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-25.5.3.tgz", "resolved": "https://registry.npmjs.org/i18next/-/i18next-25.6.0.tgz",
"integrity": "sha512-joFqorDeQ6YpIXni944upwnuHBf5IoPMuqAchGVeQLdWC2JOjxgM9V8UGLhNIIH/Q8QleRxIi0BSRQehSrDLcg==", "integrity": "sha512-tTn8fLrwBYtnclpL5aPXK/tAYBLWVvoHM1zdfXoRNLcI+RvtMsoZRV98ePlaW3khHYKuNh/Q65W/+NVFUeIwVw==",
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",