Merge pull request #11044 from firefly-iii/release-1760115302

🤖 Automatically merge the PR into the develop branch.
This commit is contained in:
github-actions[bot]
2025-10-10 18:55:11 +02:00
committed by GitHub
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 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
{

View File

@@ -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);
}

View File

@@ -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();

View File

@@ -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()
: []
),

View File

@@ -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';
}
}

View File

@@ -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),
];
}

View File

@@ -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,
];
}

View File

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

View File

@@ -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);

View File

@@ -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<int, RuleTrigger> $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();

8
composer.lock generated
View File

@@ -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",

View File

@@ -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.

12
package-lock.json generated
View File

@@ -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",