mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-02-25 18:45:27 -06:00
Merge branch 'develop' into develop
This commit is contained in:
commit
4846d102f2
@ -188,7 +188,7 @@ AUTHENTICATION_GUARD=web
|
||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||
#
|
||||
CUSTOM_LOGOUT_URI=
|
||||
CUSTOM_LOGOUT_URL=
|
||||
|
||||
# LDAP connection configuration
|
||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||
|
@ -189,7 +189,7 @@ AUTHENTICATION_GUARD=web
|
||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||
#
|
||||
CUSTOM_LOGOUT_URI=
|
||||
CUSTOM_LOGOUT_URL=
|
||||
|
||||
# LDAP connection configuration
|
||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||
|
129
.env.example
129
.env.example
@ -53,8 +53,7 @@ LOG_CHANNEL=stack
|
||||
APP_LOG_LEVEL=notice
|
||||
|
||||
# Audit log level.
|
||||
# set to "emergency" if you dont want to store audit logs.
|
||||
# leave on info otherwise.
|
||||
# Set this to "emergency" if you dont want to store audit logs, leave on info otherwise.
|
||||
AUDIT_LOG_LEVEL=info
|
||||
|
||||
# Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III
|
||||
@ -89,11 +88,11 @@ PGSQL_SSL_CERT=null
|
||||
PGSQL_SSL_KEY=null
|
||||
PGSQL_SSL_CRL_FILE=null
|
||||
|
||||
# If you're looking for performance improvements, you could install memcached.
|
||||
# If you're looking for performance improvements, you could install memcached or redis
|
||||
CACHE_DRIVER=file
|
||||
SESSION_DRIVER=file
|
||||
|
||||
# If you set either of these to 'redis', you might want to update these settings too
|
||||
# If you set either of the options above to 'redis', you might want to update these settings too
|
||||
# If you use Docker or similar, you can set REDIS_HOST_FILE, REDIS_PASSWORD_FILE or
|
||||
# REDIS_PORT_FILE to set the value from a file instead of from an environment variable
|
||||
|
||||
@ -106,8 +105,8 @@ REDIS_PATH=
|
||||
# use only when using 'tcp' or 'http' for REDIS_SCHEME. Leave empty otherwise.
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
|
||||
REDIS_PASSWORD=null
|
||||
|
||||
# always use quotes and make sure redis db "0" and "1" exists. Otherwise change accordingly.
|
||||
REDIS_DB="0"
|
||||
REDIS_CACHE_DB="1"
|
||||
@ -115,12 +114,13 @@ REDIS_CACHE_DB="1"
|
||||
# Cookie settings. Should not be necessary to change these.
|
||||
# If you use Docker or similar, you can set COOKIE_DOMAIN_FILE to set
|
||||
# the value from a file instead of from an environment variable
|
||||
# Setting samesite to "strict" may give you trouble logging in.
|
||||
COOKIE_PATH="/"
|
||||
COOKIE_DOMAIN=
|
||||
COOKIE_SECURE=false
|
||||
COOKIE_SAMESITE=lax
|
||||
|
||||
# If you want Firefly III to mail you, update these settings
|
||||
# If you want Firefly III to email you, update these settings
|
||||
# For instructions, see: https://docs.firefly-iii.org/advanced-installation/email
|
||||
# If you use Docker or similar, you can set these variables from a file by appending them with _FILE
|
||||
MAIL_MAILER=log
|
||||
@ -145,7 +145,7 @@ MAILGUN_ENDPOINT=api.mailgun.net
|
||||
MANDRILL_SECRET=
|
||||
SPARKPOST_SECRET=
|
||||
|
||||
# Firefly III can send you the following messages
|
||||
# Firefly III can send you the following messages.
|
||||
SEND_REGISTRATION_MAIL=true
|
||||
SEND_ERROR_MESSAGE=true
|
||||
SEND_LOGIN_NEW_IP_WARNING=true
|
||||
@ -153,16 +153,9 @@ SEND_LOGIN_NEW_IP_WARNING=true
|
||||
# These messages contain (sensitive) transaction information:
|
||||
SEND_REPORT_JOURNALS=true
|
||||
|
||||
# Set a Mapbox API key here (see mapbox.com) so there might be a map available at various places.
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
# Take note: it is no longer necessary to set this value, and it will be removed in future versions.
|
||||
MAPBOX_API_KEY=
|
||||
|
||||
#
|
||||
# Instead of the mapbox API key, just set this value to true if you want to set the location
|
||||
# Set this value to true if you want to set the location
|
||||
# of certain things, like transactions. Since this involves an external service, it's optional
|
||||
# and disabled by default.
|
||||
#
|
||||
ENABLE_EXTERNAL_MAP=false
|
||||
|
||||
# The map will default to this location:
|
||||
@ -170,100 +163,47 @@ MAP_DEFAULT_LAT=51.983333
|
||||
MAP_DEFAULT_LONG=5.916667
|
||||
MAP_DEFAULT_ZOOM=6
|
||||
|
||||
# Firefly III has two options for user authentication. "eloquent" is the default,
|
||||
# and "ldap" for LDAP servers.
|
||||
# For full instructions on these settings please visit:
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
# If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
#
|
||||
# If you enable 'ldap' AND you run Docker, the Docker image will contact packagist.org
|
||||
# This is necessary to download the required packages.
|
||||
# Firefly III authentication settings
|
||||
#
|
||||
LOGIN_PROVIDER=eloquent
|
||||
|
||||
# It's also possible to change the way users are authenticated. You could use Authelia for example.
|
||||
# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard".
|
||||
#
|
||||
# This will also allow Windows SSO.
|
||||
#
|
||||
# If you do this please read the documentation for instructions and warnings:
|
||||
# Firefly III supports a few authentication methods:
|
||||
# - 'web' (default, uses built in DB)
|
||||
# - 'ldap'
|
||||
# - 'remote_user_guard' for Authelia etc
|
||||
# Read more about these settings in the documentation.
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
|
||||
#
|
||||
# Set to 'ldap' to enable LDAP
|
||||
#
|
||||
# This function is available in Firefly III v5.3.0 and higher.
|
||||
AUTHENTICATION_GUARD=web
|
||||
|
||||
# If the guard is changed, Firefly III uses the 'REMOTE_USER' header as per RFC 3875.
|
||||
# You can also use another header, like AUTH_USER when using Windows SSO.
|
||||
# Some systems use X-Auth headers. In that case, use HTTP_X_AUTH_USERNAME or HTTP_X_AUTH_EMAIL
|
||||
# Depending on your system, REMOTE_USER may need to be changed to HTTP_REMOTE_USER
|
||||
#
|
||||
# If this header is 'unexpectedly empty', check out the documentation.
|
||||
# https://docs.firefly-iii.org/advanced-installation/authentication
|
||||
# LDAP connection settings:
|
||||
#
|
||||
AUTHENTICATION_GUARD_HEADER=REMOTE_USER
|
||||
LDAP_HOST=ldap.yourserver.com
|
||||
LDAP_USERNAME="uid=X,ou=,o=,dc=something,dc=com"
|
||||
LDAP_PASSWORD=super_secret
|
||||
LDAP_PORT=389
|
||||
LDAP_BASE_DN="o=something,dc=site,dc=com"
|
||||
LDAP_TIMEOUT=5
|
||||
LDAP_SSL=false
|
||||
LDAP_TLS=false
|
||||
LDAP_AUTH_FIELD=uid
|
||||
|
||||
#
|
||||
# Firefly III uses email addresses as user identifiers. When you're using an external authentication guard
|
||||
# that doesn't do this, Firefly III is incapable of emailing you. Messages sent to "Bill Gates" always fail.
|
||||
#
|
||||
# However, if you set this value, Firefly III will store the value from this header as the user's backup
|
||||
# email address and use it to communicate. So user "Bill Gates" could still have
|
||||
# the email address "bill@microsoft.com".
|
||||
#
|
||||
# Example value: AUTHENTICATION_GUARD_EMAIL=HTTP_X_AUTH_EMAIL
|
||||
# Remote user guard settings
|
||||
#
|
||||
AUTHENTICATION_GUARD_HEADER=REMOTE_USER
|
||||
AUTHENTICATION_GUARD_EMAIL=
|
||||
|
||||
|
||||
# It's impossible to log out users who's authentication is handled by an external system.
|
||||
# Enter a custom URL here that will force a logout (your authentication provider can tell you).
|
||||
# Setting this variable only works when AUTHENTICATION_GUARD != web
|
||||
#
|
||||
CUSTOM_LOGOUT_URI=
|
||||
|
||||
# LDAP connection configuration
|
||||
# OpenLDAP, FreeIPA or ActiveDirectory
|
||||
# # If you use Docker or similar, you can set this variable from a file by appending it with _FILE
|
||||
ADLDAP_CONNECTION_SCHEME=OpenLDAP
|
||||
ADLDAP_AUTO_CONNECT=true
|
||||
|
||||
# LDAP connection settings
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
# ADLDAP_CONTROLLERS, ADLDAP_PORT, ADLDAP_BASEDN
|
||||
ADLDAP_CONTROLLERS=
|
||||
ADLDAP_PORT=389
|
||||
ADLDAP_TIMEOUT=5
|
||||
ADLDAP_BASEDN=""
|
||||
ADLDAP_FOLLOW_REFFERALS=false
|
||||
|
||||
# SSL/TLS settings
|
||||
ADLDAP_USE_SSL=false
|
||||
ADLDAP_USE_TLS=false
|
||||
ADLDAP_SSL_CACERTDIR=
|
||||
ADLDAP_SSL_CACERTFILE=
|
||||
ADLDAP_SSL_CERTFILE=
|
||||
ADLDAP_SSL_KEYFILE=
|
||||
ADLDAP_SSL_CIPHER_SUITE=
|
||||
ADLDAP_SSL_REQUIRE_CERT=
|
||||
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
ADLDAP_ADMIN_USERNAME=
|
||||
ADLDAP_ADMIN_PASSWORD=
|
||||
|
||||
# You can set the following variables from a file by appending them with _FILE:
|
||||
ADLDAP_ACCOUNT_PREFIX=
|
||||
ADLDAP_ACCOUNT_SUFFIX=
|
||||
|
||||
# LDAP authentication settings.
|
||||
ADLDAP_PASSWORD_SYNC=false
|
||||
ADLDAP_LOGIN_FALLBACK=false
|
||||
|
||||
ADLDAP_DISCOVER_FIELD=distinguishedname
|
||||
ADLDAP_AUTH_FIELD=distinguishedname
|
||||
|
||||
# field to sync as local username.
|
||||
# You can set the following variable from a file by appending it with _FILE:
|
||||
ADLDAP_SYNC_FIELD=userprincipalname
|
||||
# Extra authentication settings
|
||||
#
|
||||
CUSTOM_LOGOUT_URL=
|
||||
|
||||
# You can disable the X-Frame-Options header if it interferes with tools like
|
||||
# Organizr. This is at your own risk. Applications running in frames run the risk
|
||||
@ -284,11 +224,6 @@ DISABLE_CSP_HEADER=false
|
||||
TRACKER_SITE_ID=
|
||||
TRACKER_URL=
|
||||
|
||||
# Firefly III can collect telemetry on how you use Firefly III. This is opt-in.
|
||||
# In order to allow this, change the following variable to true.
|
||||
# To read more about this feature, go to this page: https://docs.firefly-iii.org/support/telemetry
|
||||
SEND_TELEMETRY=false
|
||||
|
||||
#
|
||||
# Firefly III supports webhooks. These are security sensitive and must be enabled manually first.
|
||||
#
|
||||
|
4
.github/workflows/lock.yml
vendored
4
.github/workflows/lock.yml
vendored
@ -13,7 +13,3 @@ jobs:
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: '90'
|
||||
issue-lock-comment: >
|
||||
This issue has been automatically locked since there
|
||||
has not been any recent activity after it was closed.
|
||||
Please open a new issue for related bugs.
|
||||
|
@ -87,7 +87,7 @@ class AccountController extends Controller
|
||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
||||
$default = app('amount')->getDefaultCurrency();
|
||||
|
||||
if (0 === count($frontPage->data)) {
|
||||
if (empty($frontPage->data)) {
|
||||
$frontPage->data = $defaultSet;
|
||||
$frontPage->save();
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ use Illuminate\Http\JsonResponse;
|
||||
*
|
||||
* Shows income information grouped or limited by date.
|
||||
* Ie. all income grouped by account + currency.
|
||||
* TODO same code as Expense/AccountController.
|
||||
* See reference nr. 75
|
||||
*/
|
||||
class AccountController extends Controller
|
||||
{
|
||||
@ -74,8 +74,8 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO same code as Expense/AccountController.
|
||||
* TODO does not actually include the name of the expense account.
|
||||
* See reference nr. 76
|
||||
* See reference nr. 77
|
||||
* @param GenericRequest $request
|
||||
*
|
||||
* @return JsonResponse
|
||||
@ -103,7 +103,7 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO does not actually include the name of the expense account.
|
||||
* See reference nr. 78
|
||||
*
|
||||
* @param GenericRequest $request
|
||||
*
|
||||
|
@ -35,7 +35,7 @@ use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
* Class CategoryController
|
||||
* TODO same as opposing category controller
|
||||
* See reference nr. 79
|
||||
*/
|
||||
class CategoryController extends Controller
|
||||
{
|
||||
|
@ -58,8 +58,8 @@ class AccountController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO same code as Expense/AccountController.
|
||||
* TODO does not actually include the name of the expense account.
|
||||
* See reference nr. 80
|
||||
* See reference nr. 81
|
||||
*
|
||||
* @param GenericRequest $request
|
||||
*
|
||||
|
@ -39,7 +39,7 @@ class TagController extends Controller
|
||||
|
||||
/**
|
||||
* TagController constructor.
|
||||
* TODO lots of copying and pasting here.
|
||||
* See reference nr. 82
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
@ -103,7 +103,9 @@ class StoreController extends Controller
|
||||
throw new ValidationException($validator,0, $e);
|
||||
}
|
||||
app('preferences')->mark();
|
||||
event(new StoredTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
|
||||
$applyRules = $data['apply_rules'] ?? true;
|
||||
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
event(new StoredTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
|
||||
|
||||
$manager = $this->getManager();
|
||||
/** @var User $admin */
|
||||
|
@ -80,7 +80,9 @@ class UpdateController extends Controller
|
||||
$manager = $this->getManager();
|
||||
|
||||
app('preferences')->mark();
|
||||
event(new UpdatedTransactionGroup($transactionGroup, $data['apply_rules'] ?? true));
|
||||
$applyRules = $data['apply_rules'] ?? true;
|
||||
$fireWebhooks = $data['fire_webhooks'] ?? true;
|
||||
event(new UpdatedTransactionGroup($transactionGroup, $applyRules, $fireWebhooks));
|
||||
|
||||
/** @var User $admin */
|
||||
$admin = auth()->user();
|
||||
|
@ -72,7 +72,7 @@ class UpdateController extends Controller
|
||||
*
|
||||
* @return JsonResponse
|
||||
*
|
||||
* TODO generates query exception when link exists.
|
||||
* See reference nr. 84
|
||||
*/
|
||||
public function update(UpdateRequest $request, TransactionJournalLink $journalLink): JsonResponse
|
||||
{
|
||||
|
@ -52,7 +52,7 @@ class PreferencesController extends Controller
|
||||
*/
|
||||
public function index(): JsonResponse
|
||||
{
|
||||
// TODO via repository.
|
||||
// See reference nr. 83
|
||||
$collection = auth()->user()->preferences()->get();
|
||||
$manager = $this->getManager();
|
||||
$count = $collection->count();
|
||||
|
@ -42,7 +42,7 @@ class MoveTransactionsRequest extends FormRequest
|
||||
* Configure the validator instance with special rules for after the basic validation rules.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* TODO duplicate code.
|
||||
* See reference nr. 74
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
@ -76,7 +76,7 @@ class UpdateRequest extends FormRequest
|
||||
* Configure the validator instance with special rules for after the basic validation rules.
|
||||
*
|
||||
* @param Validator $validator
|
||||
* TODO duplicate code.
|
||||
* See reference nr. 72
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
|
@ -109,7 +109,7 @@ class UpdateRequest extends FormRequest
|
||||
}
|
||||
$return[] = $current;
|
||||
}
|
||||
if (0 === count($return)) {
|
||||
if (empty($return)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -167,7 +167,7 @@ class StoreRequest extends FormRequest
|
||||
$data = $validator->getData();
|
||||
$triggers = $data['triggers'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($triggers) || 0 === count($triggers)) {
|
||||
if (!is_countable($triggers) || empty($triggers)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ class StoreRequest extends FormRequest
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? [];
|
||||
// need at least one trigger
|
||||
if (!is_countable($actions) || 0 === count($actions)) {
|
||||
if (!is_countable($actions) || empty($actions)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||
}
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ class UpdateRequest extends FormRequest
|
||||
$data = $validator->getData();
|
||||
$triggers = $data['triggers'] ?? null;
|
||||
// need at least one trigger
|
||||
if (is_array($triggers) && 0 === count($triggers)) {
|
||||
if (is_array($triggers) && empty($triggers)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_trigger'));
|
||||
}
|
||||
}
|
||||
@ -195,7 +195,7 @@ class UpdateRequest extends FormRequest
|
||||
$data = $validator->getData();
|
||||
$actions = $data['actions'] ?? null;
|
||||
// need at least one action
|
||||
if (is_array($actions) && 0 === count($actions)) {
|
||||
if (is_array($actions) && empty($actions)) {
|
||||
$validator->errors()->add('title', (string)trans('validation.at_least_one_action'));
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +65,7 @@ class UpdateRequest extends FormRequest
|
||||
public function rules(): array
|
||||
{
|
||||
$tag = $this->route()->parameter('tagOrId');
|
||||
// TODO is uniqueObjectForUser not obsolete?
|
||||
// See reference nr. 73
|
||||
$rules = [
|
||||
'tag' => 'min:1|uniqueObjectForUser:tags,tag,' . $tag->id,
|
||||
'description' => 'min:1|nullable',
|
||||
|
@ -57,9 +57,10 @@ class StoreRequest extends FormRequest
|
||||
'group_title' => $this->string('group_title'),
|
||||
'error_if_duplicate_hash' => $this->boolean('error_if_duplicate_hash'),
|
||||
'apply_rules' => $this->boolean('apply_rules', true),
|
||||
'fire_webhooks' => $this->boolean('fire_webhooks', true),
|
||||
'transactions' => $this->getTransactionData(),
|
||||
];
|
||||
// TODO location
|
||||
// See reference nr. 71
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,6 +129,9 @@ class UpdateRequest extends FormRequest
|
||||
if ($this->has('apply_rules')) {
|
||||
$data['apply_rules'] = $this->boolean('apply_rules', true);
|
||||
}
|
||||
if ($this->has('fire_webhooks')) {
|
||||
$data['fire_webhooks'] = $this->boolean('fire_webhooks', true);
|
||||
}
|
||||
if ($this->has('group_title')) {
|
||||
$data['group_title'] = $this->string('group_title');
|
||||
}
|
||||
|
@ -125,18 +125,16 @@ class ExportData extends Command
|
||||
$exporter->setExportBills($options['export']['bills']);
|
||||
$exporter->setExportPiggies($options['export']['piggies']);
|
||||
$data = $exporter->export();
|
||||
if (0 === count($data)) {
|
||||
if (empty($data)) {
|
||||
$this->error('You must export *something*. Use --export-transactions or another option. See docs.firefly-iii.org');
|
||||
}
|
||||
$returnCode = 0;
|
||||
if (0 !== count($data)) {
|
||||
if (!empty($data)) {
|
||||
try {
|
||||
$this->exportData($options, $data);
|
||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:export-data');
|
||||
} catch (FireflyException $e) {
|
||||
$this->error(sprintf('Could not store data: %s', $e->getMessage()));
|
||||
|
||||
app('telemetry')->feature('system.command.errored', 'firefly-iii:export-data');
|
||||
$returnCode = 1;
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,6 @@ class ScanAttachments extends Command
|
||||
$this->line(sprintf('Fixed attachment #%d', $attachment->id));
|
||||
}
|
||||
|
||||
app('telemetry')->feature('system.command.executed', $this->signature);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -60,8 +60,6 @@ class SetLatestVersion extends Command
|
||||
app('fireflyconfig')->set('ff3_version', config('firefly.version'));
|
||||
$this->line('Updated version.');
|
||||
|
||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:set-latest-version');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -99,8 +99,6 @@ class ApplyRules extends Command
|
||||
|
||||
$result = $this->verifyInput();
|
||||
if (false === $result) {
|
||||
app('telemetry')->feature('system.command.errored', 'firefly-iii:apply-rules');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -119,8 +117,6 @@ class ApplyRules extends Command
|
||||
$this->warn(' --rule_groups=1,2,...');
|
||||
$this->warn(' --all_rules');
|
||||
|
||||
app('telemetry')->feature('system.command.errored', 'firefly-iii:apply-rules');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -148,8 +144,6 @@ class ApplyRules extends Command
|
||||
// file the rule(s)
|
||||
$ruleEngine->fire();
|
||||
|
||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:apply-rules');
|
||||
|
||||
$this->line('');
|
||||
$end = round(microtime(true) - $start, 2);
|
||||
$this->line(sprintf('Done in %s seconds!', $end));
|
||||
|
@ -92,8 +92,6 @@ class Cron extends Command
|
||||
|
||||
$this->info('More feedback on the cron jobs can be found in the log files.');
|
||||
|
||||
app('telemetry')->feature('system.command.executed', 'firefly-iii:cron');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -105,6 +105,7 @@ class UpgradeDatabase extends Command
|
||||
|
||||
// instructions
|
||||
'firefly:instructions update',
|
||||
'firefly-iii:verify-security-alerts'
|
||||
];
|
||||
$args = [];
|
||||
if ($this->option('force')) {
|
||||
|
@ -63,18 +63,6 @@ class UpgradeFireflyInstructions extends Command
|
||||
$this->installInstructions();
|
||||
}
|
||||
|
||||
// collect system telemetry
|
||||
$isDocker = true === env('IS_DOCKER', false) ? 'true' : 'false';
|
||||
app('telemetry')->feature('system.php.version', PHP_VERSION);
|
||||
app('telemetry')->feature('system.os.version', PHP_OS);
|
||||
app('telemetry')->feature('system.database.driver', env('DB_CONNECTION', '(unknown)'));
|
||||
app('telemetry')->feature('system.os.is_docker', $isDocker);
|
||||
try {
|
||||
app('telemetry')->feature('system.users.count', (string)User::count());
|
||||
} catch (QueryException $e) {
|
||||
// @ignoreException
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
85
app/Console/Commands/VerifySecurityAlerts.php
Normal file
85
app/Console/Commands/VerifySecurityAlerts.php
Normal file
@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace FireflyIII\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Storage;
|
||||
use Log;
|
||||
|
||||
/**
|
||||
* Class VerifySecurityAlerts
|
||||
*/
|
||||
class VerifySecurityAlerts extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'firefly-iii:verify-security-alerts';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Verify security alerts';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle(): int
|
||||
{
|
||||
// remove old advisory
|
||||
app('fireflyconfig')->delete('upgrade_security_message');
|
||||
app('fireflyconfig')->delete('upgrade_security_level');
|
||||
|
||||
// check for security advisories.
|
||||
$version = config('firefly.version');
|
||||
$disk = Storage::disk('resources');
|
||||
if (!$disk->has('alerts.json')) {
|
||||
Log::debug('No alerts.json file present.');
|
||||
return 0;
|
||||
}
|
||||
$content = $disk->get('alerts.json');
|
||||
$json = json_decode($content, true, 10);
|
||||
|
||||
/** @var array $array */
|
||||
foreach ($json as $array) {
|
||||
if ($version === $array['version'] && true === $array['advisory']) {
|
||||
Log::debug(sprintf('Version %s has an alert!', $array['version']));
|
||||
// add advisory to configuration.
|
||||
app('fireflyconfig')->set('upgrade_security_message', $array['message']);
|
||||
app('fireflyconfig')->set('upgrade_security_level', $array['level']);
|
||||
|
||||
// depends on level
|
||||
if ('info' === $array['level']) {
|
||||
Log::debug('INFO level alert');
|
||||
$this->info($array['message']);
|
||||
return 0;
|
||||
}
|
||||
if ('warning' === $array['level']) {
|
||||
Log::debug('WARNING level alert');
|
||||
$this->warn('------------------------ :o');
|
||||
$this->warn($array['message']);
|
||||
$this->warn('------------------------ :o');
|
||||
return 0;
|
||||
}
|
||||
if ('danger' === $array['level']) {
|
||||
Log::debug('DANGER level alert');
|
||||
$this->error('------------------------ :-(');
|
||||
$this->error($array['message']);
|
||||
$this->error('------------------------ :-(');
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
Log::debug('This version is not mentioned.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -37,16 +37,19 @@ class StoredTransactionGroup extends Event
|
||||
use SerializesModels;
|
||||
|
||||
public bool $applyRules;
|
||||
public bool $fireWebhooks;
|
||||
public TransactionGroup $transactionGroup;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param TransactionGroup $transactionGroup
|
||||
* @param bool $applyRules
|
||||
*/
|
||||
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true)
|
||||
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true, bool $fireWebhooks = true)
|
||||
{
|
||||
$this->transactionGroup = $transactionGroup;
|
||||
$this->fireWebhooks = $fireWebhooks;
|
||||
$this->applyRules = $applyRules;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class StoredTransactionLink
|
||||
* TODO not used.
|
||||
* See reference nr. 85
|
||||
*/
|
||||
class StoredTransactionLink extends Event
|
||||
{
|
||||
|
@ -36,10 +36,9 @@ class UpdatedTransactionGroup extends Event
|
||||
{
|
||||
use SerializesModels;
|
||||
|
||||
/** @var bool */
|
||||
public $applyRules;
|
||||
/** @var TransactionGroup The group that was stored. */
|
||||
public $transactionGroup;
|
||||
public bool $applyRules;
|
||||
public bool $fireWebhooks;
|
||||
public TransactionGroup $transactionGroup;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
@ -47,9 +46,10 @@ class UpdatedTransactionGroup extends Event
|
||||
* @param TransactionGroup $transactionGroup
|
||||
* @param bool $applyRules
|
||||
*/
|
||||
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true)
|
||||
public function __construct(TransactionGroup $transactionGroup, bool $applyRules = true, bool $fireWebhooks = true)
|
||||
{
|
||||
$this->transactionGroup = $transactionGroup;
|
||||
$this->fireWebhooks = $fireWebhooks;
|
||||
$this->applyRules = $applyRules;
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ use Illuminate\Queue\SerializesModels;
|
||||
|
||||
/**
|
||||
* Class UpdatedTransactionLink
|
||||
* TODO unused
|
||||
* See reference nr. 86
|
||||
*/
|
||||
class UpdatedTransactionLink extends Event
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ class AccountFactory
|
||||
// try with type:
|
||||
if (null === $result) {
|
||||
$types = config(sprintf('firefly.accountTypeByIdentifier.%s', $accountTypeName)) ?? [];
|
||||
if (count($types) > 0) {
|
||||
if (!empty($types)) {
|
||||
$result = AccountType::whereIn('type', $types)->first();
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ class TransactionJournalFactory
|
||||
Log::debug('Start of TransactionJournalFactory::create()');
|
||||
$collection = new Collection;
|
||||
$transactions = $dataObject['transactions'] ?? [];
|
||||
if (0 === count($transactions)) {
|
||||
if (empty($transactions)) {
|
||||
Log::error('There are no transactions in the array, the TransactionJournalFactory cannot continue.');
|
||||
|
||||
return new Collection;
|
||||
|
@ -253,7 +253,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
return [
|
||||
'journals' => $journals,
|
||||
'currency' => $currency,
|
||||
'exists' => 0!==count($journals),
|
||||
'exists' => !empty($journals),
|
||||
'end' => $this->end->formatLocalized((string)trans('config.month_and_day', [], $locale)),
|
||||
'endBalance' => app('steam')->balance($account, $this->end),
|
||||
'dayBefore' => $date->formatLocalized((string)trans('config.month_and_day', [], $locale)),
|
||||
|
@ -34,7 +34,7 @@ use Throwable;
|
||||
|
||||
/**
|
||||
* Class MonthReportGenerator.
|
||||
* TODO include info about tags.
|
||||
* See reference nr. 19
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
@ -179,7 +179,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
*/
|
||||
protected function getExpenses(): array
|
||||
{
|
||||
if (count($this->expenses) > 0) {
|
||||
if (!empty($this->expenses)) {
|
||||
Log::debug('Return previous set of expenses.');
|
||||
|
||||
return $this->expenses;
|
||||
|
@ -35,7 +35,7 @@ use Throwable;
|
||||
|
||||
/**
|
||||
* Class MonthReportGenerator.
|
||||
* TODO include info about tags.
|
||||
* See reference nr. 18
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
@ -188,7 +188,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
*/
|
||||
protected function getExpenses(): array
|
||||
{
|
||||
if (count($this->expenses) > 0) {
|
||||
if (!empty($this->expenses)) {
|
||||
Log::debug('Return previous set of expenses.');
|
||||
|
||||
return $this->expenses;
|
||||
@ -213,7 +213,7 @@ class MonthReportGenerator implements ReportGeneratorInterface
|
||||
*/
|
||||
protected function getIncome(): array
|
||||
{
|
||||
if (count($this->income) > 0) {
|
||||
if (!empty($this->income)) {
|
||||
return $this->income;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,13 @@ class StoredGroupEventHandler
|
||||
{
|
||||
Log::debug(__METHOD__);
|
||||
$group = $storedGroupEvent->transactionGroup;
|
||||
$user = $group->user;
|
||||
if (false === $storedGroupEvent->fireWebhooks) {
|
||||
Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$user = $group->user;
|
||||
/** @var MessageGeneratorInterface $engine */
|
||||
$engine = app(MessageGeneratorInterface::class);
|
||||
$engine->setUser($user);
|
||||
|
@ -82,9 +82,14 @@ class UpdatedGroupEventHandler
|
||||
*/
|
||||
public function triggerWebhooks(UpdatedTransactionGroup $updatedGroupEvent): void
|
||||
{
|
||||
Log::debug('UpdatedGroupEventHandler:triggerWebhooks');
|
||||
Log::debug(__METHOD__);
|
||||
$group = $updatedGroupEvent->transactionGroup;
|
||||
$user = $group->user;
|
||||
if (false === $updatedGroupEvent->fireWebhooks) {
|
||||
Log::info(sprintf('Will not fire webhooks for transaction group #%d', $group->id));
|
||||
|
||||
return;
|
||||
}
|
||||
$user = $group->user;
|
||||
/** @var MessageGeneratorInterface $engine */
|
||||
$engine = app(MessageGeneratorInterface::class);
|
||||
$engine->setUser($user);
|
||||
|
@ -207,7 +207,7 @@ trait MetaCollection
|
||||
$this->query->leftJoin('journal_meta', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id');
|
||||
}
|
||||
$this->query->where('journal_meta.name', '=', 'external_id');
|
||||
$this->query->where('journal_meta.data', '=', sprintf('%s', $externalId));
|
||||
$this->query->where('journal_meta.data', '=', sprintf('%s', json_encode($externalId)));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ class GroupCollector implements GroupCollectorInterface
|
||||
*/
|
||||
public function setJournalIds(array $journalIds): GroupCollectorInterface
|
||||
{
|
||||
if (0 !== count($journalIds)) {
|
||||
if (!empty($journalIds)) {
|
||||
// make all integers.
|
||||
$integerIDs = array_map('intval', $journalIds);
|
||||
|
||||
|
@ -41,7 +41,7 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface
|
||||
try {
|
||||
$json = json_encode($message->message, JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $e) {
|
||||
// TODO needs FireflyException.
|
||||
// See reference nr. 87
|
||||
return sprintf('t=1,v%d=err-invalid-signature', $this->getVersion());
|
||||
}
|
||||
|
||||
|
@ -159,7 +159,7 @@ class IndexController extends Controller
|
||||
|
||||
$accounts->each(
|
||||
function (Account $account) use ($activities, $startBalances, $endBalances) {
|
||||
// TODO lots of queries executed in this block.
|
||||
// See reference nr. 68
|
||||
$account->lastActivityDate = $this->isInArray($activities, $account->id);
|
||||
$account->startBalance = $this->isInArray($startBalances, $account->id);
|
||||
$account->endBalance = $this->isInArray($endBalances, $account->id);
|
||||
|
@ -100,10 +100,6 @@ class UpdateController extends Controller
|
||||
$channel = $request->get('update_channel');
|
||||
$channel = in_array($channel, ['stable', 'beta', 'alpha'], true) ? $channel : 'stable';
|
||||
|
||||
// store as telemetry
|
||||
app('telemetry')->feature('admin.update.channel', $channel);
|
||||
app('telemetry')->feature('admin.update.permission', (string)$checkForUpdates);
|
||||
|
||||
app('fireflyconfig')->set('permission_update_check', $checkForUpdates);
|
||||
app('fireflyconfig')->set('last_update_check', time());
|
||||
app('fireflyconfig')->set('update_channel', $channel);
|
||||
|
@ -35,7 +35,6 @@ use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Illuminate\View\View;
|
||||
use Log;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
/**
|
||||
* Class LoginController
|
||||
@ -55,7 +54,9 @@ class LoginController extends Controller
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $redirectTo = RouteServiceProvider::HOME;
|
||||
protected string $redirectTo = RouteServiceProvider::HOME;
|
||||
|
||||
private string $username;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
@ -65,6 +66,7 @@ class LoginController extends Controller
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->username = 'email';
|
||||
$this->middleware('guest')->except('logout');
|
||||
}
|
||||
|
||||
@ -80,25 +82,31 @@ class LoginController extends Controller
|
||||
public function login(Request $request)
|
||||
{
|
||||
Log::channel('audit')->info(sprintf('User is trying to login using "%s"', $request->get('email')));
|
||||
Log::info('User is trying to login.');
|
||||
if ('ldap' === config('auth.providers.users.driver')) {
|
||||
/** @var Adldap\Connections\Provider $provider */
|
||||
Adldap::getProvider('default'); // @phpstan-ignore-line
|
||||
Log::info(sprintf('User is trying to login.'));
|
||||
|
||||
$guard = config('auth.defaults.guard');
|
||||
|
||||
// if the user logs in using LDAP the field is also changed (per LDAP config)
|
||||
if ('ldap' === $guard) {
|
||||
Log::debug('User wishes to login using LDAP.');
|
||||
$this->username = config('firefly.ldap_auth_field');
|
||||
}
|
||||
|
||||
|
||||
$this->validateLogin($request);
|
||||
Log::debug('Login data is valid.');
|
||||
|
||||
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
||||
// If the class is using the ThrottlesLogins trait, we can automatically throttle
|
||||
// the login attempts for this application. We'll key this by the username and
|
||||
// the IP address of the client making these requests into this application.
|
||||
if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) {
|
||||
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get('email')));
|
||||
Log::channel('audit')->info(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
||||
Log::error(sprintf('Login for user "%s" was locked out.', $request->get($this->username())));
|
||||
$this->fireLockoutEvent($request);
|
||||
|
||||
$this->sendLockoutResponse($request);
|
||||
}
|
||||
|
||||
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
||||
if ($this->attemptLogin($request)) {
|
||||
Log::channel('audit')->info(sprintf('User "%s" has been logged in.', $request->get('email')));
|
||||
@ -108,6 +116,7 @@ class LoginController extends Controller
|
||||
|
||||
return $this->sendLoginResponse($request);
|
||||
}
|
||||
Log::warning('Login attempt failed.');
|
||||
|
||||
/** Copied directly from AuthenticatesUsers, but with logging added: */
|
||||
// If the login attempt was unsuccessful we will increment the number of attempts
|
||||
@ -129,7 +138,7 @@ class LoginController extends Controller
|
||||
public function logout(Request $request)
|
||||
{
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUri = config('firefly.custom_logout_uri');
|
||||
$logoutUri = config('firefly.custom_logout_url');
|
||||
if ('remote_user_guard' === $authGuard && '' !== $logoutUri) {
|
||||
return redirect($logoutUri);
|
||||
}
|
||||
@ -189,14 +198,26 @@ class LoginController extends Controller
|
||||
{
|
||||
Log::channel('audit')->info('Show login form (1.1).');
|
||||
|
||||
$count = DB::table('users')->count();
|
||||
$loginProvider = config('firefly.login_provider');
|
||||
$title = (string)trans('firefly.login_page_title');
|
||||
if (0 === $count && 'eloquent' === $loginProvider) {
|
||||
$count = DB::table('users')->count();
|
||||
$guard = config('auth.defaults.guard');
|
||||
$title = (string)trans('firefly.login_page_title');
|
||||
|
||||
if (0 === $count && 'web' === $guard) {
|
||||
return redirect(route('register'));
|
||||
}
|
||||
|
||||
// is allowed to?
|
||||
// switch to LDAP settings:
|
||||
if ('ldap' === $guard) {
|
||||
Log::debug('User wishes to login using LDAP.');
|
||||
$this->username = config('firefly.ldap_auth_field');
|
||||
}
|
||||
|
||||
// throw warning if still using login_provider
|
||||
$ldapWarning = false;
|
||||
if ('ldap' === config('firefly.login_provider')) {
|
||||
$ldapWarning = true;
|
||||
}
|
||||
// is allowed to register, etc.
|
||||
$singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
|
||||
$allowRegistration = true;
|
||||
$allowReset = true;
|
||||
@ -205,7 +226,7 @@ class LoginController extends Controller
|
||||
}
|
||||
|
||||
// single user mode is ignored when the user is not using eloquent:
|
||||
if ('eloquent' !== $loginProvider) {
|
||||
if ('web' !== $guard) {
|
||||
$allowRegistration = false;
|
||||
$allowReset = false;
|
||||
}
|
||||
@ -218,8 +239,18 @@ class LoginController extends Controller
|
||||
$cookieName = config('google2fa.cookie_name', 'google2fa_token');
|
||||
request()->cookies->set($cookieName, 'invalid');
|
||||
}
|
||||
$usernameField = $this->username();
|
||||
|
||||
return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'allowReset', 'title'));
|
||||
return prefixView('auth.login', compact('allowRegistration', 'email', 'remember', 'ldapWarning', 'allowReset', 'title', 'usernameField'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the login username to be used by the controller.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function username()
|
||||
{
|
||||
return $this->username;
|
||||
}
|
||||
}
|
||||
|
@ -112,9 +112,6 @@ class RegisterController extends Controller
|
||||
|
||||
$this->registered($request, $user);
|
||||
|
||||
// telemetry
|
||||
app('telemetry')->feature('system.users.count', (string)User::count());
|
||||
|
||||
return redirect($this->redirectPath());
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,7 @@ class IndexController extends Controller
|
||||
$sums = $this->getSums($budgets);
|
||||
|
||||
// get budgeted for default currency:
|
||||
if (0 === count($availableBudgets)) {
|
||||
if (empty($availableBudgets)) {
|
||||
$budgeted = $this->blRepository->budgeted($start, $end, $defaultCurrency,);
|
||||
$spentArr = $this->opsRepository->sumExpenses($start, $end, null, null, $defaultCurrency);
|
||||
$spent = $spentArr[$defaultCurrency->id]['sum'] ?? '0';
|
||||
|
@ -331,7 +331,7 @@ class AccountController extends Controller
|
||||
Log::debug('Default set is ', $defaultSet);
|
||||
$frontPage = app('preferences')->get('frontPageAccounts', $defaultSet);
|
||||
Log::debug('Frontpage preference set is ', $frontPage->data);
|
||||
if (0 === count($frontPage->data)) {
|
||||
if (empty($frontPage->data)) {
|
||||
app('preferences')->set('frontPageAccounts', $defaultSet);
|
||||
Log::debug('frontpage set is empty!');
|
||||
}
|
||||
@ -509,7 +509,7 @@ class AccountController extends Controller
|
||||
/**
|
||||
* Shows the balances for a given set of dates and accounts.
|
||||
*
|
||||
* TODO this chart is not multi-currency aware.
|
||||
* See reference nr. 55
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
|
@ -63,7 +63,7 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* Show an overview for a category for all time, per month/week/year.
|
||||
* TODO test method, for category refactor.
|
||||
* See reference nr. 59
|
||||
*
|
||||
* @param Category $category
|
||||
*
|
||||
@ -111,7 +111,7 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* Shows the category chart on the front page.
|
||||
* TODO test method, for category refactor.
|
||||
* See reference nr. 60
|
||||
*
|
||||
* @return JsonResponse
|
||||
*/
|
||||
@ -138,7 +138,7 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* Chart report.
|
||||
* TODO test method, for category refactor.
|
||||
* See reference nr. 61
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Collection $accounts
|
||||
@ -254,7 +254,7 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* Chart for period for transactions without a category.
|
||||
* TODO test me.
|
||||
* See reference nr. 62
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Carbon $start
|
||||
@ -281,7 +281,7 @@ class CategoryController extends Controller
|
||||
|
||||
/**
|
||||
* Chart for a specific period.
|
||||
* TODO test method, for category refactor.
|
||||
* See reference nr. 63
|
||||
*
|
||||
* @param Category $category
|
||||
* @param Carbon $date
|
||||
|
@ -318,7 +318,7 @@ class CategoryReportController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO duplicate function
|
||||
* See reference nr. 57
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
|
@ -249,7 +249,7 @@ class DoubleReportController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this method is double.
|
||||
* See reference nr. 51
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param int $id
|
||||
@ -274,7 +274,7 @@ class DoubleReportController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO duplicate function
|
||||
* See reference nr. 52
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
@ -319,7 +319,7 @@ class DoubleReportController extends Controller
|
||||
$journalId = $journal['transaction_journal_id'];
|
||||
|
||||
// no tags? also deserves a sport
|
||||
if (0 === count($journal['tags'])) {
|
||||
if (empty($journal['tags'])) {
|
||||
$includedJournals[] = $journalId;
|
||||
// do something
|
||||
$tagName = trans('firefly.no_tags');
|
||||
@ -379,7 +379,7 @@ class DoubleReportController extends Controller
|
||||
$journalId = $journal['transaction_journal_id'];
|
||||
|
||||
// no tags? also deserves a sport
|
||||
if (0 === count($journal['tags'])) {
|
||||
if (empty($journal['tags'])) {
|
||||
$includedJournals[] = $journalId;
|
||||
// do something
|
||||
$tagName = trans('firefly.no_tags');
|
||||
|
@ -69,7 +69,7 @@ class ExpenseReportController extends Controller
|
||||
/**
|
||||
* Main chart that shows income and expense for a combination of expense/revenue accounts.
|
||||
*
|
||||
* TODO this chart is not multi-currency aware.
|
||||
* See reference nr. 58
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param Collection $expense
|
||||
@ -187,7 +187,7 @@ class ExpenseReportController extends Controller
|
||||
$newSet[$key] = $entry;
|
||||
}
|
||||
}
|
||||
if (0===count($newSet)) {
|
||||
if (empty($newSet)) {
|
||||
$newSet = $chartData;
|
||||
}
|
||||
$data = $this->generator->multiSet($newSet);
|
||||
|
@ -58,7 +58,7 @@ class PiggyBankController extends Controller
|
||||
/**
|
||||
* Shows the piggy bank history.
|
||||
*
|
||||
* TODO this chart is not multi-currency aware.
|
||||
* See reference nr. 53
|
||||
*
|
||||
* @param PiggyBankRepositoryInterface $repository
|
||||
* @param PiggyBank $piggyBank
|
||||
|
@ -102,7 +102,7 @@ class ReportController extends Controller
|
||||
}
|
||||
);
|
||||
|
||||
// TODO get liabilities and include those as well?
|
||||
// See reference nr. 56
|
||||
|
||||
while ($current < $end) {
|
||||
// get balances by date, grouped by currency.
|
||||
|
@ -323,7 +323,7 @@ class TagReportController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO duplicate function
|
||||
* See reference nr. 54
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
|
@ -63,7 +63,7 @@ abstract class Controller extends BaseController
|
||||
|
||||
// share custom auth guard info.
|
||||
$authGuard = config('firefly.authentication_guard');
|
||||
$logoutUri = config('firefly.custom_logout_uri');
|
||||
$logoutUri = config('firefly.custom_logout_url');
|
||||
|
||||
app('view')->share('authGuard', $authGuard);
|
||||
app('view')->share('logoutUri', $logoutUri);
|
||||
|
@ -189,7 +189,7 @@ class BoxController extends Controller
|
||||
$incomes[$currencyId] = app('amount')->formatAnything($currency, $incomes[$currencyId] ?? '0', false);
|
||||
$expenses[$currencyId] = app('amount')->formatAnything($currency, $expenses[$currencyId] ?? '0', false);
|
||||
}
|
||||
if (0===count($sums)) {
|
||||
if (empty($sums)) {
|
||||
$currency = app('amount')->getDefaultCurrency();
|
||||
$sums[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||
$incomes[$currency->id] = app('amount')->formatAnything($currency, '0', false);
|
||||
|
@ -64,7 +64,7 @@ class FrontpageController extends Controller
|
||||
}
|
||||
}
|
||||
$html = '';
|
||||
if (0!==count($info)) {
|
||||
if (!empty($info)) {
|
||||
try {
|
||||
$html = prefixView('json.piggy-banks', compact('info'))->render();
|
||||
|
||||
|
@ -48,7 +48,7 @@ class IntroController extends Controller
|
||||
$specificPage = $specificPage ?? '';
|
||||
$steps = $this->getBasicSteps($route);
|
||||
$specificSteps = $this->getSpecificSteps($route, $specificPage);
|
||||
if (0 === count($specificSteps)) {
|
||||
if (empty($specificSteps)) {
|
||||
Log::debug(sprintf('No specific steps for route "%s" and page "%s"', $route, $specificPage));
|
||||
|
||||
return response()->json($steps);
|
||||
|
@ -125,11 +125,6 @@ class NewUserController extends Controller
|
||||
'invoice_date' => false, 'internal_reference' => false, 'notes' => true, 'attachments' => true,];
|
||||
app('preferences')->set('transaction_journal_optional_fields', $visibleFields);
|
||||
|
||||
// telemetry: user language preference + default language.
|
||||
app('telemetry')->feature('config.firefly.default_language', config('firefly.default_language', 'en_US'));
|
||||
app('telemetry')->feature('user.preferences.language', app('steam')->getLanguage());
|
||||
app('telemetry')->feature('user.preferences.locale', app('steam')->getLocale());
|
||||
|
||||
session()->flash('success', (string) trans('firefly.stored_new_accounts_new_user'));
|
||||
app('preferences')->mark();
|
||||
|
||||
|
@ -69,7 +69,7 @@ class IndexController extends Controller
|
||||
|
||||
/**
|
||||
* Show overview of all piggy banks.
|
||||
* TODO complicated
|
||||
* See reference nr. 66
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
|
@ -115,7 +115,7 @@ class PreferencesController extends Controller
|
||||
$locales = ['equal' => (string)trans('firefly.equal_to_language')] + $locales;
|
||||
// an important fallback is that the frontPageAccount array gets refilled automatically
|
||||
// when it turns up empty.
|
||||
if (0 === count($frontPageAccounts->data)) {
|
||||
if (empty($frontPageAccounts->data)) {
|
||||
$frontPageAccounts = $accountIds;
|
||||
}
|
||||
|
||||
@ -217,11 +217,6 @@ class PreferencesController extends Controller
|
||||
session()->flash('success', (string)trans('firefly.saved_preferences'));
|
||||
app('preferences')->mark();
|
||||
|
||||
// telemetry: user language preference + default language.
|
||||
app('telemetry')->feature('config.firefly.default_language', config('firefly.default_language', 'en_US'));
|
||||
app('telemetry')->feature('user.preferences.language', app('steam')->getLanguage());
|
||||
app('telemetry')->feature('user.preferences.locale', app('steam')->getLocale());
|
||||
|
||||
return redirect(route('preferences.index'));
|
||||
}
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ class ProfileController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO duplicate code.
|
||||
* See reference nr. 64
|
||||
*
|
||||
* @param string $mfaCode
|
||||
*/
|
||||
|
@ -86,7 +86,7 @@ class EditController extends Controller
|
||||
*/
|
||||
public function edit(Request $request, Recurrence $recurrence)
|
||||
{
|
||||
// TODO should be in repos
|
||||
// See reference nr. 69
|
||||
$count = $recurrence->recurrenceTransactions()->count();
|
||||
if (0 === $count) {
|
||||
throw new FireflyException('This recurring transaction has no meta-data. You will have to delete it and recreate it. Sorry!');
|
||||
|
@ -68,7 +68,7 @@ class IndexController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO the notes of a recurrence are pretty pointless at this moment.
|
||||
* See reference nr. 70
|
||||
* Show all recurring transactions.
|
||||
*
|
||||
* @param Request $request
|
||||
|
@ -292,7 +292,7 @@ class DoubleController extends Controller
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO this method is double.
|
||||
* See reference nr. 67
|
||||
*
|
||||
* @param Collection $accounts
|
||||
* @param int $id
|
||||
|
@ -143,7 +143,7 @@ class EditController extends Controller
|
||||
*/
|
||||
private function parseFromOperators(array $submittedOperators): array
|
||||
{
|
||||
// TODO duplicated code.
|
||||
// See reference nr. 65
|
||||
$operators = config('firefly.search.operators');
|
||||
$renderedEntries = [];
|
||||
$triggers = [];
|
||||
|
@ -144,7 +144,7 @@ class SelectController extends Controller
|
||||
$textTriggers = $this->getValidTriggerList($request);
|
||||
|
||||
// warn if nothing.
|
||||
if (0 === count($textTriggers)) {
|
||||
if (empty($textTriggers)) {
|
||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
|
||||
}
|
||||
|
||||
@ -168,7 +168,7 @@ class SelectController extends Controller
|
||||
|
||||
// Warn the user if only a subset of transactions is returned
|
||||
$warning = '';
|
||||
if (0 === count($collection)) {
|
||||
if (empty($collection)) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions');
|
||||
}
|
||||
|
||||
@ -198,7 +198,7 @@ class SelectController extends Controller
|
||||
{
|
||||
$triggers = $rule->ruleTriggers;
|
||||
|
||||
if (0 === count($triggers)) {
|
||||
if (empty($triggers)) {
|
||||
return response()->json(['html' => '', 'warning' => (string)trans('firefly.warning_no_valid_triggers')]);
|
||||
}
|
||||
// create new rule engine:
|
||||
@ -210,7 +210,7 @@ class SelectController extends Controller
|
||||
$collection = $collection->slice(0, 20);
|
||||
|
||||
$warning = '';
|
||||
if (0 === count($collection)) {
|
||||
if (empty($collection)) {
|
||||
$warning = (string)trans('firefly.warning_no_matching_transactions');
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,7 @@ class SearchController extends Controller
|
||||
public function index(Request $request, SearchInterface $searcher)
|
||||
{
|
||||
// search params:
|
||||
$fullQuery = $request->get('search');
|
||||
if(is_array($request->get('search'))) {
|
||||
$fullQuery = '';
|
||||
}
|
||||
|
@ -111,6 +111,7 @@ class InstallController extends Controller
|
||||
|
||||
// final command to set latest version in DB
|
||||
'firefly-iii:set-latest-version' => ['--james-is-cool' => true],
|
||||
'firefly-iii:verify-security-alerts' => [],
|
||||
];
|
||||
|
||||
$this->lastError = '';
|
||||
|
@ -63,7 +63,7 @@ class BulkController extends Controller
|
||||
/**
|
||||
* Edit a set of journals in bulk.
|
||||
*
|
||||
* TODO user wont be able to tell if journal is part of split.
|
||||
* See reference nr. 47
|
||||
*
|
||||
* @param array $journals
|
||||
*
|
||||
|
@ -47,7 +47,7 @@ use Log;
|
||||
/**
|
||||
* Class ConvertController.
|
||||
*
|
||||
* TODO when converting to a split transfer, all sources and destinations must be the same.
|
||||
* See reference nr. 49
|
||||
*/
|
||||
class ConvertController extends Controller
|
||||
{
|
||||
@ -346,7 +346,7 @@ class ConvertController extends Controller
|
||||
throw new FireflyException(sprintf(trans('firefly.convert_invalid_destination'), $journal->id));
|
||||
}
|
||||
|
||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
||||
// See reference nr. 50
|
||||
|
||||
$update = [
|
||||
'source_id' => $sourceId,
|
||||
|
@ -70,7 +70,7 @@ class CreateController extends Controller
|
||||
$newGroup = $service->cloneGroup($group);
|
||||
|
||||
// event!
|
||||
event(new StoredTransactionGroup($newGroup, true));
|
||||
event(new StoredTransactionGroup($newGroup));
|
||||
|
||||
app('preferences')->mark();
|
||||
|
||||
|
@ -167,7 +167,7 @@ class MassController extends Controller
|
||||
{
|
||||
$journalIds = $request->get('journals');
|
||||
if (!is_array($journalIds)) {
|
||||
// TODO something error.
|
||||
// See reference nr. 48
|
||||
throw new FireflyException('This is not an array.');
|
||||
}
|
||||
$count = 0;
|
||||
|
@ -88,7 +88,7 @@ class Authenticate
|
||||
protected function authenticate($request, array $guards)
|
||||
{
|
||||
|
||||
if (0 === count($guards)) {
|
||||
if (empty($guards)) {
|
||||
try {
|
||||
// go for default guard:
|
||||
/** @noinspection PhpUndefinedMethodInspection */
|
||||
|
@ -87,7 +87,7 @@ class Installer
|
||||
*/
|
||||
private function hasNoTables(): bool
|
||||
{
|
||||
Log::debug('Now in routine hasNoTables()');
|
||||
//Log::debug('Now in routine hasNoTables()');
|
||||
|
||||
try {
|
||||
DB::table('users')->count();
|
||||
@ -107,7 +107,7 @@ class Installer
|
||||
}
|
||||
throw new FireflyException(sprintf('Could not access the database: %s', $message), 0, $e);
|
||||
}
|
||||
Log::debug('Everything seems OK with the tables.');
|
||||
//Log::debug('Everything seems OK with the tables.');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -133,5 +133,14 @@ class Range
|
||||
{
|
||||
$pref = app('preferences')->get('list-length', config('firefly.list_length', 10))->data;
|
||||
app('view')->share('listLength', $pref);
|
||||
|
||||
// share security message:
|
||||
if (
|
||||
app('fireflyconfig')->has('upgrade_security_message')
|
||||
&& app('fireflyconfig')->has('upgrade_security_level')
|
||||
) {
|
||||
app('view')->share('upgrade_security_message', app('fireflyconfig')->get('upgrade_security_message')->data);
|
||||
app('view')->share('upgrade_security_level', app('fireflyconfig')->get('upgrade_security_level')->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -69,6 +69,9 @@ class AccountFormRequest extends FormRequest
|
||||
if (false === $this->boolean('include_net_worth')) {
|
||||
$data['include_net_worth'] = '0';
|
||||
}
|
||||
if('0' === $data['opening_balance']) {
|
||||
$data['opening_balance'] = '';
|
||||
}
|
||||
|
||||
// if the account type is "liabilities" there are actually four types of liability
|
||||
// that could have been selected.
|
||||
@ -95,7 +98,7 @@ class AccountFormRequest extends FormRequest
|
||||
$ccPaymentTypes = implode(',', array_keys(config('firefly.ccTypes')));
|
||||
$rules = [
|
||||
'name' => 'required|min:1|uniqueAccountForUser',
|
||||
'opening_balance' => 'numeric|required_with:opening_balance_date|nullable|max:1000000000',
|
||||
'opening_balance' => 'numeric|nullable|max:1000000000',
|
||||
'opening_balance_date' => 'date|required_with:opening_balance|nullable',
|
||||
'iban' => ['iban', 'nullable', new UniqueIban(null, $this->string('objectType'))],
|
||||
'BIC' => 'bic|nullable',
|
||||
|
@ -304,7 +304,7 @@ class RecurrenceFormRequest extends FormRequest
|
||||
$sourceId = null;
|
||||
$destinationId = null;
|
||||
|
||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
||||
// See reference nr. 45
|
||||
|
||||
switch ($this->string('transaction_type')) {
|
||||
default:
|
||||
|
@ -37,7 +37,7 @@ class TestRuleFormRequest extends FormRequest
|
||||
|
||||
/**
|
||||
* Rules for this request.
|
||||
* TODO these rules are not valid anymore.
|
||||
* See reference nr. 46
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* LdapFilterScope.php
|
||||
* AttributeHandler.php
|
||||
* Copyright (c) 2021 james@firefly-iii.org
|
||||
*
|
||||
* This file is part of Firefly III (https://github.com/firefly-iii).
|
||||
@ -20,28 +19,23 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
namespace FireflyIII\Ldap;
|
||||
|
||||
namespace FireflyIII\Scopes;
|
||||
use FireflyIII\User as DatabaseUser;
|
||||
use LdapRecord\Models\OpenLDAP\User as LdapUser;
|
||||
|
||||
use Adldap\Laravel\Scopes\ScopeInterface;
|
||||
use Adldap\Query\Builder;
|
||||
|
||||
// @phpstan-ignore-next-line
|
||||
class LdapFilterScope implements ScopeInterface // @phpstan-ignore-line
|
||||
/**
|
||||
* Class AttributeHandler
|
||||
*/
|
||||
class AttributeHandler
|
||||
{
|
||||
/**
|
||||
* If the ADLDAP_AUTH_FILTER is provided, apply the filter to the LDAP query.
|
||||
*
|
||||
* @param Builder $query
|
||||
*
|
||||
* @return void
|
||||
* @param LdapUser $ldap
|
||||
* @param DatabaseUser $database
|
||||
*/
|
||||
public function apply(Builder $query)
|
||||
public function handle(LdapUser $ldap, DatabaseUser $database)
|
||||
{
|
||||
$filter = (string)config('ldap_auth.custom_filter');
|
||||
if ('' !== $filter) {
|
||||
$query->rawFilter($filter);
|
||||
}
|
||||
$database->email = $ldap->getFirstAttribute('mail');
|
||||
$database->save();
|
||||
}
|
||||
}
|
@ -70,7 +70,7 @@ class Configuration extends Model
|
||||
protected $table = 'configuration';
|
||||
|
||||
/**
|
||||
* TODO can be replaced by native laravel code
|
||||
* See reference nr. 17
|
||||
* @codeCoverageIgnore
|
||||
*
|
||||
* @param mixed $value
|
||||
|
@ -319,7 +319,7 @@ class TransactionJournal extends Model
|
||||
if (!self::isJoined($query, 'transaction_types')) {
|
||||
$query->leftJoin('transaction_types', 'transaction_types.id', '=', 'transaction_journals.transaction_type_id');
|
||||
}
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$query->whereIn('transaction_types.type', $types);
|
||||
}
|
||||
}
|
||||
|
@ -125,12 +125,12 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
$query = $this->user->accounts()->where('iban', '!=', '')->whereNotNull('iban');
|
||||
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||
$query->whereIn('account_types.type', $types);
|
||||
}
|
||||
|
||||
// TODO a loop like this is no longer necessary
|
||||
// See reference nr. 9
|
||||
|
||||
$accounts = $query->get(['accounts.*']);
|
||||
/** @var Account $account */
|
||||
@ -153,7 +153,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
$query = $this->user->accounts();
|
||||
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$query->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||
$query->whereIn('account_types.type', $types);
|
||||
}
|
||||
@ -161,7 +161,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
|
||||
$accounts = $query->get(['accounts.*']);
|
||||
|
||||
// TODO no longer need to loop like this
|
||||
// See reference nr. 10
|
||||
|
||||
/** @var Account $account */
|
||||
foreach ($accounts as $account) {
|
||||
@ -222,7 +222,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
$query = $this->user->accounts();
|
||||
|
||||
if (0 !== count($accountIds)) {
|
||||
if (!empty($accountIds)) {
|
||||
$query->whereIn('accounts.id', $accountIds);
|
||||
}
|
||||
$query->orderBy('accounts.order', 'ASC');
|
||||
@ -242,19 +242,19 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
{
|
||||
$res = array_intersect([AccountType::ASSET, AccountType::MORTGAGE, AccountType::LOAN, AccountType::DEBT], $types);
|
||||
$query = $this->user->accounts();
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
|
||||
// add sort parameters. At this point they're filtered to allowed fields to sort by:
|
||||
if (count($sort) > 0) {
|
||||
if (!empty($sort)) {
|
||||
foreach ($sort as $param) {
|
||||
$query->orderBy($param[0], $param[1]);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === count($sort)) {
|
||||
if (0 !== count($res)) {
|
||||
if (empty($sort)) {
|
||||
if (!empty($res)) {
|
||||
$query->orderBy('accounts.order', 'ASC');
|
||||
}
|
||||
$query->orderBy('accounts.active', 'DESC');
|
||||
@ -276,7 +276,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
$query->where('name', 'account_role');
|
||||
}, 'attachments']
|
||||
);
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
$query->where('active', true);
|
||||
@ -336,7 +336,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
$query->where('name', 'account_role');
|
||||
}]
|
||||
);
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$query->accountTypeIn($types);
|
||||
}
|
||||
$query->where('active', 0);
|
||||
@ -674,7 +674,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
}
|
||||
|
||||
}
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||
$dbQuery->whereIn('account_types.type', $types);
|
||||
}
|
||||
@ -712,7 +712,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
);
|
||||
}
|
||||
}
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||
$dbQuery->whereIn('account_types.type', $types);
|
||||
}
|
||||
@ -791,7 +791,7 @@ class AccountRepository implements AccountRepositoryInterface
|
||||
}
|
||||
);
|
||||
|
||||
if (0 !== count($types)) {
|
||||
if (!empty($types)) {
|
||||
$dbQuery->leftJoin('account_types', 'accounts.account_type_id', '=', 'account_types.id');
|
||||
$dbQuery->whereIn('account_types.type', $types);
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ class BillRepository implements BillRepositoryInterface
|
||||
{
|
||||
$bills = $this->user->bills()->get(['bills.*']);
|
||||
|
||||
// TODO no longer need to loop like this
|
||||
// See reference nr. 6
|
||||
|
||||
/** @var Bill $bill */
|
||||
foreach ($bills as $bill) {
|
||||
|
@ -72,7 +72,7 @@ interface BudgetLimitRepositoryInterface
|
||||
public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit;
|
||||
|
||||
/**
|
||||
* TODO this method is not multi-currency aware.
|
||||
* See reference nr. 11
|
||||
*
|
||||
* @param Carbon|null $start
|
||||
* @param Carbon|null $end
|
||||
|
@ -74,7 +74,7 @@ interface BudgetRepositoryInterface
|
||||
public function findByName(?string $name): ?Budget;
|
||||
|
||||
/**
|
||||
* TODO refactor to "find"
|
||||
* See reference nr. 12
|
||||
*
|
||||
* @param int|null $budgetId
|
||||
*
|
||||
|
@ -146,8 +146,8 @@ class NoBudgetRepository implements NoBudgetRepositoryInterface
|
||||
|
||||
/** @noinspection MoreThanThreeArgumentsInspection */
|
||||
/**
|
||||
* TODO this method does not include foreign amount transactions. It only sums up "amount".
|
||||
* TODO this probably also applies to the other "sumExpenses" methods.
|
||||
* See reference nr. 15
|
||||
* See reference nr. 16
|
||||
*
|
||||
* @param Carbon $start
|
||||
* @param Carbon $end
|
||||
|
@ -227,7 +227,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
if ($accounts->count() > 0) {
|
||||
$collector->setAccounts($accounts);
|
||||
}
|
||||
// TODO possible candidate for getExtractedGroups
|
||||
// See reference nr. 13
|
||||
$set = $collector->getGroups();
|
||||
$return = [];
|
||||
$total = [];
|
||||
@ -359,7 +359,7 @@ class OperationsRepository implements OperationsRepositoryInterface
|
||||
|
||||
/**
|
||||
* For now, simply refer to whichever repository holds this function.
|
||||
* TODO might be done better in the future.
|
||||
* See reference nr. 14
|
||||
*
|
||||
* @param Budget $budget
|
||||
* @param Carbon|null $start
|
||||
|
@ -89,7 +89,7 @@ class CategoryRepository implements CategoryRepositoryInterface
|
||||
{
|
||||
$categories = $this->user->categories()->get(['categories.*']);
|
||||
|
||||
// TODO no longer need to loop like this
|
||||
// See reference nr. 7
|
||||
|
||||
foreach ($categories as $category) {
|
||||
if ($category->name === $name) {
|
||||
|
@ -58,7 +58,7 @@ interface JournalRepositoryInterface
|
||||
public function findByType(array $types): Collection;
|
||||
|
||||
/**
|
||||
* TODO Refactor to "find".
|
||||
* See reference nr. 1
|
||||
* Find a specific journal.
|
||||
*
|
||||
* @param int $journalId
|
||||
@ -85,7 +85,7 @@ interface JournalRepositoryInterface
|
||||
public function getDestinationAccount(TransactionJournal $journal): Account;
|
||||
|
||||
/**
|
||||
* TODO this method is no longer well-fitted in 4.8,0. Should be refactored and/or removed.
|
||||
* See reference nr. 2
|
||||
* Return a list of all destination accounts related to journal.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
@ -96,7 +96,7 @@ interface JournalRepositoryInterface
|
||||
public function getJournalDestinationAccounts(TransactionJournal $journal): Collection;
|
||||
|
||||
/**
|
||||
* TODO this method is no longer well-fitted in 4.8,0. Should be refactored and/or removed.
|
||||
* See reference nr. 3
|
||||
* Return a list of all source accounts related to journal.
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
@ -121,7 +121,7 @@ interface JournalRepositoryInterface
|
||||
public function getLast(): ?TransactionJournal;
|
||||
|
||||
/**
|
||||
* TODO used only in transformer, so only for API use.
|
||||
* See reference nr. 4
|
||||
*
|
||||
* @param TransactionJournalLink $link
|
||||
*
|
||||
@ -150,7 +150,7 @@ interface JournalRepositoryInterface
|
||||
public function getSourceAccount(TransactionJournal $journal): Account;
|
||||
|
||||
/**
|
||||
* TODO maybe move to account repository?
|
||||
* See reference nr. 5
|
||||
*
|
||||
* @param int $journalId
|
||||
*/
|
||||
|
@ -355,7 +355,7 @@ class RecurringRepository implements RecurringRepositoryInterface
|
||||
foreach ($journalMeta as $journalId) {
|
||||
$search[] = (int)$journalId;
|
||||
}
|
||||
if (0 === count($search)) {
|
||||
if (empty($search)) {
|
||||
|
||||
return new Collection;
|
||||
}
|
||||
|
@ -542,8 +542,6 @@ class RuleRepository implements RuleRepositoryInterface
|
||||
'order' => $order,
|
||||
'active' => $active,
|
||||
];
|
||||
app('telemetry')->feature('rules.triggers.uses_trigger', $trigger['type']);
|
||||
|
||||
$this->storeTrigger($rule, $triggerValues);
|
||||
++$order;
|
||||
}
|
||||
@ -571,8 +569,6 @@ class RuleRepository implements RuleRepositoryInterface
|
||||
'order' => $order,
|
||||
'active' => $active,
|
||||
];
|
||||
app('telemetry')->feature('rules.actions.uses_action', $action['type']);
|
||||
|
||||
$this->storeAction($rule, $actionValues);
|
||||
++$order;
|
||||
}
|
||||
|
@ -380,7 +380,6 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
|
||||
{
|
||||
/** @var GroupUpdateService $service */
|
||||
$service = app(GroupUpdateService::class);
|
||||
|
||||
return $service->update($transactionGroup, $data);
|
||||
}
|
||||
|
||||
@ -398,9 +397,9 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface
|
||||
$array['categories'] = $journal->categories->toArray();
|
||||
$array['budgets'] = $journal->budgets->toArray();
|
||||
$array['notes'] = $journal->notes->toArray();
|
||||
$array['locations'] = []; // todo
|
||||
$array['locations'] = [];
|
||||
$array['attachments'] = $journal->attachments->toArray();
|
||||
$array['links'] = []; // todo
|
||||
$array['links'] = [];
|
||||
$array['piggy_bank_events'] = $journal->piggyBankEvents->toArray();
|
||||
|
||||
/** @var Transaction $transaction */
|
||||
|
@ -269,7 +269,7 @@ class UserRepository implements UserRepositoryInterface
|
||||
*/
|
||||
public function hasRole(User $user, string $role): bool
|
||||
{
|
||||
// TODO no longer need to loop like this
|
||||
// See reference nr. 8
|
||||
|
||||
/** @var Role $userRole */
|
||||
foreach ($user->roles as $userRole) {
|
||||
|
@ -102,7 +102,7 @@ trait AccountServiceTrait
|
||||
/**
|
||||
* Update meta data for account. Depends on type which fields are valid.
|
||||
*
|
||||
* TODO this method treats expense accounts and liabilities the same way (tries to save interest)
|
||||
* See reference nr. 97
|
||||
*
|
||||
* @param Account $account
|
||||
* @param array $data
|
||||
@ -410,7 +410,7 @@ trait AccountServiceTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO rename to "getOpposingTransaction"
|
||||
* See reference nr. 98
|
||||
*
|
||||
* @param TransactionJournal $journal
|
||||
* @param Account $account
|
||||
@ -705,7 +705,7 @@ trait AccountServiceTrait
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO Refactor to "getFirstJournal"
|
||||
* See reference nr. 99
|
||||
*
|
||||
* @param TransactionGroup $group
|
||||
*
|
||||
|
@ -67,7 +67,7 @@ class CreditRecalculateService
|
||||
// work based on account.
|
||||
$this->processAccount();
|
||||
}
|
||||
if (0 === count($this->work)) {
|
||||
if (empty($this->work)) {
|
||||
Log::debug('No work accounts, do not do CreditRecalculationService');
|
||||
|
||||
return;
|
||||
@ -127,7 +127,7 @@ class CreditRecalculateService
|
||||
{
|
||||
/** @var TransactionJournal $journal */
|
||||
foreach ($this->group->transactionJournals as $journal) {
|
||||
if (0 === count($this->work)) {
|
||||
if (empty($this->work)) {
|
||||
try {
|
||||
$this->findByJournal($journal);
|
||||
} catch (FireflyException $e) {
|
||||
|
@ -145,7 +145,7 @@ trait RecurringTransactionTrait
|
||||
if (array_key_exists('foreign_amount', $array) && '' === (string)$array['foreign_amount']) {
|
||||
unset($array['foreign_amount']);
|
||||
}
|
||||
// TODO typeOverrule: the account validator may have another opinion on the transaction type.
|
||||
// See reference nr. 100
|
||||
$transaction = new RecurrenceTransaction(
|
||||
[
|
||||
'recurrence_id' => $recurrence->id,
|
||||
@ -313,7 +313,7 @@ trait RecurringTransactionTrait
|
||||
*/
|
||||
protected function updateTags(RecurrenceTransaction $transaction, array $tags): void
|
||||
{
|
||||
if (count($tags) > 0) {
|
||||
if (!empty($tags)) {
|
||||
/** @var RecurrenceMeta|null $entry */
|
||||
$entry = $transaction->recurrenceTransactionMeta()->where('name', 'tags')->first();
|
||||
if (null === $entry) {
|
||||
@ -322,7 +322,7 @@ trait RecurringTransactionTrait
|
||||
$entry->value = json_encode($tags);
|
||||
$entry->save();
|
||||
}
|
||||
if (0 === count($tags)) {
|
||||
if (empty($tags)) {
|
||||
// delete if present
|
||||
$transaction->recurrenceTransactionMeta()->where('name', 'tags')->delete();
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ use Log;
|
||||
|
||||
/**
|
||||
* Class AccountUpdateService
|
||||
* TODO this is a mess.
|
||||
* See reference nr. 90
|
||||
*/
|
||||
class AccountUpdateService
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user