Merge branch 'develop' into develop

This commit is contained in:
alex6480 2021-06-15 15:25:07 +02:00 committed by GitHub
commit 4846d102f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
390 changed files with 2488 additions and 2678 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,7 +35,7 @@ use Illuminate\Support\Collection;
/**
* Class CategoryController
* TODO same as opposing category controller
* See reference nr. 79
*/
class CategoryController extends Controller
{

View File

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

View File

@ -39,7 +39,7 @@ class TagController extends Controller
/**
* TagController constructor.
* TODO lots of copying and pasting here.
* See reference nr. 82
*/
public function __construct()
{

View File

@ -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 */

View File

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

View File

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

View File

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

View File

@ -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
*/

View File

@ -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
*/

View File

@ -109,7 +109,7 @@ class UpdateRequest extends FormRequest
}
$return[] = $current;
}
if (0 === count($return)) {
if (empty($return)) {
return null;
}

View File

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

View File

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

View File

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

View File

@ -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
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -105,6 +105,7 @@ class UpgradeDatabase extends Command
// instructions
'firefly:instructions update',
'firefly-iii:verify-security-alerts'
];
$args = [];
if ($this->option('force')) {

View File

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

View 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;
}
}

View File

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

View File

@ -27,7 +27,7 @@ use Illuminate\Queue\SerializesModels;
/**
* Class StoredTransactionLink
* TODO not used.
* See reference nr. 85
*/
class StoredTransactionLink extends Event
{

View File

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

View File

@ -27,7 +27,7 @@ use Illuminate\Queue\SerializesModels;
/**
* Class UpdatedTransactionLink
* TODO unused
* See reference nr. 86
*/
class UpdatedTransactionLink extends Event
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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) {
return redirect(route('register'));
$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;
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -318,7 +318,7 @@ class CategoryReportController extends Controller
}
/**
* TODO duplicate function
* See reference nr. 57
*
* @param Carbon $start
* @param Carbon $end

View File

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

View File

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

View File

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

View File

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

View File

@ -323,7 +323,7 @@ class TagReportController extends Controller
}
/**
* TODO duplicate function
* See reference nr. 54
*
* @param Carbon $start
* @param Carbon $end

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -69,7 +69,7 @@ class IndexController extends Controller
/**
* Show overview of all piggy banks.
* TODO complicated
* See reference nr. 66
*
* @param Request $request
*

View File

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

View File

@ -653,7 +653,7 @@ class ProfileController extends Controller
}
/**
* TODO duplicate code.
* See reference nr. 64
*
* @param string $mfaCode
*/

View File

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

View File

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

View File

@ -292,7 +292,7 @@ class DoubleController extends Controller
}
/**
* TODO this method is double.
* See reference nr. 67
*
* @param Collection $accounts
* @param int $id

View File

@ -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 = [];

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 */

View File

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

View File

@ -109,7 +109,7 @@ class Range
// send error to view if could not set money format
if (false === $moneyResult) {
Log::error('Could not set locale. The following array doesnt work: ', $localeArray);
app('view')->share('invalidMonetaryLocale', true);
app('view')->share('invalidMonetaryLocale', true);
}
// save some formats:
@ -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);
}
}
}

View File

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

View File

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

View File

@ -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
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -74,7 +74,7 @@ interface BudgetRepositoryInterface
public function findByName(?string $name): ?Budget;
/**
* TODO refactor to "find"
* See reference nr. 12
*
* @param int|null $budgetId
*

View File

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

View File

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

View File

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

View File

@ -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
*/

View File

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

View File

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

View File

@ -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 */

View File

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

View File

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

View File

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

View File

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

View File

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