diff --git a/.ci/.env.ci b/.ci/.env.ci index 38e6a837c8..7bdf5582eb 100644 --- a/.ci/.env.ci +++ b/.ci/.env.ci @@ -260,12 +260,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 - # You can fine tune the start-up of a Docker container by editing these environment variables. # Use this at your own risk. Disabling certain checks and features may result in lost of inconsistent data. # However if you know what you're doing you can significantly speed up container start times. diff --git a/.deploy/heroku/.env.heroku b/.deploy/heroku/.env.heroku index 013b5b810a..f9974abbe3 100644 --- a/.deploy/heroku/.env.heroku +++ b/.deploy/heroku/.env.heroku @@ -261,12 +261,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 - # You can fine tune the start-up of a Docker container by editing these environment variables. # Use this at your own risk. Disabling certain checks and features may result in lost of inconsistent data. # However if you know what you're doing you can significantly speed up container start times. diff --git a/.env.example b/.env.example index 1c69588792..9581358e1d 100644 --- a/.env.example +++ b/.env.example @@ -38,12 +38,6 @@ TRUSTED_PROXIES= # Also available are 'syslog', 'errorlog' and 'stdout' which will log to the system itself. # A rotating log option is 'daily', creates 5 files that (surprise) rotate. # Default setting 'stack' will log to 'daily' and to 'stdout' at the same time. - -# - Docker + versions <= 4.8.1.8 and before: use "stdout" -# - Docker + versions > 4.8.1.8 : use "docker_out" -# - Docker + versions >= 5.1.1 : use "stack" -# - For everything else (als not Docker) : use 'stack' - LOG_CHANNEL=stack # Log level. You can set this from least severe to most severe: @@ -174,23 +168,21 @@ MAP_DEFAULT_ZOOM=6 # - '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 -# AUTHENTICATION_GUARD=web # # LDAP connection settings: # 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_BASE_DN="o=something,dc=site,dc=com" +LDAP_USERNAME="uid=X,ou=,o=,dc=something,dc=com" +LDAP_PASSWORD=super_secret + LDAP_AUTH_FIELD=uid # @@ -199,7 +191,6 @@ LDAP_AUTH_FIELD=uid AUTHENTICATION_GUARD_HEADER=REMOTE_USER AUTHENTICATION_GUARD_EMAIL= - # # Extra authentication settings # diff --git a/.github/assets/img/imac-complete.png b/.github/assets/img/imac-complete.png new file mode 100644 index 0000000000..82d9d7dc8d Binary files /dev/null and b/.github/assets/img/imac-complete.png differ diff --git a/.github/assets/img/ipad-complete.png b/.github/assets/img/ipad-complete.png new file mode 100644 index 0000000000..28c428bef2 Binary files /dev/null and b/.github/assets/img/ipad-complete.png differ diff --git a/.github/assets/img/iphone-complete.png b/.github/assets/img/iphone-complete.png new file mode 100644 index 0000000000..56f97fe7ca Binary files /dev/null and b/.github/assets/img/iphone-complete.png differ diff --git a/.github/assets/img/logo-small.png b/.github/assets/img/logo-small.png new file mode 100644 index 0000000000..af3334c9ce Binary files /dev/null and b/.github/assets/img/logo-small.png differ diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php index a3de7d9470..5fb3a330dc 100644 --- a/app/Api/V1/Controllers/Controller.php +++ b/app/Api/V1/Controllers/Controller.php @@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Controllers; use Carbon\Carbon; use Carbon\Exceptions\InvalidDateException; +use Carbon\Exceptions\InvalidFormatException; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; @@ -91,7 +92,7 @@ abstract class Controller extends BaseController if (null !== $date) { try { $obj = Carbon::parse($date); - } catch (InvalidDateException $e) { + } catch (InvalidDateException|InvalidFormatException $e) { // don't care Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage())); } diff --git a/app/Api/V1/Controllers/Data/Bulk/AccountController.php b/app/Api/V1/Controllers/Data/Bulk/AccountController.php index 704a6b62aa..a3584e1ed6 100644 --- a/app/Api/V1/Controllers/Data/Bulk/AccountController.php +++ b/app/Api/V1/Controllers/Data/Bulk/AccountController.php @@ -1,4 +1,25 @@ . + */ + declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers\Data\Bulk; @@ -12,11 +33,16 @@ use Illuminate\Http\JsonResponse; /** * Class AccountController + * + * @deprecated */ class AccountController extends Controller { private AccountRepositoryInterface $repository; + /** + * + */ public function __construct() { parent::__construct(); @@ -37,8 +63,8 @@ class AccountController extends Controller */ public function moveTransactions(MoveTransactionsRequest $request): JsonResponse { - $accountIds = $request->getAll(); - $original = $this->repository->find($accountIds['original_account']); + $accountIds = $request->getAll(); + $original = $this->repository->find($accountIds['original_account']); $destination = $this->repository->find($accountIds['destination_account']); /** @var AccountDestroyService $service */ diff --git a/app/Api/V1/Controllers/Data/Bulk/TransactionController.php b/app/Api/V1/Controllers/Data/Bulk/TransactionController.php new file mode 100644 index 0000000000..1138b4838c --- /dev/null +++ b/app/Api/V1/Controllers/Data/Bulk/TransactionController.php @@ -0,0 +1,97 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers\Data\Bulk; + +use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\Data\Bulk\TransactionRequest; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Services\Internal\Destroy\AccountDestroyService; +use Illuminate\Http\JsonResponse; + +/** + * Class TransactionController + * + * Endpoint to update transactions by submitting + * (optional) a "where" clause and an "update" + * clause. + * + * Because this is a security nightmare waiting to happen validation + * is pretty strict. + */ +class TransactionController extends Controller +{ + private AccountRepositoryInterface $repository; + + /** + * + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser(auth()->user()); + + return $next($request); + } + ); + } + + /** + * @param TransactionRequest $request + * + * @return JsonResponse + */ + public function update(TransactionRequest $request): JsonResponse + { + $query = $request->getAll(); + $params = $query['query']; + // this deserves better code, but for now a loop of basic if-statements + // to respond to what is in the $query. + // this is OK because only one thing can be in the query at the moment. + if ($this->updatesTransactionAccount($params)) { + $original = $this->repository->find((int)$params['where']['source_account_id']); + $destination = $this->repository->find((int)$params['update']['destination_account_id']); + + /** @var AccountDestroyService $service */ + $service = app(AccountDestroyService::class); + $service->moveTransactions($original, $destination); + } + + return response()->json([], 204); + } + + /** + * @param array $params + * + * @return bool + */ + private function updatesTransactionAccount(array $params): bool + { + return array_key_exists('source_account_id', $params['where']) && array_key_exists('destination_account_id', $params['update']); + } + +} diff --git a/app/Api/V1/Controllers/Data/Export/ExportController.php b/app/Api/V1/Controllers/Data/Export/ExportController.php index f90de392d8..72786554b4 100644 --- a/app/Api/V1/Controllers/Data/Export/ExportController.php +++ b/app/Api/V1/Controllers/Data/Export/ExportController.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Api\V1\Controllers\Data\Export; use FireflyIII\Api\V1\Controllers\Controller; diff --git a/app/Api/V1/Controllers/Insight/Expense/BillController.php b/app/Api/V1/Controllers/Insight/Expense/BillController.php index 7bb372af26..c73cc8e1b8 100644 --- a/app/Api/V1/Controllers/Insight/Expense/BillController.php +++ b/app/Api/V1/Controllers/Insight/Expense/BillController.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Api\V1\Controllers\Insight\Expense; use FireflyIII\Api\V1\Controllers\Controller; diff --git a/app/Api/V1/Controllers/Insight/Expense/TagController.php b/app/Api/V1/Controllers/Insight/Expense/TagController.php index bdbeeb8f23..d9e16fba55 100644 --- a/app/Api/V1/Controllers/Insight/Expense/TagController.php +++ b/app/Api/V1/Controllers/Insight/Expense/TagController.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Api\V1\Controllers\Insight\Expense; use FireflyIII\Api\V1\Controllers\Controller; diff --git a/app/Api/V1/Controllers/Insight/Income/AccountController.php b/app/Api/V1/Controllers/Insight/Income/AccountController.php index 3a3a72ee87..30e6b3a9e5 100644 --- a/app/Api/V1/Controllers/Insight/Income/AccountController.php +++ b/app/Api/V1/Controllers/Insight/Income/AccountController.php @@ -38,7 +38,6 @@ use Illuminate\Http\JsonResponse; * * Shows income information grouped or limited by date. * Ie. all income grouped by account + currency. - * See reference nr. 75 */ class AccountController extends Controller { @@ -74,9 +73,6 @@ class AccountController extends Controller } /** - * See reference nr. 76 - * See reference nr. 77 - * * @param GenericRequest $request * * @return JsonResponse @@ -104,8 +100,6 @@ class AccountController extends Controller } /** - * See reference nr. 78 - * * @param GenericRequest $request * * @return JsonResponse diff --git a/app/Api/V1/Controllers/Insight/Income/CategoryController.php b/app/Api/V1/Controllers/Insight/Income/CategoryController.php index 69388c113e..ffc84536fb 100644 --- a/app/Api/V1/Controllers/Insight/Income/CategoryController.php +++ b/app/Api/V1/Controllers/Insight/Income/CategoryController.php @@ -35,7 +35,6 @@ use Illuminate\Support\Collection; /** * Class CategoryController -* See reference nr. 79 */ class CategoryController extends Controller { diff --git a/app/Api/V1/Controllers/Insight/Income/TagController.php b/app/Api/V1/Controllers/Insight/Income/TagController.php index 6b3714f7ac..37eb525a60 100644 --- a/app/Api/V1/Controllers/Insight/Income/TagController.php +++ b/app/Api/V1/Controllers/Insight/Income/TagController.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Api\V1\Controllers\Insight\Income; use FireflyIII\Api\V1\Controllers\Controller; diff --git a/app/Api/V1/Controllers/Insight/Transfer/AccountController.php b/app/Api/V1/Controllers/Insight/Transfer/AccountController.php index e3239b578a..f20716ab84 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/AccountController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/AccountController.php @@ -58,8 +58,6 @@ class AccountController extends Controller } /** -* See reference nr. 80 -* See reference nr. 81 * * @param GenericRequest $request * diff --git a/app/Api/V1/Controllers/Insight/Transfer/TagController.php b/app/Api/V1/Controllers/Insight/Transfer/TagController.php index b0366d70d7..e67b01ac9c 100644 --- a/app/Api/V1/Controllers/Insight/Transfer/TagController.php +++ b/app/Api/V1/Controllers/Insight/Transfer/TagController.php @@ -39,7 +39,6 @@ class TagController extends Controller /** * TagController constructor. -* See reference nr. 82 */ public function __construct() { diff --git a/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php b/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php index 140147105a..3e9459070b 100644 --- a/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php +++ b/app/Api/V1/Controllers/Models/TransactionLink/UpdateController.php @@ -26,7 +26,6 @@ namespace FireflyIII\Api\V1\Controllers\Models\TransactionLink; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\Models\TransactionLink\UpdateRequest; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface; @@ -71,8 +70,6 @@ class UpdateController extends Controller * @param TransactionJournalLink $journalLink * * @return JsonResponse - * -* See reference nr. 84 */ public function update(UpdateRequest $request, TransactionJournalLink $journalLink): JsonResponse { diff --git a/app/Api/V1/Controllers/User/PreferencesController.php b/app/Api/V1/Controllers/User/PreferencesController.php index a0223f95df..5c7b1df7c7 100644 --- a/app/Api/V1/Controllers/User/PreferencesController.php +++ b/app/Api/V1/Controllers/User/PreferencesController.php @@ -27,6 +27,7 @@ namespace FireflyIII\Api\V1\Controllers\User; use FireflyIII\Api\V1\Controllers\Controller; use FireflyIII\Api\V1\Requests\User\PreferenceStoreRequest; use FireflyIII\Api\V1\Requests\User\PreferenceUpdateRequest; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Preference; use FireflyIII\Transformers\PreferenceTransformer; use Illuminate\Http\JsonResponse; @@ -47,13 +48,12 @@ class PreferencesController extends Controller * List all of them. * * @return JsonResponse - * @throws \FireflyIII\Exceptions\FireflyException + * @throws FireflyException * @codeCoverageIgnore */ public function index(): JsonResponse { -// See reference nr. 83 - $collection = auth()->user()->preferences()->get(); + $collection = app('preferences')->all(); $manager = $this->getManager(); $count = $collection->count(); $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; @@ -119,7 +119,7 @@ class PreferencesController extends Controller * @param Preference $preference * * @return JsonResponse - * @throws \FireflyIII\Exceptions\FireflyException + * @throws FireflyException */ public function update(PreferenceUpdateRequest $request, Preference $preference): JsonResponse { diff --git a/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php b/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php index 3e17e64644..e343066d47 100644 --- a/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php +++ b/app/Api/V1/Requests/Data/Bulk/MoveTransactionsRequest.php @@ -1,4 +1,25 @@ . + */ + declare(strict_types=1); namespace FireflyIII\Api\V1\Requests\Data\Bulk; diff --git a/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php b/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php new file mode 100644 index 0000000000..02e013fdea --- /dev/null +++ b/app/Api/V1/Requests/Data/Bulk/TransactionRequest.php @@ -0,0 +1,86 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Requests\Data\Bulk; + +use FireflyIII\Enums\ClauseType; +use FireflyIII\Rules\IsValidBulkClause; +use FireflyIII\Support\Request\ChecksLogin; +use FireflyIII\Support\Request\ConvertsDataTypes; +use FireflyIII\Validation\Api\Data\Bulk\ValidatesBulkTransactionQuery; +use Illuminate\Foundation\Http\FormRequest; +use Illuminate\Validation\Validator; +use JsonException; +use Log; + +/** + * Class TransactionRequest + */ +class TransactionRequest extends FormRequest +{ + use ChecksLogin, ConvertsDataTypes, ValidatesBulkTransactionQuery; + + /** + * @return array + */ + public function getAll(): array + { + $data = []; + try { + $data = [ + 'query' => json_decode($this->get('query'), true, 8, JSON_THROW_ON_ERROR), + ]; + } catch (JsonException $e) { + // dont really care. the validation should catch invalid json. + Log::error($e->getMessage()); + } + + return $data; + } + + /** + * @return string[] + */ + public function rules(): array + { + return [ + 'query' => ['required', 'min:1', 'max:255', 'json', new IsValidBulkClause(ClauseType::TRANSACTION)], + ]; + } + + /** + * @param Validator $validator + * + * @return void + */ + public function withValidator(Validator $validator): void + { + $validator->after( + function (Validator $validator) { + // validate transaction query data. + $this->validateTransactionQuery($validator); + } + ); + } +} diff --git a/app/Api/V1/Requests/Models/Bill/StoreRequest.php b/app/Api/V1/Requests/Models/Bill/StoreRequest.php index 88560c1077..d4ea90da3a 100644 --- a/app/Api/V1/Requests/Models/Bill/StoreRequest.php +++ b/app/Api/V1/Requests/Models/Bill/StoreRequest.php @@ -55,6 +55,8 @@ class StoreRequest extends FormRequest 'currency_id' => ['currency_id', 'integer'], 'currency_code' => ['currency_code', 'string'], 'date' => ['date', 'date'], + 'end_date' => ['end_date', 'date'], + 'extension_date' => ['extension_date', 'date'], 'repeat_freq' => ['repeat_freq', 'string'], 'skip' => ['skip', 'integer'], 'active' => ['active', 'boolean'], @@ -75,16 +77,18 @@ class StoreRequest extends FormRequest public function rules(): array { return [ - 'name' => 'between:1,255|uniqueObjectForUser:bills,name', - 'amount_min' => 'numeric|gt:0', - 'amount_max' => 'numeric|gt:0', - 'currency_id' => 'numeric|exists:transaction_currencies,id', - 'currency_code' => 'min:3|max:3|exists:transaction_currencies,code', - 'date' => 'date', - 'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly', - 'skip' => 'between:0,31', - 'active' => [new IsBoolean], - 'notes' => 'between:1,65536', + 'name' => 'between:1,255|uniqueObjectForUser:bills,name', + 'amount_min' => 'numeric|gt:0|required', + 'amount_max' => 'numeric|gt:0|required', + 'currency_id' => 'numeric|exists:transaction_currencies,id', + 'currency_code' => 'min:3|max:3|exists:transaction_currencies,code', + 'date' => 'date|required', + 'end_date' => 'date|after:date', + 'extension_date' => 'date|after:date', + 'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly|required', + 'skip' => 'between:0,31', + 'active' => [new IsBoolean], + 'notes' => 'between:1,65536', ]; } diff --git a/app/Api/V1/Requests/Models/Bill/UpdateRequest.php b/app/Api/V1/Requests/Models/Bill/UpdateRequest.php index 2a4a89e555..5a3fbc91ef 100644 --- a/app/Api/V1/Requests/Models/Bill/UpdateRequest.php +++ b/app/Api/V1/Requests/Models/Bill/UpdateRequest.php @@ -53,6 +53,8 @@ class UpdateRequest extends FormRequest 'currency_id' => ['currency_id', 'integer'], 'currency_code' => ['currency_code', 'string'], 'date' => ['date', 'date'], + 'end_date' => ['end_date', 'date'], + 'extension_date' => ['extension_date', 'date'], 'repeat_freq' => ['repeat_freq', 'string'], 'skip' => ['skip', 'integer'], 'active' => ['active', 'boolean'], @@ -75,16 +77,18 @@ class UpdateRequest extends FormRequest $bill = $this->route()->parameter('bill'); return [ - 'name' => sprintf('between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id), - 'amount_min' => 'numeric|gt:0', - 'amount_max' => 'numeric|gt:0', - 'currency_id' => 'numeric|exists:transaction_currencies,id', - 'currency_code' => 'min:3|max:3|exists:transaction_currencies,code', - 'date' => 'date', - 'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly', - 'skip' => 'between:0,31', - 'active' => [new IsBoolean], - 'notes' => 'between:1,65536', + 'name' => sprintf('between:1,255|uniqueObjectForUser:bills,name,%d', $bill->id), + 'amount_min' => 'numeric|gt:0', + 'amount_max' => 'numeric|gt:0', + 'currency_id' => 'numeric|exists:transaction_currencies,id', + 'currency_code' => 'min:3|max:3|exists:transaction_currencies,code', + 'date' => 'date', + 'end_date' => 'date|after:date', + 'extension_date' => 'date|after:date', + 'repeat_freq' => 'in:weekly,monthly,quarterly,half-year,yearly', + 'skip' => 'between:0,31', + 'active' => [new IsBoolean], + 'notes' => 'between:1,65536', ]; } diff --git a/app/Api/V1/Requests/User/PreferenceUpdateRequest.php b/app/Api/V1/Requests/User/PreferenceUpdateRequest.php index dede3ef1ab..067fd12730 100644 --- a/app/Api/V1/Requests/User/PreferenceUpdateRequest.php +++ b/app/Api/V1/Requests/User/PreferenceUpdateRequest.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Api\V1\Requests\User; use FireflyIII\Support\Request\ChecksLogin; diff --git a/app/Console/Commands/Correction/FixPostgresSequences.php b/app/Console/Commands/Correction/FixPostgresSequences.php index 2ac42466c9..eec112169d 100644 --- a/app/Console/Commands/Correction/FixPostgresSequences.php +++ b/app/Console/Commands/Correction/FixPostgresSequences.php @@ -1,4 +1,25 @@ . + */ + declare(strict_types=1); namespace FireflyIII\Console\Commands\Correction; @@ -88,7 +109,6 @@ class FixPostgresSequences extends Command 'rules', 'tag_transaction_journal', 'tags', - 'telemetry', 'transaction_currencies', 'transaction_groups', 'transaction_journals', diff --git a/app/Console/Commands/Upgrade/UpgradeLiabilities.php b/app/Console/Commands/Upgrade/UpgradeLiabilities.php index 26435e1107..87b72a934a 100644 --- a/app/Console/Commands/Upgrade/UpgradeLiabilities.php +++ b/app/Console/Commands/Upgrade/UpgradeLiabilities.php @@ -1,4 +1,25 @@ . + */ + declare(strict_types=1); namespace FireflyIII\Console\Commands\Upgrade; diff --git a/app/Console/Commands/VerifySecurityAlerts.php b/app/Console/Commands/VerifySecurityAlerts.php index 7caa2774b0..4d4bdd33bf 100644 --- a/app/Console/Commands/VerifySecurityAlerts.php +++ b/app/Console/Commands/VerifySecurityAlerts.php @@ -1,4 +1,25 @@ . + */ + declare(strict_types=1); namespace FireflyIII\Console\Commands; diff --git a/app/Events/UpdatedTransactionLink.php b/app/Enums/ClauseType.php similarity index 58% rename from app/Events/UpdatedTransactionLink.php rename to app/Enums/ClauseType.php index 325988a955..1897aee173 100644 --- a/app/Events/UpdatedTransactionLink.php +++ b/app/Enums/ClauseType.php @@ -1,7 +1,8 @@ link = $link; - } + public const TRANSACTION = 'transaction'; + public const WHERE = 'where'; + public const UPDATE = 'update'; } diff --git a/app/Events/StoredAccount.php b/app/Events/StoredAccount.php index eb016dd6d1..b8a77937b9 100644 --- a/app/Events/StoredAccount.php +++ b/app/Events/StoredAccount.php @@ -1,5 +1,5 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Events; use FireflyIII\Models\Account; diff --git a/app/Events/UpdatedAccount.php b/app/Events/UpdatedAccount.php index 5afa242e3e..a71e50b357 100644 --- a/app/Events/UpdatedAccount.php +++ b/app/Events/UpdatedAccount.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + + namespace FireflyIII\Events; use FireflyIII\Models\Account; diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 5bbc3ede7d..f6fdbd6244 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -136,7 +136,6 @@ class Handler extends ExceptionHandler */ public function report(Throwable $e) { - // do email the user (no telemetry) $doMailError = config('firefly.send_error_message'); if ($this->shouldntReportLocal($e) || !$doMailError) { parent::report($e); diff --git a/app/Factory/BillFactory.php b/app/Factory/BillFactory.php index 417f72660d..8bde75a9ea 100644 --- a/app/Factory/BillFactory.php +++ b/app/Factory/BillFactory.php @@ -67,6 +67,8 @@ class BillFactory 'transaction_currency_id' => $currency->id, 'amount_max' => $data['amount_max'], 'date' => $data['date'], + 'end_date' => $data['end_date'] ?? null, + 'extension_date' => $data['extension_date'] ?? null, 'repeat_freq' => $data['repeat_freq'], 'skip' => $skip, 'automatch' => true, diff --git a/app/Generator/Webhook/StandardMessageGenerator.php b/app/Generator/Webhook/StandardMessageGenerator.php index f48404cfde..a01140490e 100644 --- a/app/Generator/Webhook/StandardMessageGenerator.php +++ b/app/Generator/Webhook/StandardMessageGenerator.php @@ -1,8 +1,8 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Generator\Webhook; use FireflyIII\Exceptions\FireflyException; diff --git a/app/Handlers/Events/LDAPEventHandler.php b/app/Handlers/Events/LDAPEventHandler.php new file mode 100644 index 0000000000..84253d3c79 --- /dev/null +++ b/app/Handlers/Events/LDAPEventHandler.php @@ -0,0 +1,57 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Handlers\Events; + + +use FireflyIII\User; +use LdapRecord\Laravel\Events\Import\Imported; +use Log; + +/** + * Class LDAPEventHandler + */ +class LDAPEventHandler +{ + + /** + * @param Imported $event + */ + public function importedUser(Imported $event) + { + Log::debug(sprintf('Now in %s', __METHOD__)); + /** @var User $user */ + $user = $event->eloquent; + $alternative = User::where('email', $user->email)->where('id', '!=', $user->id)->first(); + if (null !== $alternative) { + Log::debug(sprintf('User #%d is created but user #%d already exists.', $user->id, $alternative->id)); + $alternative->objectguid = $user->objectguid; + $alternative->domain = $user->domain; + $alternative->save(); + $user->delete(); + auth()->logout(); + } + } + +} diff --git a/app/Handlers/Events/StoredAccountEventHandler.php b/app/Handlers/Events/StoredAccountEventHandler.php index 4784cfd546..59c670e135 100644 --- a/app/Handlers/Events/StoredAccountEventHandler.php +++ b/app/Handlers/Events/StoredAccountEventHandler.php @@ -1,5 +1,5 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Handlers\Events; use FireflyIII\Events\StoredAccount; diff --git a/app/Handlers/Events/UpdatedAccountEventHandler.php b/app/Handlers/Events/UpdatedAccountEventHandler.php index 23414e04f5..ec070538ff 100644 --- a/app/Handlers/Events/UpdatedAccountEventHandler.php +++ b/app/Handlers/Events/UpdatedAccountEventHandler.php @@ -1,5 +1,5 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Handlers\Events; diff --git a/app/Handlers/Events/UserEventHandler.php b/app/Handlers/Events/UserEventHandler.php index 5187c4099b..2c5faa42a8 100644 --- a/app/Handlers/Events/UserEventHandler.php +++ b/app/Handlers/Events/UserEventHandler.php @@ -29,6 +29,7 @@ use FireflyIII\Events\DetectedNewIPAddress; use FireflyIII\Events\RegisteredUser; use FireflyIII\Events\RequestedNewPassword; use FireflyIII\Events\UserChangedEmail; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Mail\ConfirmEmailChangeMail; use FireflyIII\Mail\NewIPAddressWarningMail; use FireflyIII\Mail\RegisteredUser as RegisteredUserMail; @@ -190,6 +191,7 @@ class UserEventHandler } catch (Exception $e) { // @phpstan-ignore-line Log::error($e->getMessage()); } + return true; } @@ -216,6 +218,7 @@ class UserEventHandler } catch (Exception $e) { // @phpstan-ignore-line Log::error($e->getMessage()); } + return true; } @@ -241,6 +244,7 @@ class UserEventHandler } catch (Exception $e) { // @phpstan-ignore-line Log::error($e->getMessage()); } + return true; } @@ -283,6 +287,7 @@ class UserEventHandler /** * @param Login $event + * * @throws \FireflyIII\Exceptions\FireflyException */ public function storeUserIPAddress(Login $event): void @@ -290,9 +295,16 @@ class UserEventHandler /** @var User $user */ $user = $event->user; /** @var array $preference */ - $preference = app('preferences')->getForUser($user, 'login_ip_history', [])->data; - $inArray = false; - $ip = request()->ip(); + try { + $preference = app('preferences')->getForUser($user, 'login_ip_history', [])->data; + } catch (FireflyException $e) { + // don't care. + Log::error($e->getMessage()); + + return; + } + $inArray = false; + $ip = request()->ip(); Log::debug(sprintf('User logging in from IP address %s', $ip)); // update array if in array diff --git a/app/Helpers/Help/Help.php b/app/Helpers/Help/Help.php index 26a0dba6e8..163995d6a5 100644 --- a/app/Helpers/Help/Help.php +++ b/app/Helpers/Help/Help.php @@ -95,7 +95,7 @@ class Help implements HelpInterface if ('' !== $content) { Log::debug('Content is longer than zero. Expect something.'); $converter = new CommonMarkConverter(); - $content = $converter->convertToHtml($content); + $content = (string) $converter->convertToHtml($content); } return $content; diff --git a/app/Helpers/Webhook/Sha3SignatureGenerator.php b/app/Helpers/Webhook/Sha3SignatureGenerator.php index aa5b7e1ce6..7ef80dedbd 100644 --- a/app/Helpers/Webhook/Sha3SignatureGenerator.php +++ b/app/Helpers/Webhook/Sha3SignatureGenerator.php @@ -23,8 +23,11 @@ declare(strict_types=1); namespace FireflyIII\Helpers\Webhook; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\WebhookMessage; use JsonException; +use Log; + /** * Class Sha3SignatureGenerator @@ -41,8 +44,11 @@ class Sha3SignatureGenerator implements SignatureGeneratorInterface try { $json = json_encode($message->message, JSON_THROW_ON_ERROR); } catch (JsonException $e) { -// See reference nr. 87 - return sprintf('t=1,v%d=err-invalid-signature', $this->getVersion()); + Log::error('Could not generate hash.'); + Log::error(sprintf('JSON value: %s', $message->message)); + Log::error($e->getMessage()); + Log::error($e->getTraceAsString()); + throw new FireflyException('Could not generate JSON for SHA3 hash.', $e); } // signature v1 is generated using the following structure: diff --git a/app/Http/Controllers/Admin/TelemetryController.php b/app/Http/Controllers/Admin/TelemetryController.php deleted file mode 100644 index 470b3a710f..0000000000 --- a/app/Http/Controllers/Admin/TelemetryController.php +++ /dev/null @@ -1,66 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers\Admin; - -use FireflyIII\Http\Controllers\Controller; - -/** - * Class TelemetryController - */ -class TelemetryController extends Controller -{ - /** - * TelemetryController constructor. - */ - public function __construct() - { - if (false === config('firefly.feature_flags.telemetry')) { - die('Telemetry is disabled.'); - } - parent::__construct(); - - $this->middleware( - function ($request, $next) { - app('view')->share('title', (string)trans('firefly.administration')); - app('view')->share('mainTitleIcon', 'fa-hand-spock-o'); - - return $next($request); - } - ); - } - - /** - * Index - */ - public function index() - { - app('view')->share('subTitleIcon', 'fa-eye'); - app('view')->share('subTitle', (string)trans('firefly.telemetry_admin_index')); - $version = config('firefly.version'); - $enabled = config('firefly.send_telemetry', false) && config('firefly.feature_flags.telemetry'); - return prefixView('admin.telemetry.index', compact('version', 'enabled')); - } - -} diff --git a/app/Http/Controllers/Auth/ForgotPasswordController.php b/app/Http/Controllers/Auth/ForgotPasswordController.php index 24c302777a..b816187321 100644 --- a/app/Http/Controllers/Auth/ForgotPasswordController.php +++ b/app/Http/Controllers/Auth/ForgotPasswordController.php @@ -30,7 +30,6 @@ use Illuminate\Contracts\View\Factory; use Illuminate\Foundation\Auth\SendsPasswordResetEmails; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Password; use Illuminate\View\View; use Log; @@ -93,15 +92,12 @@ class ForgotPasswordController extends Controller // We will send the password reset link to this user. Once we have attempted // to send the link, we will examine the response then see the message we // need to show to the user. Finally, we'll send out a proper response. - $response = $this->broker()->sendResetLink( - $request->only('email') - ); + $this->broker()->sendResetLink($request->only('email')); - if ($response === Password::RESET_LINK_SENT) { - return back()->with('status', trans($response)); - } + // always send the same response: + $response = trans('firefly.forgot_password_response'); - return back()->withErrors(['email' => trans($response)]); + return back()->with('status', trans($response)); } /** diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 13afb3a466..27a8cb866d 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -29,6 +29,7 @@ use FireflyIII\Http\Controllers\Controller; use FireflyIII\Providers\RouteServiceProvider; use Illuminate\Contracts\View\Factory; use Illuminate\Foundation\Auth\AuthenticatesUsers; +use Illuminate\Foundation\Auth\ThrottlesLogins; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; @@ -47,7 +48,7 @@ use Log; */ class LoginController extends Controller { - use AuthenticatesUsers; + use AuthenticatesUsers, ThrottlesLogins; /** * Where to redirect users after login. diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index aac62aa510..22e49777ee 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -69,6 +69,7 @@ class RegisterController extends Controller if ('eloquent' !== $loginProvider || 'web' !== $authGuard) { throw new FireflyException('Using external identity provider. Cannot continue.'); } + } /** @@ -84,21 +85,19 @@ class RegisterController extends Controller { // is allowed to? $allowRegistration = true; - $loginProvider = config('firefly.login_provider'); $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; $userCount = User::count(); - if (true === $singleUserMode && $userCount > 0 && 'eloquent' === $loginProvider) { + $guard = config('auth.defaults.guard'); + if (true === $singleUserMode && $userCount > 0 && 'ldap' !== $guard) { $allowRegistration = false; } - if ('eloquent' !== $loginProvider) { + if ('ldap' === $guard) { $allowRegistration = false; } if (false === $allowRegistration) { - $message = 'Registration is currently not available.'; - - return prefixView('error', compact('message')); + throw new FireflyException('Registration is currently not available :('); } $this->validator($request->all())->validate(); @@ -126,21 +125,21 @@ class RegisterController extends Controller public function showRegistrationForm(Request $request) { $allowRegistration = true; - $loginProvider = config('firefly.login_provider'); $isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site'))->data; $singleUserMode = app('fireflyconfig')->get('single_user_mode', config('firefly.configuration.single_user_mode'))->data; $userCount = User::count(); $pageTitle = (string)trans('firefly.register_page_title'); + $guard = config('auth.defaults.guard'); if (true === $isDemoSite) { $allowRegistration = false; } - if (true === $singleUserMode && $userCount > 0 && 'eloquent' === $loginProvider) { + if (true === $singleUserMode && $userCount > 0 && 'ldap' !== $guard) { $allowRegistration = false; } - if ('eloquent' !== $loginProvider) { + if ('ldap' === $guard) { $allowRegistration = false; } diff --git a/app/Http/Controllers/Auth/ResetPasswordController.php b/app/Http/Controllers/Auth/ResetPasswordController.php index cfef605eb6..0fdf8c8fb3 100644 --- a/app/Http/Controllers/Auth/ResetPasswordController.php +++ b/app/Http/Controllers/Auth/ResetPasswordController.php @@ -87,7 +87,6 @@ class ResetPasswordController extends Controller return prefixView('error', compact('message')); } - $rules = [ 'token' => 'required', 'email' => 'required|email', diff --git a/app/Http/Controllers/Bill/IndexController.php b/app/Http/Controllers/Bill/IndexController.php index 7f7d472c3e..ba627833e1 100644 --- a/app/Http/Controllers/Bill/IndexController.php +++ b/app/Http/Controllers/Bill/IndexController.php @@ -107,18 +107,18 @@ class IndexController extends Controller 'object_group_title' => $array['object_group_title'], 'bills' => [], ]; - - // expected today? default: - $array['next_expected_match_diff'] = trans('firefly.not_expected_period'); - $nextExpectedMatch = new Carbon($array['next_expected_match']); - if ($nextExpectedMatch->isToday()) { - $array['next_expected_match_diff'] = trans('firefly.today'); - } - $current = $array['pay_dates'][0] ?? null; - if (null !== $current && !$nextExpectedMatch->isToday()) { - $currentExpectedMatch = Carbon::createFromFormat('Y-m-d\TH:i:sP', $current); - $array['next_expected_match_diff'] = $currentExpectedMatch->diffForHumans(today(), Carbon::DIFF_RELATIVE_TO_NOW); - } +// var_dump($array);exit; +// // expected today? default: +// $array['next_expected_match_diff'] = trans('firefly.not_expected_period'); +// $nextExpectedMatch = new Carbon($array['next_expected_match']); +// if ($nextExpectedMatch->isToday()) { +// $array['next_expected_match_diff'] = trans('firefly.today'); +// } +// $current = $array['pay_dates'][0] ?? null; +// if (null !== $current && !$nextExpectedMatch->isToday()) { +// $currentExpectedMatch = Carbon::createFromFormat('Y-m-d\TH:i:sP', $current); +// $array['next_expected_match_diff'] = $currentExpectedMatch->diffForHumans(today(), Carbon::DIFF_RELATIVE_TO_NOW); +// } $currency = $bill->transactionCurrency ?? $defaultCurrency; $array['currency_id'] = $currency->id; diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php index d7a6081a7c..acc35ec5bf 100644 --- a/app/Http/Controllers/DebugController.php +++ b/app/Http/Controllers/DebugController.php @@ -150,7 +150,6 @@ class DebugController extends Controller $foundDBversion = FireflyConfig::get('db_version', 1)->data; // some new vars. - $telemetry = true === config('firefly.send_telemetry') && true === config('firefly.feature_flags.telemetry'); $defaultLanguage = (string)config('firefly.default_language'); $defaultLocale = (string)config('firefly.default_locale'); $userLanguage = app('steam')->getLanguage(); @@ -218,7 +217,6 @@ class DebugController extends Controller 'logContent', 'cacheDriver', 'trustedProxies', - 'telemetry', 'userLanguage', 'userLocale', 'defaultLanguage', diff --git a/app/Http/Controllers/PreferencesController.php b/app/Http/Controllers/PreferencesController.php index 30fbc5ea6b..be5de919b9 100644 --- a/app/Http/Controllers/PreferencesController.php +++ b/app/Http/Controllers/PreferencesController.php @@ -166,9 +166,13 @@ class PreferencesController extends Controller // custom fiscal year $customFiscalYear = 1 === (int)$request->get('customFiscalYear'); - $fiscalYearStart = date('m-d', strtotime((string)$request->get('fiscalYearStart'))); - app('preferences')->set('customFiscalYear', $customFiscalYear); - app('preferences')->set('fiscalYearStart', $fiscalYearStart); + $string = strtotime((string)$request->get('fiscalYearStart')); + if(false !== $string) { + $fiscalYearStart = date('m-d', $string); + app('preferences')->set('customFiscalYear', $customFiscalYear); + app('preferences')->set('fiscalYearStart', $fiscalYearStart); + } + // save page size: app('preferences')->set('listPageSize', 50); diff --git a/app/Http/Controllers/Recurring/CreateController.php b/app/Http/Controllers/Recurring/CreateController.php index d0455c2d48..08a995118b 100644 --- a/app/Http/Controllers/Recurring/CreateController.php +++ b/app/Http/Controllers/Recurring/CreateController.php @@ -30,6 +30,7 @@ use FireflyIII\Http\Requests\RecurrenceFormRequest; use FireflyIII\Models\RecurrenceRepetition; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use Illuminate\Contracts\View\Factory; @@ -47,6 +48,7 @@ class CreateController extends Controller private AttachmentHelperInterface $attachments; private BudgetRepositoryInterface $budgetRepos; private RecurringRepositoryInterface $recurring; + private BillRepositoryInterface $billRepository; /** * CreateController constructor. @@ -64,9 +66,10 @@ class CreateController extends Controller app('view')->share('title', (string)trans('firefly.recurrences')); app('view')->share('subTitle', (string)trans('firefly.create_new_recurrence')); - $this->recurring = app(RecurringRepositoryInterface::class); - $this->budgetRepos = app(BudgetRepositoryInterface::class); - $this->attachments = app(AttachmentHelperInterface::class); + $this->recurring = app(RecurringRepositoryInterface::class); + $this->budgetRepos = app(BudgetRepositoryInterface::class); + $this->attachments = app(AttachmentHelperInterface::class); + $this->billRepository = app(BillRepositoryInterface::class); return $next($request); } @@ -83,6 +86,7 @@ class CreateController extends Controller public function create(Request $request) { $budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); + $bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills()); $defaultCurrency = app('amount')->getDefaultCurrency(); $tomorrow = today(config('app.timezone')); $oldRepetitionType = $request->old('repetition_type'); @@ -115,7 +119,7 @@ class CreateController extends Controller return prefixView( 'recurring.create', - compact('tomorrow', 'oldRepetitionType', 'weekendResponses', 'preFilled', 'repetitionEnds', 'defaultCurrency', 'budgets') + compact('tomorrow', 'oldRepetitionType', 'bills', 'weekendResponses', 'preFilled', 'repetitionEnds', 'defaultCurrency', 'budgets') ); } @@ -155,11 +159,12 @@ class CreateController extends Controller $type = strtolower($journal->transactionType->type); /** @var Transaction $source */ - $source = $journal->transactions()->where('amount', '<', 0)->first(); + $source = $journal->transactions()->where('amount', '<', 0)->first(); /** @var Transaction $dest */ $dest = $journal->transactions()->where('amount', '>', 0)->first(); $category = $journal->categories()->first() ? $journal->categories()->first()->name : ''; $budget = $journal->budgets()->first() ? $journal->budgets()->first()->id : 0; + $bill = $journal->bill ? $journal->bill->id : 0; $hasOldInput = null !== $request->old('_token'); // flash some data $preFilled = []; if (true === $hasOldInput) { @@ -178,6 +183,7 @@ class CreateController extends Controller 'transaction_type' => $request->old('transaction_type'), 'category' => $request->old('category'), 'budget_id' => $request->old('budget_id'), + 'bill_id' => $request->old('bill_id'), 'active' => (bool)$request->old('active'), 'apply_rules' => (bool)$request->old('apply_rules'), ]; @@ -198,6 +204,7 @@ class CreateController extends Controller 'transaction_type' => $type, 'category' => $category, 'budget_id' => $budget, + 'bill_id' => $bill, 'active' => true, 'apply_rules' => true, ]; @@ -243,7 +250,7 @@ class CreateController extends Controller } if (count($this->attachments->getMessages()->get('attachments')) > 0) { - $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); } $redirect = redirect($this->getPreviousUri('recurring.create.uri')); diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index 910b0046c7..432d4b5eb2 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -29,6 +29,7 @@ use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\RecurrenceFormRequest; use FireflyIII\Models\Recurrence; use FireflyIII\Models\RecurrenceRepetition; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; use FireflyIII\Transformers\RecurrenceTransformer; @@ -48,6 +49,7 @@ class EditController extends Controller private AttachmentHelperInterface $attachments; private BudgetRepositoryInterface $budgetRepos; private RecurringRepositoryInterface $recurring; + private BillRepositoryInterface $billRepository; /** * EditController constructor. @@ -65,9 +67,10 @@ class EditController extends Controller app('view')->share('title', (string)trans('firefly.recurrences')); app('view')->share('subTitle', (string)trans('firefly.recurrences')); - $this->recurring = app(RecurringRepositoryInterface::class); - $this->budgetRepos = app(BudgetRepositoryInterface::class); - $this->attachments = app(AttachmentHelperInterface::class); + $this->recurring = app(RecurringRepositoryInterface::class); + $this->budgetRepos = app(BudgetRepositoryInterface::class); + $this->attachments = app(AttachmentHelperInterface::class); + $this->billRepository = app(BillRepositoryInterface::class); return $next($request); } @@ -86,7 +89,7 @@ class EditController extends Controller */ public function edit(Request $request, Recurrence $recurrence) { -// See reference nr. 69 + // 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!'); @@ -98,6 +101,7 @@ class EditController extends Controller $array = $transformer->transform($recurrence); $budgets = app('expandedform')->makeSelectListWithEmpty($this->budgetRepos->getActiveBudgets()); + $bills = app('expandedform')->makeSelectListWithEmpty($this->billRepository->getActiveBills()); /** @var RecurrenceRepetition $repetition */ $repetition = $recurrence->recurrenceRepetitions()->first(); @@ -146,7 +150,10 @@ class EditController extends Controller return prefixView( 'recurring.edit', - compact('recurrence', 'array', 'weekendResponses', 'budgets', 'preFilled', 'currentRepType', 'repetitionEnd', 'repetitionEnds') + compact( + 'recurrence', 'array', 'bills', + 'weekendResponses', 'budgets', 'preFilled', 'currentRepType', 'repetitionEnd', 'repetitionEnds' + ) ); } diff --git a/app/Http/Middleware/InterestingMessage.php b/app/Http/Middleware/InterestingMessage.php index 0d199782dc..abe5adf499 100644 --- a/app/Http/Middleware/InterestingMessage.php +++ b/app/Http/Middleware/InterestingMessage.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Middleware; use Closure; use FireflyIII\Models\Account; +use FireflyIII\Models\Bill; use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionJournal; use Illuminate\Http\Request; @@ -58,6 +59,10 @@ class InterestingMessage Preferences::mark(); $this->handleAccountMessage($request); } + if ($this->billMessage($request)) { + Preferences::mark(); + $this->handleBillMessage($request); + } return $next($request); } @@ -88,11 +93,12 @@ class InterestingMessage /** * @param Request $request */ - private function handleAccountMessage(Request $request): void { + private function handleAccountMessage(Request $request): void + { // get parameters from request. $accountId = $request->get('account_id'); - $message = $request->get('message'); + $message = $request->get('message'); /** @var Account $account */ $account = auth()->user()->accounts()->withTrashed()->find($accountId); @@ -103,10 +109,38 @@ class InterestingMessage if ('deleted' === $message) { session()->flash('success', (string)trans('firefly.account_deleted', ['name' => $account->name])); } - if('created' === $message) { + if ('created' === $message) { session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name])); } + if ('updated' === $message) { + session()->flash('success', (string)trans('firefly.updated_account', ['name' => $account->name])); + } } + + /** + * @param Request $request + */ + private function handleBillMessage(Request $request): void + { + + // get parameters from request. + $billId = $request->get('bill_id'); + $message = $request->get('message'); + + /** @var Bill $bill */ + $bill = auth()->user()->bills()->withTrashed()->find($billId); + + if (null === $bill) { + return; + } + if ('deleted' === $message) { + session()->flash('success', (string)trans('firefly.deleted_bill', ['name' => $bill->name])); + } + if ('created' === $message) { + session()->flash('success', (string)trans('firefly.stored_new_bill', ['name' => $bill->name])); + } + } + /** * @param Request $request */ @@ -162,4 +196,18 @@ class InterestingMessage return null !== $accountId && null !== $message; } + + /** + * @param Request $request + * + * @return bool + */ + private function billMessage(Request $request): bool + { + // get parameters from request. + $billId = $request->get('bill_id'); + $message = $request->get('message'); + + return null !== $billId && null !== $message; + } } diff --git a/app/Http/Middleware/StartFireflySession.php b/app/Http/Middleware/StartFireflySession.php index 88e1d10ff9..e2ae331a9a 100644 --- a/app/Http/Middleware/StartFireflySession.php +++ b/app/Http/Middleware/StartFireflySession.php @@ -46,11 +46,13 @@ class StartFireflySession extends StartSession $isDeletePage = strpos($uri, 'delete'); $isLoginPage = strpos($uri, '/login'); $isJsonPage = strpos($uri, '/json'); + $isView = strpos($uri, '/attachments/view'); // also stop remembering "delete" URL's. if (false === $isScriptPage && false === $isDeletePage && false === $isLoginPage && false === $isJsonPage + && false === $isView && 'GET' === $request->method() && !$request->ajax()) { $session->setPreviousUrl($uri); diff --git a/app/Http/Requests/RecurrenceFormRequest.php b/app/Http/Requests/RecurrenceFormRequest.php index 1fd8aad43c..e43c1b3c44 100644 --- a/app/Http/Requests/RecurrenceFormRequest.php +++ b/app/Http/Requests/RecurrenceFormRequest.php @@ -78,6 +78,8 @@ class RecurrenceFormRequest extends FormRequest 'foreign_currency_code' => null, 'budget_id' => $this->integer('budget_id'), 'budget_name' => null, + 'bill_id' => $this->integer('bill_id'), + 'bill_name' => null, 'category_id' => null, 'category_name' => $this->string('category'), 'tags' => '' !== $this->string('tags') ? explode(',', $this->string('tags')) : [], @@ -109,7 +111,7 @@ class RecurrenceFormRequest extends FormRequest // fill in source and destination account data switch ($this->string('transaction_type')) { default: - throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); + throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); case 'withdrawal': $return['transactions'][0]['source_id'] = $this->integer('source_id'); $return['transactions'][0]['destination_id'] = $this->integer('withdrawal_destination_id'); @@ -162,11 +164,11 @@ class RecurrenceFormRequest extends FormRequest $return['type'] = substr($value, 0, 6); $return['moment'] = substr($value, 7); } - if (0 === strpos($value, 'monthly')) { + if (str_starts_with($value, 'monthly')) { $return['type'] = substr($value, 0, 7); $return['moment'] = substr($value, 8); } - if (0 === strpos($value, 'ndom')) { + if (str_starts_with($value, 'ndom')) { $return['type'] = substr($value, 0, 4); $return['moment'] = substr($value, 5); } @@ -213,6 +215,7 @@ class RecurrenceFormRequest extends FormRequest // optional fields: 'budget_id' => 'mustExist:budgets,id|belongsToUser:budgets,id|nullable', + 'bill_id' => 'mustExist:bills,id|belongsToUser:bills,id|nullable', 'category' => 'between:1,255|nullable', 'tags' => 'between:1,255|nullable', ]; @@ -251,7 +254,7 @@ class RecurrenceFormRequest extends FormRequest break; default: - throw new FireflyException(sprintf('Cannot handle transaction type of type "%s"', $this->string('transaction_type'))); + throw new FireflyException(sprintf('Cannot handle transaction type of type "%s"', $this->string('transaction_type'))); } // update some rules in case the user is editing a post: @@ -304,11 +307,11 @@ class RecurrenceFormRequest extends FormRequest $sourceId = null; $destinationId = null; -// See reference nr. 45 + // See reference nr. 45 switch ($this->string('transaction_type')) { default: - throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); + throw new FireflyException(sprintf('Cannot handle transaction type "%s"', $this->string('transaction_type'))); case 'withdrawal': $sourceId = (int)$data['source_id']; $destinationId = (int)$data['withdrawal_destination_id']; diff --git a/app/Ldap/AttributeHandler.php b/app/Ldap/AttributeHandler.php index 99f8f75c4b..bdde31ef88 100644 --- a/app/Ldap/AttributeHandler.php +++ b/app/Ldap/AttributeHandler.php @@ -1,5 +1,5 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Ldap; use FireflyIII\User as DatabaseUser; diff --git a/app/Models/Bill.php b/app/Models/Bill.php index e1e924cd83..34fd41804d 100644 --- a/app/Models/Bill.php +++ b/app/Models/Bill.php @@ -110,6 +110,8 @@ class Bill extends Model 'updated_at' => 'datetime', 'deleted_at' => 'datetime', 'date' => 'date', + 'end_date' => 'date', + 'extension_date' => 'date', 'skip' => 'int', 'automatch' => 'boolean', 'active' => 'boolean', @@ -120,7 +122,7 @@ class Bill extends Model /** @var array Fields that can be filled */ protected $fillable = ['name', 'match', 'amount_min', 'user_id', 'amount_max', 'date', 'repeat_freq', 'skip', - 'automatch', 'active', 'transaction_currency_id']; + 'automatch', 'active', 'transaction_currency_id', 'end_date', 'extension_date']; /** @var array Hidden from view */ protected $hidden = ['amount_min_encrypted', 'amount_max_encrypted', 'name_encrypted', 'match_encrypted']; diff --git a/app/Models/Telemetry.php b/app/Models/Telemetry.php deleted file mode 100644 index e9ebd9b239..0000000000 --- a/app/Models/Telemetry.php +++ /dev/null @@ -1,75 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Models; -use Eloquent; -use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Carbon; - -/** - * FireflyIII\Models\Telemetry - * - * @property int $id - * @property Carbon|null $created_at - * @property Carbon|null $updated_at - * @property Carbon|null $submitted - * @property int|null $user_id - * @property string $installation_id - * @property string $type - * @property string $key - * @property array $value - * @method static Builder|Telemetry newModelQuery() - * @method static Builder|Telemetry newQuery() - * @method static Builder|Telemetry query() - * @method static Builder|Telemetry whereCreatedAt($value) - * @method static Builder|Telemetry whereId($value) - * @method static Builder|Telemetry whereInstallationId($value) - * @method static Builder|Telemetry whereKey($value) - * @method static Builder|Telemetry whereSubmitted($value) - * @method static Builder|Telemetry whereType($value) - * @method static Builder|Telemetry whereUpdatedAt($value) - * @method static Builder|Telemetry whereUserId($value) - * @method static Builder|Telemetry whereValue($value) - * @mixin Eloquent - */ -class Telemetry extends Model -{ - /** @var string */ - protected $table = 'telemetry'; - - /** @var array */ - protected $fillable = ['installation_id', 'submitted', 'user_id', 'key', 'type', 'value']; - /** - * The attributes that should be cast to native types. - * - * @var array - */ - protected $casts - = [ - 'submitted' => 'datetime', - 'value' => 'array', - ]; - -} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 9db77aeb27..02139dd890 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -44,6 +44,7 @@ use Illuminate\Auth\Events\Login; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Laravel\Passport\Client; use Laravel\Passport\Events\AccessTokenCreated; +use LdapRecord\Laravel\Events\Import\Imported; use Log; use Mail; use Request; @@ -130,6 +131,11 @@ class EventServiceProvider extends ServiceProvider UpdatedAccount::class => [ 'FireflyIII\Handlers\Events\UpdatedAccountEventHandler@recalculateCredit', ], + + // LDAP related events: + Imported::class => [ + 'FireflyIII\Handlers\Events\LDAPEventHandler@importedUser', + ], ]; /** diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php index 5430e9c5aa..fcd2200ca6 100644 --- a/app/Providers/FireflyServiceProvider.php +++ b/app/Providers/FireflyServiceProvider.php @@ -64,7 +64,6 @@ use FireflyIII\Support\Form\RuleForm; use FireflyIII\Support\Navigation; use FireflyIII\Support\Preferences; use FireflyIII\Support\Steam; -use FireflyIII\Support\Telemetry; use FireflyIII\TransactionRules\Engine\RuleEngineInterface; use FireflyIII\TransactionRules\Engine\SearchRuleEngine; use FireflyIII\Validation\FireflyValidator; @@ -165,13 +164,6 @@ class FireflyServiceProvider extends ServiceProvider } ); - $this->app->bind( - 'telemetry', - static function () { - return new Telemetry; - } - ); - // chart generator: $this->app->bind(GeneratorInterface::class, ChartJsGenerator::class); // other generators diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index ff753aeba2..f36ce1636e 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -149,21 +149,17 @@ class AccountRepository implements AccountRepositoryInterface } Log::debug(sprintf('Searching for account named "%s" (of user #%d) of the following type(s)', $name, $this->user->id), ['types' => $types]); - $accounts = $query->get(['accounts.*']); - - // See reference nr. 10 - + $query->where('accounts.name', $name); /** @var Account $account */ - foreach ($accounts as $account) { - if ($account->name === $name) { - Log::debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id)); + $account = $query->first(['accounts.*']); + if (null === $account) { + Log::debug(sprintf('There is no account with name "%s" of types', $name), $types); - return $account; - } + return null; } - Log::debug(sprintf('There is no account with name "%s" of types', $name), $types); + Log::debug(sprintf('Found #%d (%s) with type id %d', $account->id, $account->name, $account->account_type_id)); - return null; + return $account; } /** diff --git a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php index c74adb0db1..1f93291dde 100644 --- a/app/Repositories/Budget/BudgetLimitRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetLimitRepositoryInterface.php @@ -72,7 +72,7 @@ interface BudgetLimitRepositoryInterface public function find(Budget $budget, TransactionCurrency $currency, Carbon $start, Carbon $end): ?BudgetLimit; /** -* See reference nr. 11 + * See reference nr. 11 * * @param Carbon|null $start * @param Carbon|null $end diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index ea595eeff0..0bf2fc4373 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -99,8 +99,6 @@ interface JournalRepositoryInterface public function getLast(): ?TransactionJournal; /** - * See reference nr. 4 - * * @param TransactionJournalLink $link * * @return string diff --git a/app/Repositories/LinkType/LinkTypeRepository.php b/app/Repositories/LinkType/LinkTypeRepository.php index f7e260e4be..c2196efa41 100644 --- a/app/Repositories/LinkType/LinkTypeRepository.php +++ b/app/Repositories/LinkType/LinkTypeRepository.php @@ -24,8 +24,6 @@ namespace FireflyIII\Repositories\LinkType; use Exception; use FireflyIII\Events\DestroyedTransactionLink; -use FireflyIII\Events\StoredTransactionLink; -use FireflyIII\Events\UpdatedTransactionLink; use FireflyIII\Models\LinkType; use FireflyIII\Models\Note; use FireflyIII\Models\TransactionJournal; @@ -281,8 +279,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface // make note in noteable: $this->setNoteText($link, (string)$information['notes']); - event(new StoredTransactionLink($link)); - return $link; } @@ -352,8 +348,6 @@ class LinkTypeRepository implements LinkTypeRepositoryInterface $this->setNoteText($journalLink, $data['notes']); } - event(new UpdatedTransactionLink($journalLink)); - return $journalLink; } diff --git a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php index 5235d66d27..b608fd8eb2 100644 --- a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php +++ b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Repositories\PiggyBank; + use Carbon\Carbon; use Exception; use FireflyIII\Exceptions\FireflyException; @@ -90,7 +91,7 @@ trait ModifiesPiggyBanks $leftOnAccount = $this->leftOnAccount($piggyBank, today(config('app.timezone'))); $savedSoFar = (string)$this->getRepetition($piggyBank)->currentamount; $leftToSave = bcsub($piggyBank->targetamount, $savedSoFar); - $maxAmount = (string)min(round((float)$leftOnAccount, 12), round((float)$leftToSave, 12)); + $maxAmount = 1 === bccomp($leftOnAccount, $leftToSave) ? $leftToSave : $leftOnAccount; $compare = bccomp($amount, $maxAmount); $result = $compare <= 0; @@ -304,7 +305,7 @@ trait ModifiesPiggyBanks $piggyBank = PiggyBank::create($piggyData); } catch (QueryException $e) { Log::error(sprintf('Could not store piggy bank: %s', $e->getMessage()), $piggyData); - throw new FireflyException('400005: Could not store new piggy bank.',0,$e); + throw new FireflyException('400005: Could not store new piggy bank.', 0, $e); } // reset order then set order: @@ -315,7 +316,7 @@ trait ModifiesPiggyBanks // repetition is auto created. $repetition = $this->getRepetition($piggyBank); - if (null !== $repetition && array_key_exists('current_amount',$data) && '' !== $data['current_amount']) { + if (null !== $repetition && array_key_exists('current_amount', $data) && '' !== $data['current_amount']) { $repetition->currentamount = $data['current_amount']; $repetition->save(); } diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index be1ae9e6fc..bd05564f1b 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -61,6 +61,7 @@ class TagRepository implements TagRepositoryInterface */ public function destroy(Tag $tag): bool { + DB::table('tag_transaction_journal')->where('tag_id', $tag->id)->delete(); $tag->transactionJournals()->sync([]); $tag->delete(); diff --git a/app/Rules/IsDateOrTime.php b/app/Rules/IsDateOrTime.php index 23af02ac1d..44f47a032f 100644 --- a/app/Rules/IsDateOrTime.php +++ b/app/Rules/IsDateOrTime.php @@ -26,6 +26,7 @@ namespace FireflyIII\Rules; use Carbon\Carbon; use Carbon\Exceptions\InvalidDateException; +use Carbon\Exceptions\InvalidFormatException; use Illuminate\Contracts\Validation\Rule; use Log; @@ -67,6 +68,10 @@ class IsDateOrTime implements Rule } catch (InvalidDateException $e) { Log::error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage())); + return false; + } catch(InvalidFormatException $e) { + Log::error(sprintf('"%s" is of an invalid format: %s', $value, $e->getMessage())); + return false; } @@ -78,6 +83,10 @@ class IsDateOrTime implements Rule } catch (InvalidDateException $e) { Log::error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage())); + return false; + } catch(InvalidFormatException $e) { + Log::error(sprintf('"%s" is of an invalid format: %s', $value, $e->getMessage())); + return false; } diff --git a/app/Rules/IsValidBulkClause.php b/app/Rules/IsValidBulkClause.php new file mode 100644 index 0000000000..d10b78c0dd --- /dev/null +++ b/app/Rules/IsValidBulkClause.php @@ -0,0 +1,116 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Rules; + +use Illuminate\Contracts\Validation\Rule; +use Illuminate\Support\Facades\Validator; +use JsonException; + +/** + * Class IsValidBulkClause + */ +class IsValidBulkClause implements Rule +{ + private array $rules; + private string $error; + + /** + * @param string $type + */ + public function __construct(string $type) + { + $this->rules = config(sprintf('bulk.%s', $type)); + $this->error = (string)trans('firefly.belongs_user'); + } + + /** + * @param string $attribute + * @param mixed $value + * + * @return bool + */ + public function passes($attribute, $value): bool + { + $result = $this->basicValidation((string)$value); + if (false === $result) { + return false; + } + return true; + } + + /** + * @return string + */ + public function message(): string + { + return $this->error; + } + + /** + * Does basic rule based validation. + * + * @return bool + */ + private function basicValidation(string $value): bool + { + try { + $array = json_decode($value, true, 8, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + $this->error = (string)trans('validation.json'); + + return false; + } + $clauses = ['where', 'update']; + foreach ($clauses as $clause) { + if (!array_key_exists($clause, $array)) { + $this->error = (string)trans(sprintf('validation.missing_%s', $clause)); + + return false; + } + /** + * @var string $arrayKey + * @var mixed $arrayValue + */ + foreach ($array[$clause] as $arrayKey => $arrayValue) { + if (!array_key_exists($arrayKey, $this->rules[$clause])) { + $this->error = (string)trans(sprintf('validation.invalid_%s_key', $clause)); + + return false; + } + // validate! + $validator = Validator::make(['value' => $arrayValue], [ + 'value' => $this->rules[$clause][$arrayKey], + ]); + if ($validator->fails()) { + $this->error = sprintf('%s: %s: %s',$clause, $arrayKey, join(', ', ($validator->errors()->get('value')))); + + return false; + } + } + } + + return true; + } +} diff --git a/app/Services/Internal/Support/CreditRecalculateService.php b/app/Services/Internal/Support/CreditRecalculateService.php index cbe7a735e9..7c50885384 100644 --- a/app/Services/Internal/Support/CreditRecalculateService.php +++ b/app/Services/Internal/Support/CreditRecalculateService.php @@ -1,5 +1,5 @@ . */ +declare(strict_types=1); + + namespace FireflyIII\Services\Internal\Support; diff --git a/app/Services/Internal/Support/JournalServiceTrait.php b/app/Services/Internal/Support/JournalServiceTrait.php index 9af842ec1c..ce621bc415 100644 --- a/app/Services/Internal/Support/JournalServiceTrait.php +++ b/app/Services/Internal/Support/JournalServiceTrait.php @@ -74,7 +74,7 @@ trait JournalServiceTrait // and now try to find it, based on the type of transaction. $message = 'Based on the fact that the transaction is a %s, the %s account should be in: %s. Direction is %s.'; - Log::debug(sprintf($message, $transactionType, $direction, implode(', ', $expectedTypes[$transactionType]), $direction)); + Log::debug(sprintf($message, $transactionType, $direction, implode(', ', $expectedTypes[$transactionType] ?? ['UNKNOWN']), $direction)); $result = $this->findAccountById($data, $expectedTypes[$transactionType]); $result = $this->findAccountByName($result, $data, $expectedTypes[$transactionType]); diff --git a/app/Services/Internal/Support/RecurringTransactionTrait.php b/app/Services/Internal/Support/RecurringTransactionTrait.php index 57c4fa56ab..433111735f 100644 --- a/app/Services/Internal/Support/RecurringTransactionTrait.php +++ b/app/Services/Internal/Support/RecurringTransactionTrait.php @@ -26,6 +26,7 @@ namespace FireflyIII\Services\Internal\Support; use Exception; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\AccountFactory; +use FireflyIII\Factory\BillFactory; use FireflyIII\Factory\BudgetFactory; use FireflyIII\Factory\CategoryFactory; use FireflyIII\Factory\PiggyBankFactory; @@ -136,16 +137,16 @@ trait RecurringTransactionTrait $validator->setUser($recurrence->user); $validator->setTransactionType($recurrence->transactionType->type); if (!$validator->validateSource($source->id, null, null)) { - throw new FireflyException(sprintf('Source invalid: %s', $validator->sourceError)); + throw new FireflyException(sprintf('Source invalid: %s', $validator->sourceError)); } if (!$validator->validateDestination($destination->id, null, null)) { - throw new FireflyException(sprintf('Destination invalid: %s', $validator->destError)); + throw new FireflyException(sprintf('Destination invalid: %s', $validator->destError)); } if (array_key_exists('foreign_amount', $array) && '' === (string)$array['foreign_amount']) { unset($array['foreign_amount']); } -// See reference nr. 100 + // See reference nr. 100 $transaction = new RecurrenceTransaction( [ 'recurrence_id' => $recurrence->id, @@ -163,6 +164,9 @@ trait RecurringTransactionTrait if (array_key_exists('budget_id', $array)) { $this->setBudget($transaction, (int)$array['budget_id']); } + if (array_key_exists('bill_id', $array)) { + $this->setBill($transaction, (int)$array['bill_id']); + } if (array_key_exists('category_id', $array)) { $this->setCategory($transaction, (int)$array['category_id']); } @@ -254,6 +258,29 @@ trait RecurringTransactionTrait $meta->save(); } + /** + * @param RecurrenceTransaction $transaction + * @param int $billId + */ + private function setBill(RecurrenceTransaction $transaction, int $billId): void + { + $billFactory = app(BillFactory::class); + $billFactory->setUser($transaction->recurrence->user); + $bill = $billFactory->find($billId, null); + if (null === $bill) { + return; + } + + $meta = $transaction->recurrenceTransactionMeta()->where('name', 'bill_id')->first(); + if (null === $meta) { + $meta = new RecurrenceTransactionMeta; + $meta->rt_id = $transaction->id; + $meta->name = 'bill_id'; + } + $meta->value = $bill->id; + $meta->save(); + } + /** * @param RecurrenceTransaction $transaction * @param int $categoryId @@ -269,6 +296,7 @@ trait RecurringTransactionTrait // remove category: $transaction->recurrenceTransactionMeta()->where('name', 'category_id')->delete(); $transaction->recurrenceTransactionMeta()->where('name', 'category_name')->delete(); + return; } diff --git a/app/Services/Internal/Update/GroupCloneService.php b/app/Services/Internal/Update/GroupCloneService.php index ffaf0113f1..8bf0eb443f 100644 --- a/app/Services/Internal/Update/GroupCloneService.php +++ b/app/Services/Internal/Update/GroupCloneService.php @@ -35,7 +35,6 @@ use FireflyIII\Models\TransactionJournalMeta; /** * Class GroupCloneService -* See reference nr. 92 */ class GroupCloneService { diff --git a/app/Services/Internal/Update/GroupUpdateService.php b/app/Services/Internal/Update/GroupUpdateService.php index b5a44a7d84..9648b38c22 100644 --- a/app/Services/Internal/Update/GroupUpdateService.php +++ b/app/Services/Internal/Update/GroupUpdateService.php @@ -32,7 +32,6 @@ use Log; /** * Class GroupUpdateService - * See reference nr. 91 */ class GroupUpdateService { diff --git a/app/Services/Internal/Update/JournalUpdateService.php b/app/Services/Internal/Update/JournalUpdateService.php index 77c533e098..0a18d2f21e 100644 --- a/app/Services/Internal/Update/JournalUpdateService.php +++ b/app/Services/Internal/Update/JournalUpdateService.php @@ -48,7 +48,6 @@ use Log; * Class to centralise code that updates a journal given the input by system. * * Class JournalUpdateService - * See reference nr. 93 */ class JournalUpdateService { @@ -163,8 +162,6 @@ class JournalUpdateService $this->updateAmount(); $this->updateForeignAmount(); - // See reference nr. 94 - app('preferences')->mark(); $this->transactionJournal->refresh(); diff --git a/app/Services/Internal/Update/RecurrenceUpdateService.php b/app/Services/Internal/Update/RecurrenceUpdateService.php index 051f8bd4cd..c1d597d77b 100644 --- a/app/Services/Internal/Update/RecurrenceUpdateService.php +++ b/app/Services/Internal/Update/RecurrenceUpdateService.php @@ -289,6 +289,9 @@ class RecurrenceUpdateService if (array_key_exists('budget_id', $current)) { $this->setBudget($match, (int)$current['budget_id']); } + if (array_key_exists('bill_id', $current)) { + $this->setBill($match, (int)$current['bill_id']); + } // reset category if name is set but empty: // can be removed when v1 is retired. if (array_key_exists('category_name', $current) && '' === (string)$current['category_name']) { diff --git a/app/Support/Binder/EitherConfigKey.php b/app/Support/Binder/EitherConfigKey.php index 93b0fa4fd2..b344771c96 100644 --- a/app/Support/Binder/EitherConfigKey.php +++ b/app/Support/Binder/EitherConfigKey.php @@ -1,7 +1,7 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Support\Binder; use Illuminate\Routing\Route; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -38,8 +40,10 @@ class EitherConfigKey 'firefly.accountRoles', 'firefly.valid_liabilities', 'firefly.interest_periods', + 'firefly.bill_periods', 'firefly.enable_external_map', 'firefly.expected_source_types', + 'firefly.credit_card_types', 'app.timezone', ]; /** diff --git a/app/Support/ExpandedForm.php b/app/Support/ExpandedForm.php index d700106ca4..29c6c04c0a 100644 --- a/app/Support/ExpandedForm.php +++ b/app/Support/ExpandedForm.php @@ -58,9 +58,9 @@ class ExpandedForm unset($options['currency'], $options['placeholder']); // make sure value is formatted nicely: - if (null !== $value && '' !== $value) { - $value = round((float)$value, 8); - } + //if (null !== $value && '' !== $value) { + //$value = round((float)$value, 8); + //} try { $html = prefixView('form.amount-no-currency', compact('classes', 'name', 'label', 'value', 'options'))->render(); } catch (Throwable $e) { // @phpstan-ignore-line @@ -224,6 +224,7 @@ class ExpandedForm } $selectList[$entryId] = $title; } + return $selectList; } @@ -246,7 +247,7 @@ class ExpandedForm // make sure value is formatted nicely: if (null !== $value && '' !== $value) { - $value = round((float)$value, $selectedCurrency->decimal_places); + // $value = round((float)$value, $selectedCurrency->decimal_places); } try { $html = prefixView('form.non-selectable-amount', compact('selectedCurrency', 'classes', 'name', 'label', 'value', 'options'))->render(); diff --git a/app/Support/Form/CurrencyForm.php b/app/Support/Form/CurrencyForm.php index 7299245058..ac7e10cade 100644 --- a/app/Support/Form/CurrencyForm.php +++ b/app/Support/Form/CurrencyForm.php @@ -34,8 +34,6 @@ use Throwable; * Class CurrencyForm * * All currency related form methods. - * -* See reference nr. 22 */ class CurrencyForm { @@ -61,7 +59,7 @@ class CurrencyForm * * @return string */ - protected function currencyField(string $name, string $view, $value = null, array $options = null): string + protected function currencyField(string $name, string $view, mixed $value = null, array $options = null): string { $label = $this->label($name, $options); $options = $this->expandOptionArray($name, $label, $options); diff --git a/app/Support/Http/Controllers/ModelInformation.php b/app/Support/Http/Controllers/ModelInformation.php index 9798b973e0..d91cbb83a4 100644 --- a/app/Support/Http/Controllers/ModelInformation.php +++ b/app/Support/Http/Controllers/ModelInformation.php @@ -130,8 +130,8 @@ trait ModelInformation $billTriggers = ['currency_is', 'amount_more', 'amount_less', 'description_contains']; $values = [ $bill->transactionCurrency()->first()->name, - round((float)$bill->amount_min, 12), - round((float)$bill->amount_max, 12), + round((float)$bill->amount_min, 24), + round((float)$bill->amount_max, 24), $bill->name, ]; foreach ($billTriggers as $index => $trigger) { diff --git a/app/Support/Http/Controllers/PeriodOverview.php b/app/Support/Http/Controllers/PeriodOverview.php index 9e26079941..90dfed5d71 100644 --- a/app/Support/Http/Controllers/PeriodOverview.php +++ b/app/Support/Http/Controllers/PeriodOverview.php @@ -38,7 +38,7 @@ use Log; /** * Trait PeriodOverview. * -* See reference nr. 36 + * See reference nr. 36 * * - Always request start date and end date. * - Group expenses, income, etc. under this period. @@ -91,7 +91,7 @@ trait PeriodOverview $cache->addProperty('account-show-period-entries'); $cache->addProperty($account->id); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } /** @var array $dates */ $dates = app('navigation')->blockPeriods($start, $end, $range); @@ -284,7 +284,7 @@ trait PeriodOverview $cache->addProperty($category->id); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } /** @var array $dates */ $dates = app('navigation')->blockPeriods($start, $end, $range); @@ -360,7 +360,7 @@ trait PeriodOverview $cache->addProperty('no-budget-period-entries'); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } /** @var array $dates */ @@ -392,7 +392,7 @@ trait PeriodOverview } /** -* See reference nr. 37 + * See reference nr. 37 * * Show period overview for no category view. * @@ -419,7 +419,7 @@ trait PeriodOverview $cache->addProperty('no-category-period-entries'); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } $dates = app('navigation')->blockPeriods($start, $end, $range); @@ -494,7 +494,7 @@ trait PeriodOverview $cache->addProperty('tag-period-entries'); $cache->addProperty($tag->id); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } /** @var array $dates */ $dates = app('navigation')->blockPeriods($start, $end, $range); @@ -568,7 +568,7 @@ trait PeriodOverview $cache->addProperty('transactions-period-entries'); $cache->addProperty($transactionType); if ($cache->has()) { - return $cache->get(); + return $cache->get(); } /** @var array $dates */ $dates = app('navigation')->blockPeriods($start, $end, $range); diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php index f7b8d59e4e..dabd433bd7 100644 --- a/app/Support/Preferences.php +++ b/app/Support/Preferences.php @@ -29,6 +29,7 @@ use FireflyIII\Models\Preference; use FireflyIII\User; use Illuminate\Support\Collection; use Log; +use PDOException; use Session; /** @@ -144,6 +145,19 @@ class Preferences return $result; } + /** + * @return Collection + */ + public function all(): Collection + { + $user = auth()->user(); + if(null === $user) { + return new Collection; + } + + return Preference::where('user_id', $user->id)->get(); + } + /** * @param User $user * @param string $name @@ -284,7 +298,11 @@ class Preferences $pref->name = $name; } $pref->data = $value; - $pref->save(); + try { + $pref->save(); + } catch(PDOException $e) { + throw new FireflyException(sprintf('Could not save preference: %s', $e->getMessage()), 0, $e); + } Cache::forever($fullName, $pref); return $pref; diff --git a/app/Support/Telemetry.php b/app/Support/Telemetry.php deleted file mode 100644 index c260103518..0000000000 --- a/app/Support/Telemetry.php +++ /dev/null @@ -1,88 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support; - -use Carbon\Carbon; -use FireflyIII\Support\System\GeneratesInstallationId; -use Sentry\Severity; -use Sentry\State\Scope; -use function Sentry\captureMessage; -use function Sentry\configureScope; - -/** - * Class Telemetry - */ -class Telemetry -{ - use GeneratesInstallationId; - - /** - * Feature telemetry stores a $value for the given $feature. - * Will only store the given $feature / $value combination once. - * - * - * Examples: - * - execute-cli-command [value] - * - use-help-pages - * - has-created-bill - * - first-time-install - * - more - * - * Its use should be limited to exotic and strange use cases in Firefly III. - * Because time and date are logged as well, useful to track users' evolution in Firefly III. - * - * Any meta-data stored is strictly non-financial. - * - * @param string $key - * @param string $value - */ - public function feature(string $key, string $value): void - { - if (false === config('firefly.send_telemetry') || false === config('firefly.feature_flags.telemetry')) { - // hard stop if not allowed to do telemetry. - // do nothing! - return; - } - $this->generateInstallationId(); - $installationId = app('fireflyconfig')->get('installation_id'); - - // add some context: - configureScope( - function (Scope $scope) use ($installationId, $key, $value): void { - $scope->setContext( - 'telemetry', [ - 'installation_id' => $installationId->data, - 'version' => config('firefly.version'), - 'collected_at' => Carbon::now()->format('r'), - 'key' => $key, - 'value' => $value, - ] - ); - } - ); - captureMessage(sprintf('FIT: %s/%s', $key, $value), Severity::info()); - } - -} diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php index 4517bc30d4..5c3b7d8d72 100644 --- a/app/Support/Twig/General.php +++ b/app/Support/Twig/General.php @@ -28,7 +28,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Support\Search\OperatorQuerySearch; use League\CommonMark\CommonMarkConverter; -use League\CommonMark\Environment; +use League\CommonMark\Environment\Environment; use League\CommonMark\Extension\GithubFlavoredMarkdownExtension; use Route; use Twig\Extension\AbstractExtension; @@ -203,14 +203,16 @@ class General extends AbstractExtension protected function markdown(): TwigFilter { return new TwigFilter( - 'markdown', + 'markdown', static function (string $text): string { + + $environment = Environment::createCommonMarkEnvironment(); $environment->addExtension(new GithubFlavoredMarkdownExtension()); $converter = new CommonMarkConverter(['allow_unsafe_links' => false, 'max_nesting_level' => 3, 'html_input' => 'escape'], $environment); - return $converter->convertToHtml($text); + return (string) $converter->convertToHtml($text); }, ['is_safe' => ['html']] ); } @@ -355,7 +357,7 @@ class General extends AbstractExtension /** * @return TwigFunction -* See reference nr. 43 + * See reference nr. 43 */ protected function getMetaField(): TwigFunction { diff --git a/app/Transformers/BillTransformer.php b/app/Transformers/BillTransformer.php index f1804ddf62..995dd48de9 100644 --- a/app/Transformers/BillTransformer.php +++ b/app/Transformers/BillTransformer.php @@ -78,43 +78,62 @@ class BillTransformer extends AbstractTransformer $paidDataFormatted = []; $payDatesFormatted = []; - foreach($paidData['paid_dates'] as $object) { - $object['date'] = Carbon::createFromFormat('!Y-m-d', $object['date'], config('app.timezone'))->toAtomString(); - $paidDataFormatted[] = $object; + foreach ($paidData['paid_dates'] as $object) { + $object['date'] = Carbon::createFromFormat('!Y-m-d', $object['date'], config('app.timezone'))->toAtomString(); + $paidDataFormatted[] = $object; } foreach ($payDates as $string) { $payDatesFormatted[] = Carbon::createFromFormat('!Y-m-d', $string, config('app.timezone'))->toAtomString(); } $nextExpectedMatch = null; - if(null !== $paidData['next_expected_match'] ) { + if (null !== $paidData['next_expected_match']) { $nextExpectedMatch = Carbon::createFromFormat('!Y-m-d', $paidData['next_expected_match'], config('app.timezone'))->toAtomString(); } + $nextExpectedMatchDiff = trans('firefly.not_expected_period'); + // converting back and forth is bad code but OK. + $temp = new Carbon($nextExpectedMatch); + if ($temp->isToday()) { + $nextExpectedMatchDiff = trans('firefly.today'); + } + + $current = $payDatesFormatted[0] ?? null; + if (null !== $current && !$temp->isToday()) { + $temp2 = Carbon::createFromFormat('Y-m-d\TH:i:sP', $current); + $nextExpectedMatchDiff = $temp2->diffForHumans(today(), Carbon::DIFF_RELATIVE_TO_NOW); + } + unset($temp, $temp2); + return [ - 'id' => (int)$bill->id, - 'created_at' => $bill->created_at->toAtomString(), - 'updated_at' => $bill->updated_at->toAtomString(), - 'currency_id' => (string)$bill->transaction_currency_id, - 'currency_code' => $currency->code, - 'currency_symbol' => $currency->symbol, - 'currency_decimal_places' => (int)$currency->decimal_places, - 'name' => $bill->name, - 'amount_min' => number_format((float)$bill->amount_min, $currency->decimal_places, '.', ''), - 'amount_max' => number_format((float)$bill->amount_max, $currency->decimal_places, '.', ''), - 'date' => $bill->date->toAtomString(), - 'repeat_freq' => $bill->repeat_freq, - 'skip' => (int)$bill->skip, - 'active' => $bill->active, - 'order' => (int)$bill->order, - 'notes' => $notes, - 'next_expected_match' => $nextExpectedMatch, - 'pay_dates' => $payDatesFormatted, - 'paid_dates' => $paidDataFormatted, - 'object_group_id' => $objectGroupId ? (string)$objectGroupId : null, - 'object_group_order' => $objectGroupOrder, - 'object_group_title' => $objectGroupTitle, - 'links' => [ + 'id' => (int)$bill->id, + 'created_at' => $bill->created_at->toAtomString(), + 'updated_at' => $bill->updated_at->toAtomString(), + 'currency_id' => (string)$bill->transaction_currency_id, + 'currency_code' => $currency->code, + 'currency_symbol' => $currency->symbol, + 'currency_decimal_places' => (int)$currency->decimal_places, + 'name' => $bill->name, + 'amount_min' => number_format((float)$bill->amount_min, $currency->decimal_places, '.', ''), + 'amount_max' => number_format((float)$bill->amount_max, $currency->decimal_places, '.', ''), + 'date' => $bill->date->toAtomString(), + 'end_date' => $bill->end_date?->toAtomString(), + 'extension_date' => $bill->extension_date?->toAtomString(), + 'repeat_freq' => $bill->repeat_freq, + 'skip' => (int)$bill->skip, + 'active' => $bill->active, + 'order' => (int)$bill->order, + 'notes' => $notes, + 'object_group_id' => $objectGroupId ? (string)$objectGroupId : null, + 'object_group_order' => $objectGroupOrder, + 'object_group_title' => $objectGroupTitle, + + // these fields need work: + 'next_expected_match' => $nextExpectedMatch, + 'next_expected_match_diff' => $nextExpectedMatchDiff, + 'pay_dates' => $payDatesFormatted, + 'paid_dates' => $paidDataFormatted, + 'links' => [ [ 'rel' => 'self', 'uri' => '/bills/' . $bill->id, @@ -208,7 +227,7 @@ class BillTransformer extends AbstractTransformer protected function lastPaidDate(Collection $dates, Carbon $default): Carbon { if (0 === $dates->count()) { - return $default; + return $default; } $latest = $dates->first()->date; /** @var TransactionJournal $journal */ @@ -254,6 +273,7 @@ class BillTransformer extends AbstractTransformer return $date->format('Y-m-d'); } ); + return $simple->toArray(); } diff --git a/app/Transformers/RecurrenceTransformer.php b/app/Transformers/RecurrenceTransformer.php index 949d39fa67..19a14d4a98 100644 --- a/app/Transformers/RecurrenceTransformer.php +++ b/app/Transformers/RecurrenceTransformer.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace FireflyIII\Transformers; + use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Factory\CategoryFactory; @@ -29,6 +30,7 @@ use FireflyIII\Models\Recurrence; use FireflyIII\Models\RecurrenceRepetition; use FireflyIII\Models\RecurrenceTransaction; use FireflyIII\Models\RecurrenceTransactionMeta; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\Repositories\Recurring\RecurringRepositoryInterface; @@ -44,6 +46,7 @@ class RecurrenceTransformer extends AbstractTransformer private CategoryFactory $factory; private PiggyBankRepositoryInterface $piggyRepos; private RecurringRepositoryInterface $repository; + private BillRepositoryInterface $billRepos; /** * RecurrenceTransformer constructor. @@ -56,6 +59,7 @@ class RecurrenceTransformer extends AbstractTransformer $this->piggyRepos = app(PiggyBankRepositoryInterface::class); $this->factory = app(CategoryFactory::class); $this->budgetRepos = app(BudgetRepositoryInterface::class); + $this->billRepos = app(BillRepositoryInterface::class); } @@ -251,6 +255,8 @@ class RecurrenceTransformer extends AbstractTransformer $array['budget_name'] = null; $array['piggy_bank_id'] = null; $array['piggy_bank_name'] = null; + $array['bill_id'] = null; + $array['bill_name'] = null; /** @var RecurrenceTransactionMeta $transactionMeta */ foreach ($transaction->recurrenceTransactionMeta as $transactionMeta) { @@ -258,6 +264,11 @@ class RecurrenceTransformer extends AbstractTransformer default: throw new FireflyException(sprintf('Recurrence transformer cant handle field "%s"', $transactionMeta->name)); case 'bill_id': + $bill = $this->billRepos->find((int)$transactionMeta->value); + if (null !== $bill) { + $array['bill_id'] = (string)$bill->id; + $array['bill_name'] = $bill->name; + } break; case 'tags': $array['tags'] = json_decode($transactionMeta->value); diff --git a/app/Validation/Account/LiabilityValidation.php b/app/Validation/Account/LiabilityValidation.php index 0a7df89e64..f8990f4190 100644 --- a/app/Validation/Account/LiabilityValidation.php +++ b/app/Validation/Account/LiabilityValidation.php @@ -1,5 +1,5 @@ . */ +declare(strict_types=1); + namespace FireflyIII\Validation\Account; diff --git a/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php new file mode 100644 index 0000000000..7f5f21839d --- /dev/null +++ b/app/Validation/Api/Data/Bulk/ValidatesBulkTransactionQuery.php @@ -0,0 +1,75 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Validation\Api\Data\Bulk; + +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use Illuminate\Validation\Validator; + +/** + * + */ +trait ValidatesBulkTransactionQuery +{ + /** + * @param Validator $validator + */ + protected function validateTransactionQuery(Validator $validator): void + { + $data = $validator->getData(); + // assumption is all validation has already taken place + // and the query key exists. + $json = json_decode($data['query'], true, 8); + + if (array_key_exists('source_account_id', $json['where']) + && array_key_exists('destination_account_id', $json['update']) + ) { + // find both accounts + // must be same type. + // already validated: belongs to this user. + $repository = app(AccountRepositoryInterface::class); + $source = $repository->find((int)$json['where']['source_account_id']); + $dest = $repository->find((int)$json['update']['destination_account_id']); + if (null === $source) { + $validator->errors()->add('query', sprintf((string)trans('validation.invalid_query_data'), 'where', 'source_account_id')); + + return; + } + if (null === $dest) { + $validator->errors()->add('query', sprintf((string)trans('validation.invalid_query_data'), 'update', 'destination_account_id')); + + return; + } + if ($source->accountType->type !== $dest->accountType->type) { + $validator->errors()->add('query', (string)trans('validation.invalid_query_account_type')); + return; + } + // must have same currency: + if($repository->getAccountCurrency($source)->id !== $repository->getAccountCurrency($dest)->id) { + $validator->errors()->add('query', (string)trans('validation.invalid_query_currency')); + } + } + } + +} diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index 21c85d620f..971292ac58 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -28,7 +28,6 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\Account; use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountType; -use FireflyIII\Models\Budget; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\TransactionType; use FireflyIII\Models\Webhook; @@ -179,10 +178,13 @@ class FireflyValidator extends Validator '32', '33', '34', '35',]; // take - $first = substr($value, 0, 4); - $last = substr($value, 4); - $iban = $last . $first; - $iban = str_replace($search, $replace, $iban); + $first = substr($value, 0, 4); + $last = substr($value, 4); + $iban = $last . $first; + $iban = trim(str_replace($search, $replace, $iban)); + if (0 === strlen($iban)) { + return false; + } $checksum = bcmod($iban, '97'); return 1 === (int)$checksum; @@ -263,16 +265,8 @@ class FireflyValidator extends Validator if ('set_budget' === $actionType) { /** @var BudgetRepositoryInterface $repository */ $repository = app(BudgetRepositoryInterface::class); - $budgets = $repository->getBudgets(); - // count budgets, should have at least one -// See reference nr. 102 - $count = $budgets->filter( - function (Budget $budget) use ($value) { - return $budget->name === $value; - } - )->count(); - return 1 === $count; + return null !== $repository->findByName($value); } // if it's link to bill, verify the name of the bill. @@ -439,7 +433,7 @@ class FireflyValidator extends Validator */ private function validateAccountAnonymously(): bool { - if (!array_key_exists('user_id',$this->data)) { + if (!array_key_exists('user_id', $this->data)) { return false; } @@ -447,16 +441,14 @@ class FireflyValidator extends Validator $type = AccountType::find($this->data['account_type_id'])->first(); $value = $this->data['name']; - $set = $user->accounts()->where('account_type_id', $type->id)->get(); -// See reference nr. 103 - /** @var Account $entry */ - foreach ($set as $entry) { - if ($entry->name === $value) { - return false; + $set = $user->accounts()->where('account_type_id', $type->id)->get(); + $result = $set->first( + function (Account $account) use ($value) { + return $account->name === $value; } - } + ); - return true; + return null === $result; } /** @@ -480,15 +472,13 @@ class FireflyValidator extends Validator $accountTypeIds = $accountTypes->pluck('id')->toArray(); /** @var Collection $set */ $set = auth()->user()->accounts()->whereIn('account_type_id', $accountTypeIds)->where('id', '!=', $ignore)->get(); -// See reference nr. 104 - /** @var Account $entry */ - foreach ($set as $entry) { - if ($entry->name === $value) { - return false; + $result = $set->first( + function (Account $account) use ($value) { + return $account->name === $value; } - } + ); + return null === $result; - return true; } /** @@ -504,16 +494,13 @@ class FireflyValidator extends Validator /** @var Collection $set */ $set = auth()->user()->accounts()->where('account_type_id', $type->id)->where('id', '!=', $ignore)->get(); -// See reference nr. 105 - /** @var Account $entry */ - foreach ($set as $entry) { -// See reference nr. 106 - if ($entry->name === $value) { - return false; - } - } - return true; + $result = $set->first( + function (Account $account) use ($value) { + return $account->name === $value; + } + ); + return null === $result; } /** @@ -718,7 +705,7 @@ class FireflyValidator extends Validator * @param mixed $value * @param mixed $parameters * -* See reference nr. 107 + * See reference nr. 107 * * @return bool */ @@ -730,18 +717,8 @@ class FireflyValidator extends Validator if (null !== $exclude) { $query->where('piggy_banks.id', '!=', (int)$exclude); } - $set = $query->get(['piggy_banks.*']); - - /** @var PiggyBank $entry */ - foreach ($set as $entry) { - - $fieldValue = $entry->name; - if ($fieldValue === $value) { - return false; - } - } - - return true; + $query->where('piggy_banks.name',$value); + return null === $query->first(['piggy_banks.*']); } /** diff --git a/changelog.md b/changelog.md index ee6fd4f701..c4a6eb5751 100644 --- a/changelog.md +++ b/changelog.md @@ -8,7 +8,6 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - A few new pages for the new v2 layout. Thanks @alex6480! -- Feature to be able to rebuild Docker images and show security warnings in new builds. - Added a new currency yay! - You can now manage loans and debts a little better. @@ -16,14 +15,32 @@ This project adheres to [Semantic Versioning](http://semver.org/). - A better cache routine for layout v2 pages. - All LDAP libraries have been upgrade. +### Deprecated +- Initial release. + +### Removed +- All telemetry options have been removed. + + ### Fixed +- [Issue 4894](https://github.com/firefly-iii/firefly-iii/issues/4894) Bad number comparison - Various Sonarqube issues, thanks @hazma-fadil! - Correct menu display, thanks @vonsogt! + +### Security +- Feature to be able to rebuild Docker images and show security warnings in new builds. + ### API - You can disable webhooks with an extra field in API submissions. - There is a static cron token (see `.env.example`) which is useful for Docker. +## 5.5.13 - 2021-07-25 + +### Security + +- This version of Firefly III fixes [CVE-2021-3663](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3663) + ## 5.5.12 - 2021-06-03 ⚠️ On July 1st 2021 the Docker tag will change to `fireflyiii/core`. You can already start using the new tag. diff --git a/composer.json b/composer.json index e1ca58f0bf..32cfa0294c 100644 --- a/composer.json +++ b/composer.json @@ -84,18 +84,17 @@ "ext-xml": "*", "bacon/bacon-qr-code": "2.*", "diglactic/laravel-breadcrumbs": "^7.0", - "directorytree/ldaprecord-laravel": "^2.2", "doctrine/dbal": "3.*", "fideloper/proxy": "4.*", "gdbots/query-parser": "^2.0", "guzzlehttp/guzzle": "^7.2", - "jc5/google2fa-laravel": "2.0.5", + "jc5/google2fa-laravel": "2.0.6", "jc5/recovery": "^2", - "laravel/framework": "^8.48", + "laravel/framework": "^8.51", "laravel/passport": "10.*", "laravel/ui": "^3.0", "laravelcollective/html": "6.*", - "league/commonmark": "1.*", + "league/commonmark": "2.*", "league/csv": "^9.6", "league/fractal": "0.*", "pragmarx/google2fa": "^8.0", @@ -111,8 +110,8 @@ "filp/whoops": "2.*", "fakerphp/faker": "1.*", "mockery/mockery": "1.*", - "nunomaduro/larastan": "^0.7.0", - "phpstan/phpstan": "^0.12.34", + "nunomaduro/larastan": "^0.7.11", + "phpstan/phpstan": "^0.12.94", "phpstan/phpstan-deprecation-rules": "^0.12.5", "phpunit/phpunit": "^9.5", "roave/security-advisories": "dev-master", diff --git a/composer.lock b/composer.lock index a64d0c79d6..a1e1de3ff9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0019b285c24678c7040e6f0724d449b6", + "content-hash": "9b20fef800a2c999627ed1399ac196a6", "packages": [ { "name": "bacon/bacon-qr-code", @@ -301,6 +301,81 @@ }, "time": "2021-04-09T23:57:26+00:00" }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.0", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "e04ff030d24a33edc2421bef305e32919dd78fc3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/e04ff030d24a33edc2421bef305e32919dd78fc3", + "reference": "e04ff030d24a33edc2421bef305e32919dd78fc3", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.0" + }, + "time": "2021-01-01T22:08:42+00:00" + }, { "name": "diglactic/laravel-breadcrumbs", "version": "v7.0.0", @@ -372,163 +447,25 @@ }, "time": "2021-05-23T16:43:52+00:00" }, - { - "name": "directorytree/ldaprecord", - "version": "v2.5.3", - "source": { - "type": "git", - "url": "https://github.com/DirectoryTree/LdapRecord.git", - "reference": "cca4bcef8b4cdcb4f03beb11d876eaf322511bfd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/cca4bcef8b4cdcb4f03beb11d876eaf322511bfd", - "reference": "cca4bcef8b4cdcb4f03beb11d876eaf322511bfd", - "shasum": "" - }, - "require": { - "ext-json": "*", - "ext-ldap": "*", - "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0", - "nesbot/carbon": "^1.0|^2.0", - "php": ">=7.3", - "psr/log": "^1.0", - "psr/simple-cache": "^1.0", - "tightenco/collect": "^5.6|^6.0|^7.0|^8.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^8.0", - "spatie/ray": "^1.24" - }, - "type": "library", - "autoload": { - "psr-4": { - "LdapRecord\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Steve Bauman", - "email": "steven_bauman@outlook.com", - "role": "Developer" - } - ], - "description": "A fully-featured LDAP ORM.", - "homepage": "https://www.ldaprecord.com", - "keywords": [ - "active directory", - "ad", - "adLDAP", - "adldap2", - "directory", - "ldap", - "ldaprecord", - "orm", - "windows" - ], - "support": { - "docs": "https://ldaprecord.com", - "email": "steven_bauman@outlook.com", - "issues": "https://github.com/DirectoryTree/LdapRecord/issues", - "source": "https://github.com/DirectoryTree/LdapRecord" - }, - "funding": [ - { - "url": "https://github.com/stevebauman", - "type": "github" - } - ], - "time": "2021-06-25T20:26:27+00:00" - }, - { - "name": "directorytree/ldaprecord-laravel", - "version": "v2.3.3", - "source": { - "type": "git", - "url": "https://github.com/DirectoryTree/LdapRecord-Laravel.git", - "reference": "81f4d8a6336bfd9fb59f61d1db1c01faa9e44d46" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DirectoryTree/LdapRecord-Laravel/zipball/81f4d8a6336bfd9fb59f61d1db1c01faa9e44d46", - "reference": "81f4d8a6336bfd9fb59f61d1db1c01faa9e44d46", - "shasum": "" - }, - "require": { - "directorytree/ldaprecord": "^2.4.4", - "ext-ldap": "*", - "illuminate/support": "^5.6|^6.0|^7.0|^8.0", - "php": ">=7.2", - "ramsey/uuid": "*" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "^3.0", - "mockery/mockery": "~1.0", - "orchestra/testbench": "~3.7|~4.0|~5.0|~6.0", - "phpunit/phpunit": "~7.0|~8.0|~9.0" - }, - "type": "project", - "extra": { - "laravel": { - "providers": [ - "LdapRecord\\Laravel\\LdapServiceProvider", - "LdapRecord\\Laravel\\LdapAuthServiceProvider" - ] - } - }, - "autoload": { - "psr-4": { - "LdapRecord\\Laravel\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "LDAP Authentication & Management for Laravel.", - "keywords": [ - "adldap2", - "laravel", - "ldap", - "ldaprecord" - ], - "support": { - "issues": "https://github.com/DirectoryTree/LdapRecord-Laravel/issues", - "source": "https://github.com/DirectoryTree/LdapRecord-Laravel/tree/v2.3.3" - }, - "funding": [ - { - "url": "https://github.com/stevebauman", - "type": "github" - } - ], - "time": "2021-05-30T23:04:22+00:00" - }, { "name": "doctrine/cache", - "version": "2.0.3", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "c9622c6820d3ede1e2315a6a377ea1076e421d88" + "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/c9622c6820d3ede1e2315a6a377ea1076e421d88", - "reference": "c9622c6820d3ede1e2315a6a377ea1076e421d88", + "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", + "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", "shasum": "" }, "require": { "php": "~7.1 || ^8.0" }, "conflict": { - "doctrine/common": ">2.2,<2.4", - "psr/cache": ">=3" + "doctrine/common": ">2.2,<2.4" }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", @@ -537,8 +474,9 @@ "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "predis/predis": "~1.0", - "psr/cache": "^1.0 || ^2.0", - "symfony/cache": "^4.4 || ^5.2" + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", + "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" }, "suggest": { "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" @@ -590,7 +528,7 @@ ], "support": { "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.0.3" + "source": "https://github.com/doctrine/cache/tree/2.1.1" }, "funding": [ { @@ -606,7 +544,7 @@ "type": "tidelift" } ], - "time": "2021-05-25T09:43:04+00:00" + "time": "2021-07-17T14:49:29+00:00" }, { "name": "doctrine/dbal", @@ -1671,16 +1609,16 @@ }, { "name": "jc5/google2fa-laravel", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/JC5/google2fa-laravel.git", - "reference": "b5b87f96fb241b30b8d2d0fd27d3dce311f7ae42" + "reference": "271957317a84d36276c698e85db3ea33551e321d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JC5/google2fa-laravel/zipball/b5b87f96fb241b30b8d2d0fd27d3dce311f7ae42", - "reference": "b5b87f96fb241b30b8d2d0fd27d3dce311f7ae42", + "url": "https://api.github.com/repos/JC5/google2fa-laravel/zipball/271957317a84d36276c698e85db3ea33551e321d", + "reference": "271957317a84d36276c698e85db3ea33551e321d", "shasum": "" }, "require": { @@ -1689,8 +1627,8 @@ "pragmarx/google2fa-qrcode": "^1.0" }, "require-dev": { - "orchestra/testbench": "3.4.*|3.5.*|3.6.*|3.7.*|4.*", - "phpunit/phpunit": "~5|~6|~7|~8", + "orchestra/testbench": "3.4.*|3.5.*|3.6.*|3.7.*|4.*|5.*|6.*", + "phpunit/phpunit": "~9", "roave/security-advisories": "dev-master" }, "suggest": { @@ -1746,9 +1684,9 @@ ], "support": { "issues": "https://github.com/JC5/google2fa-laravel/issues", - "source": "https://github.com/JC5/google2fa-laravel/tree/2.0.5" + "source": "https://github.com/JC5/google2fa-laravel/tree/2.0.6" }, - "time": "2020-07-28T18:27:58+00:00" + "time": "2021-07-10T05:21:50+00:00" }, { "name": "jc5/recovery", @@ -1826,16 +1764,16 @@ }, { "name": "laravel/framework", - "version": "v8.49.1", + "version": "v8.54.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "62aee1bfeefd82f160c7aa3b4c63cb2f053215c0" + "reference": "7b88554cd1aeb52b7f82689bf244182e7a81894b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/62aee1bfeefd82f160c7aa3b4c63cb2f053215c0", - "reference": "62aee1bfeefd82f160c7aa3b4c63cb2f053215c0", + "url": "https://api.github.com/repos/laravel/framework/zipball/7b88554cd1aeb52b7f82689bf244182e7a81894b", + "reference": "7b88554cd1aeb52b7f82689bf244182e7a81894b", "shasum": "" }, "require": { @@ -1845,7 +1783,7 @@ "ext-json": "*", "ext-mbstring": "*", "ext-openssl": "*", - "league/commonmark": "^1.3", + "league/commonmark": "^1.3|^2.0", "league/flysystem": "^1.1", "monolog/monolog": "^2.0", "nesbot/carbon": "^2.31", @@ -1908,7 +1846,7 @@ "illuminate/view": "self.version" }, "require-dev": { - "aws/aws-sdk-php": "^3.155", + "aws/aws-sdk-php": "^3.186.4", "doctrine/dbal": "^2.6|^3.0", "filp/whoops": "^2.8", "guzzlehttp/guzzle": "^6.5.5|^7.0.1", @@ -1921,7 +1859,7 @@ "symfony/cache": "^5.1.4" }, "suggest": { - "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.155).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.186.4).", "brianium/paratest": "Required to run tests in parallel (^6.0).", "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).", "ext-ftp": "Required to use the Flysystem FTP driver.", @@ -1990,7 +1928,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2021-07-02T16:50:12+00:00" + "time": "2021-08-10T14:25:51+00:00" }, { "name": "laravel/passport", @@ -2336,42 +2274,51 @@ }, { "name": "league/commonmark", - "version": "1.6.5", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "44ffd8d3c4a9133e4bd0548622b09c55af39db5f" + "reference": "0d57f20aa03129ee7ef5f690e634884315d4238c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/44ffd8d3c4a9133e4bd0548622b09c55af39db5f", - "reference": "44ffd8d3c4a9133e4bd0548622b09c55af39db5f", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/0d57f20aa03129ee7ef5f690e634884315d4238c", + "reference": "0d57f20aa03129ee7ef5f690e634884315d4238c", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1 || ^8.0" - }, - "conflict": { - "scrutinizer/ocular": "1.7.*" + "league/config": "^1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { - "cebe/markdown": "~1.0", - "commonmark/commonmark.js": "0.29.2", - "erusev/parsedown": "~1.0", + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "erusev/parsedown": "^1.0", "ext-json": "*", "github/gfm": "0.29.0", - "michelf/php-markdown": "~1.4", - "mikehaertl/php-shellcommand": "^1.4", - "phpstan/phpstan": "^0.12.90", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.2", - "scrutinizer/ocular": "^1.5", - "symfony/finder": "^4.2" + "michelf/php-markdown": "^1.4", + "phpstan/phpstan": "^0.12.88", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" }, - "bin": [ - "bin/commonmark" - ], "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.1-dev" + } + }, "autoload": { "psr-4": { "League\\CommonMark\\": "src" @@ -2389,7 +2336,7 @@ "role": "Lead Developer" } ], - "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)", + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", "homepage": "https://commonmark.thephpleague.com", "keywords": [ "commonmark", @@ -2403,6 +2350,7 @@ ], "support": { "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", "issues": "https://github.com/thephpleague/commonmark/issues", "rss": "https://github.com/thephpleague/commonmark/releases.atom", "source": "https://github.com/thephpleague/commonmark" @@ -2433,7 +2381,89 @@ "type": "tidelift" } ], - "time": "2021-06-26T11:57:13+00:00" + "time": "2021-07-31T19:15:22+00:00" + }, + { + "name": "league/config", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "20d42d88f12a76ff862e17af4f14a5a4bbfd0925" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/20d42d88f12a76ff862e17af4f14a5a4bbfd0925", + "reference": "20d42d88f12a76ff862e17af4f14a5a4bbfd0925", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-06-19T15:52:37+00:00" }, { "name": "league/csv", @@ -2793,16 +2823,16 @@ }, { "name": "league/oauth2-server", - "version": "8.2.4", + "version": "8.3.2", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-server.git", - "reference": "622eaa1f28eb4a2dea0cfc7e4f5280fac794e83c" + "reference": "0809487d33dd8a2c8c8c04e4a599ba4aadba1ae6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/622eaa1f28eb4a2dea0cfc7e4f5280fac794e83c", - "reference": "622eaa1f28eb4a2dea0cfc7e4f5280fac794e83c", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/0809487d33dd8a2c8c8c04e4a599ba4aadba1ae6", + "reference": "0809487d33dd8a2c8c8c04e4a599ba4aadba1ae6", "shasum": "" }, "require": { @@ -2868,7 +2898,7 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-server/issues", - "source": "https://github.com/thephpleague/oauth2-server/tree/8.2.4" + "source": "https://github.com/thephpleague/oauth2-server/tree/8.3.2" }, "funding": [ { @@ -2876,20 +2906,20 @@ "type": "github" } ], - "time": "2020-12-10T11:35:44+00:00" + "time": "2021-07-27T08:17:08+00:00" }, { "name": "monolog/monolog", - "version": "2.2.0", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084" + "reference": "71312564759a7db5b789296369c1a264efc43aad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084", - "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/71312564759a7db5b789296369c1a264efc43aad", + "reference": "71312564759a7db5b789296369c1a264efc43aad", "shasum": "" }, "require": { @@ -2908,7 +2938,7 @@ "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", "phpspec/prophecy": "^1.6.1", - "phpstan/phpstan": "^0.12.59", + "phpstan/phpstan": "^0.12.91", "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", @@ -2960,7 +2990,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.2.0" + "source": "https://github.com/Seldaek/monolog/tree/2.3.2" }, "funding": [ { @@ -2972,26 +3002,27 @@ "type": "tidelift" } ], - "time": "2020-12-14T13:15:25+00:00" + "time": "2021-07-23T07:42:52+00:00" }, { "name": "nesbot/carbon", - "version": "2.50.0", + "version": "2.51.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "f47f17d17602b2243414a44ad53d9f8b9ada5fdb" + "reference": "8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f47f17d17602b2243414a44ad53d9f8b9ada5fdb", - "reference": "f47f17d17602b2243414a44ad53d9f8b9ada5fdb", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922", + "reference": "8619c299d1e0d4b344e1f98ca07a1ce2cfbf1922", "shasum": "" }, "require": { "ext-json": "*", "php": "^7.1.8 || ^8.0", "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", "symfony/translation": "^3.4 || ^4.0 || ^5.0" }, "require-dev": { @@ -3010,8 +3041,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev", - "dev-3.x": "3.x-dev" + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" }, "laravel": { "providers": [ @@ -3065,7 +3096,154 @@ "type": "tidelift" } ], - "time": "2021-06-28T22:38:45+00:00" + "time": "2021-07-28T13:16:28+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "f5ed39fc96358f922cedfd1e516f0dadf5d2be0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/f5ed39fc96358f922cedfd1e516f0dadf5d2be0d", + "reference": "f5ed39fc96358f922cedfd1e516f0dadf5d2be0d", + "shasum": "" + }, + "require": { + "nette/utils": "^3.1.4 || ^4.0", + "php": ">=7.1 <8.1" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.1" + }, + "time": "2021-03-04T17:51:11+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/967cfc4f9a1acd5f1058d76715a424c53343c20c", + "reference": "967cfc4f9a1acd5f1058d76715a424c53343c20c", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.1" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^0.12", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.2" + }, + "time": "2021-03-03T22:53:25+00:00" }, { "name": "nyholm/psr7", @@ -4212,20 +4390,21 @@ }, { "name": "ramsey/collection", - "version": "1.1.3", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/ramsey/collection.git", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1" + "reference": "eaca1dc1054ddd10cbd83c1461907bee6fb528fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/collection/zipball/28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", - "reference": "28a5c4ab2f5111db6a60b2b4ec84057e0f43b9c1", + "url": "https://api.github.com/repos/ramsey/collection/zipball/eaca1dc1054ddd10cbd83c1461907bee6fb528fa", + "reference": "eaca1dc1054ddd10cbd83c1461907bee6fb528fa", "shasum": "" }, "require": { - "php": "^7.2 || ^8" + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" }, "require-dev": { "captainhook/captainhook": "^5.3", @@ -4235,6 +4414,7 @@ "hamcrest/hamcrest-php": "^2", "jangregor/phpstan-prophecy": "^0.8", "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", "phpstan/extension-installer": "^1", "phpstan/phpstan": "^0.12.32", "phpstan/phpstan-mockery": "^0.12.5", @@ -4262,7 +4442,7 @@ "homepage": "https://benramsey.com" } ], - "description": "A PHP 7.2+ library for representing and manipulating collections.", + "description": "A PHP library for representing and manipulating collections.", "keywords": [ "array", "collection", @@ -4273,7 +4453,7 @@ ], "support": { "issues": "https://github.com/ramsey/collection/issues", - "source": "https://github.com/ramsey/collection/tree/1.1.3" + "source": "https://github.com/ramsey/collection/tree/1.2.1" }, "funding": [ { @@ -4285,20 +4465,20 @@ "type": "tidelift" } ], - "time": "2021-01-21T17:40:04+00:00" + "time": "2021-08-06T03:41:06+00:00" }, { "name": "ramsey/uuid", - "version": "4.1.1", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "cd4032040a750077205918c86049aa0f43d22947" + "reference": "7231612a5221f5524d3575bebdce20eeef8547a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/cd4032040a750077205918c86049aa0f43d22947", - "reference": "cd4032040a750077205918c86049aa0f43d22947", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/7231612a5221f5524d3575bebdce20eeef8547a1", + "reference": "7231612a5221f5524d3575bebdce20eeef8547a1", "shasum": "" }, "require": { @@ -4312,26 +4492,26 @@ "rhumsaa/uuid": "self.version" }, "require-dev": { - "codeception/aspect-mock": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", "doctrine/annotations": "^1.8", - "goaop/framework": "^2", + "ergebnis/composer-normalize": "^2.15", "mockery/mockery": "^1.3", "moontoast/math": "^1.1", "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", "php-mock/php-mock-mockery": "^1.3", - "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", - "phpbench/phpbench": "^0.17.1", + "phpbench/phpbench": "^1.0", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-mockery": "^0.12", "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^8.5", - "psy/psysh": "^0.10.0", - "slevomat/coding-standard": "^6.0", + "phpunit/phpunit": "^8.5 || ^9", + "slevomat/coding-standard": "^7.0", "squizlabs/php_codesniffer": "^3.5", - "vimeo/psalm": "3.9.4" + "vimeo/psalm": "^4.9" }, "suggest": { "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", @@ -4344,7 +4524,10 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.x-dev" + "dev-main": "4.x-dev" + }, + "captainhook": { + "force-install": true } }, "autoload": { @@ -4360,7 +4543,6 @@ "MIT" ], "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", - "homepage": "https://github.com/ramsey/uuid", "keywords": [ "guid", "identifier", @@ -4368,16 +4550,19 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "rss": "https://github.com/ramsey/uuid/releases.atom", - "source": "https://github.com/ramsey/uuid" + "source": "https://github.com/ramsey/uuid/tree/4.2.0" }, "funding": [ { "url": "https://github.com/ramsey", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" } ], - "time": "2020-08-18T17:17:46+00:00" + "time": "2021-08-06T22:30:43+00:00" }, { "name": "rcrowe/twigbridge", @@ -4458,16 +4643,16 @@ }, { "name": "spatie/data-transfer-object", - "version": "3.3.0", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/spatie/data-transfer-object.git", - "reference": "ad1547a1d35e81051520955c9f02f0eaafeb2ab9" + "reference": "e480f199043ae6342102da5ca5fe37e1759ec04f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/ad1547a1d35e81051520955c9f02f0eaafeb2ab9", - "reference": "ad1547a1d35e81051520955c9f02f0eaafeb2ab9", + "url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/e480f199043ae6342102da5ca5fe37e1759ec04f", + "reference": "e480f199043ae6342102da5ca5fe37e1759ec04f", "shasum": "" }, "require": { @@ -4508,7 +4693,7 @@ ], "support": { "issues": "https://github.com/spatie/data-transfer-object/issues", - "source": "https://github.com/spatie/data-transfer-object/tree/3.3.0" + "source": "https://github.com/spatie/data-transfer-object/tree/3.4.0" }, "funding": [ { @@ -4520,7 +4705,7 @@ "type": "github" } ], - "time": "2021-06-01T11:27:12+00:00" + "time": "2021-08-10T12:43:37+00:00" }, { "name": "swiftmailer/swiftmailer", @@ -4599,16 +4784,16 @@ }, { "name": "symfony/console", - "version": "v5.3.2", + "version": "v5.3.6", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1" + "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/649730483885ff2ca99ca0560ef0e5f6b03f2ac1", - "reference": "649730483885ff2ca99ca0560ef0e5f6b03f2ac1", + "url": "https://api.github.com/repos/symfony/console/zipball/51b71afd6d2dc8f5063199357b9880cea8d8bfe2", + "reference": "51b71afd6d2dc8f5063199357b9880cea8d8bfe2", "shasum": "" }, "require": { @@ -4616,11 +4801,12 @@ "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2", "symfony/string": "^5.1" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -4628,10 +4814,10 @@ "symfony/process": "<4.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/event-dispatcher": "^4.4|^5.0", @@ -4677,7 +4863,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.2" + "source": "https://github.com/symfony/console/tree/v5.3.6" }, "funding": [ { @@ -4693,24 +4879,25 @@ "type": "tidelift" } ], - "time": "2021-06-12T09:42:48+00:00" + "time": "2021-07-27T19:10:22+00:00" }, { "name": "symfony/css-selector", - "version": "v5.3.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "fcd0b29a7a0b1bb5bfbedc6231583d77fea04814" + "reference": "7fb120adc7f600a59027775b224c13a33530dd90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/fcd0b29a7a0b1bb5bfbedc6231583d77fea04814", - "reference": "fcd0b29a7a0b1bb5bfbedc6231583d77fea04814", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/7fb120adc7f600a59027775b224c13a33530dd90", + "reference": "7fb120adc7f600a59027775b224c13a33530dd90", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -4742,7 +4929,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.3.0" + "source": "https://github.com/symfony/css-selector/tree/v5.3.4" }, "funding": [ { @@ -4758,7 +4945,7 @@ "type": "tidelift" } ], - "time": "2021-05-26T17:40:38+00:00" + "time": "2021-07-21T12:38:00+00:00" }, { "name": "symfony/deprecation-contracts", @@ -4829,22 +5016,21 @@ }, { "name": "symfony/error-handler", - "version": "v5.3.3", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "43323e79c80719e8a4674e33484bca98270d223f" + "reference": "281f6c4660bcf5844bb0346fe3a4664722fe4c73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/43323e79c80719e8a4674e33484bca98270d223f", - "reference": "43323e79c80719e8a4674e33484bca98270d223f", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/281f6c4660bcf5844bb0346fe3a4664722fe4c73", + "reference": "281f6c4660bcf5844bb0346fe3a4664722fe4c73", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/log": "^1.0", - "symfony/polyfill-php80": "^1.15", + "psr/log": "^1|^2|^3", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { @@ -4878,7 +5064,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.3.3" + "source": "https://github.com/symfony/error-handler/tree/v5.3.4" }, "funding": [ { @@ -4894,27 +5080,27 @@ "type": "tidelift" } ], - "time": "2021-06-24T08:13:00+00:00" + "time": "2021-07-23T15:55:36+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.3.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "67a5f354afa8e2f231081b3fa11a5912f933c3ce" + "reference": "f2fd2208157553874560f3645d4594303058c4bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/67a5f354afa8e2f231081b3fa11a5912f933c3ce", - "reference": "67a5f354afa8e2f231081b3fa11a5912f933c3ce", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f2fd2208157553874560f3645d4594303058c4bd", + "reference": "f2fd2208157553874560f3645d4594303058c4bd", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/dependency-injection": "<4.4" @@ -4924,7 +5110,7 @@ "symfony/event-dispatcher-implementation": "2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/error-handler": "^4.4|^5.0", @@ -4963,7 +5149,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.4" }, "funding": [ { @@ -4979,7 +5165,7 @@ "type": "tidelift" } ], - "time": "2021-05-26T17:43:10+00:00" + "time": "2021-07-23T15:55:36+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -5062,20 +5248,21 @@ }, { "name": "symfony/finder", - "version": "v5.3.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "0ae3f047bed4edff6fd35b26a9a6bfdc92c953c6" + "reference": "17f50e06018baec41551a71a15731287dbaab186" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/0ae3f047bed4edff6fd35b26a9a6bfdc92c953c6", - "reference": "0ae3f047bed4edff6fd35b26a9a6bfdc92c953c6", + "url": "https://api.github.com/repos/symfony/finder/zipball/17f50e06018baec41551a71a15731287dbaab186", + "reference": "17f50e06018baec41551a71a15731287dbaab186", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -5103,7 +5290,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.3.0" + "source": "https://github.com/symfony/finder/tree/v5.3.4" }, "funding": [ { @@ -5119,7 +5306,7 @@ "type": "tidelift" } ], - "time": "2021-05-26T12:52:38+00:00" + "time": "2021-07-23T15:54:19+00:00" }, { "name": "symfony/http-client-contracts", @@ -5201,23 +5388,23 @@ }, { "name": "symfony/http-foundation", - "version": "v5.3.3", + "version": "v5.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "0e45ab1574caa0460d9190871a8ce47539e40ccf" + "reference": "a8388f7b7054a7401997008ce9cd8c6b0ab7ac75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0e45ab1574caa0460d9190871a8ce47539e40ccf", - "reference": "0e45ab1574caa0460d9190871a8ce47539e40ccf", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a8388f7b7054a7401997008ce9cd8c6b0ab7ac75", + "reference": "a8388f7b7054a7401997008ce9cd8c6b0ab7ac75", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "predis/predis": "~1.0", @@ -5254,7 +5441,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.3.3" + "source": "https://github.com/symfony/http-foundation/tree/v5.3.6" }, "funding": [ { @@ -5270,25 +5457,25 @@ "type": "tidelift" } ], - "time": "2021-06-27T09:19:40+00:00" + "time": "2021-07-27T17:08:17+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.3.3", + "version": "v5.3.6", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "90ad9f4b21ddcb8ebe9faadfcca54929ad23f9f8" + "reference": "60030f209018356b3b553b9dbd84ad2071c1b7e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/90ad9f4b21ddcb8ebe9faadfcca54929ad23f9f8", - "reference": "90ad9f4b21ddcb8ebe9faadfcca54929ad23f9f8", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/60030f209018356b3b553b9dbd84ad2071c1b7e0", + "reference": "60030f209018356b3b553b9dbd84ad2071c1b7e0", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4|^5.0", "symfony/event-dispatcher": "^5.0", @@ -5296,7 +5483,7 @@ "symfony/http-foundation": "^5.3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/browser-kit": "<4.4", @@ -5315,7 +5502,7 @@ "twig/twig": "<2.13" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", @@ -5366,7 +5553,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.3.3" + "source": "https://github.com/symfony/http-kernel/tree/v5.3.6" }, "funding": [ { @@ -5382,20 +5569,20 @@ "type": "tidelift" } ], - "time": "2021-06-30T08:27:49+00:00" + "time": "2021-07-29T07:06:27+00:00" }, { "name": "symfony/mime", - "version": "v5.3.2", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "47dd7912152b82d0d4c8d9040dbc93d6232d472a" + "reference": "633e4e8afe9e529e5599d71238849a4218dd497b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/47dd7912152b82d0d4c8d9040dbc93d6232d472a", - "reference": "47dd7912152b82d0d4c8d9040dbc93d6232d472a", + "url": "https://api.github.com/repos/symfony/mime/zipball/633e4e8afe9e529e5599d71238849a4218dd497b", + "reference": "633e4e8afe9e529e5599d71238849a4218dd497b", "shasum": "" }, "require": { @@ -5403,7 +5590,7 @@ "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-intl-idn": "^1.10", "symfony/polyfill-mbstring": "^1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "egulias/email-validator": "~3.0.0", @@ -5449,7 +5636,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.3.2" + "source": "https://github.com/symfony/mime/tree/v5.3.4" }, "funding": [ { @@ -5465,7 +5652,7 @@ "type": "tidelift" } ], - "time": "2021-06-09T10:58:01+00:00" + "time": "2021-07-21T12:40:44+00:00" }, { "name": "symfony/polyfill-ctype", @@ -5628,16 +5815,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.23.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "24b72c6baa32c746a4d0840147c9715e42bb68ab" + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/24b72c6baa32c746a4d0840147c9715e42bb68ab", - "reference": "24b72c6baa32c746a4d0840147c9715e42bb68ab", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", "shasum": "" }, "require": { @@ -5689,7 +5876,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" }, "funding": [ { @@ -5705,7 +5892,7 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:17:38+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -5880,16 +6067,16 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1", - "reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -5940,7 +6127,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" }, "funding": [ { @@ -5956,7 +6143,7 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:27:20+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-php72", @@ -6115,16 +6302,16 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.23.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0" + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0", - "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "shasum": "" }, "require": { @@ -6178,7 +6365,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" }, "funding": [ { @@ -6194,25 +6381,104 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2021-07-28T13:41:28+00:00" }, { - "name": "symfony/process", - "version": "v5.3.2", + "name": "symfony/polyfill-php81", + "version": "v1.23.0", "source": { "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "714b47f9196de61a196d86c4bad5f09201b307df" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "e66119f3de95efc359483f810c4c3e6436279436" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/714b47f9196de61a196d86c4bad5f09201b307df", - "reference": "714b47f9196de61a196d86c4bad5f09201b307df", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", + "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-05-21T13:25:03+00:00" + }, + { + "name": "symfony/process", + "version": "v5.3.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "d16634ee55b895bd85ec714dadc58e4428ecf030" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/d16634ee55b895bd85ec714dadc58e4428ecf030", + "reference": "d16634ee55b895bd85ec714dadc58e4428ecf030", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -6240,7 +6506,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.3.2" + "source": "https://github.com/symfony/process/tree/v5.3.4" }, "funding": [ { @@ -6256,20 +6522,20 @@ "type": "tidelift" } ], - "time": "2021-06-12T10:15:01+00:00" + "time": "2021-07-23T15:54:19+00:00" }, { "name": "symfony/psr-http-message-bridge", - "version": "v2.1.0", + "version": "v2.1.1", "source": { "type": "git", "url": "https://github.com/symfony/psr-http-message-bridge.git", - "reference": "81db2d4ae86e9f0049828d9343a72b9523884e5d" + "reference": "c9012994c4b4fb23e7c57dd86b763a417a04feba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/81db2d4ae86e9f0049828d9343a72b9523884e5d", - "reference": "81db2d4ae86e9f0049828d9343a72b9523884e5d", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/c9012994c4b4fb23e7c57dd86b763a417a04feba", + "reference": "c9012994c4b4fb23e7c57dd86b763a417a04feba", "shasum": "" }, "require": { @@ -6279,7 +6545,7 @@ }, "require-dev": { "nyholm/psr7": "^1.1", - "psr/log": "^1.1", + "psr/log": "^1.1 || ^2 || ^3", "symfony/browser-kit": "^4.4 || ^5.0", "symfony/config": "^4.4 || ^5.0", "symfony/event-dispatcher": "^4.4 || ^5.0", @@ -6328,7 +6594,7 @@ ], "support": { "issues": "https://github.com/symfony/psr-http-message-bridge/issues", - "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.0" + "source": "https://github.com/symfony/psr-http-message-bridge/tree/v2.1.1" }, "funding": [ { @@ -6344,26 +6610,26 @@ "type": "tidelift" } ], - "time": "2021-02-17T10:35:25+00:00" + "time": "2021-07-27T17:25:39+00:00" }, { "name": "symfony/routing", - "version": "v5.3.0", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "368e81376a8e049c37cb80ae87dbfbf411279199" + "reference": "0a35d2f57d73c46ab6d042ced783b81d09a624c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/368e81376a8e049c37cb80ae87dbfbf411279199", - "reference": "368e81376a8e049c37cb80ae87dbfbf411279199", + "url": "https://api.github.com/repos/symfony/routing/zipball/0a35d2f57d73c46ab6d042ced783b81d09a624c4", + "reference": "0a35d2f57d73c46ab6d042ced783b81d09a624c4", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "doctrine/annotations": "<1.12", @@ -6373,7 +6639,7 @@ }, "require-dev": { "doctrine/annotations": "^1.12", - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^5.3", "symfony/dependency-injection": "^4.4|^5.0", "symfony/expression-language": "^4.4|^5.0", @@ -6418,7 +6684,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.3.0" + "source": "https://github.com/symfony/routing/tree/v5.3.4" }, "funding": [ { @@ -6434,7 +6700,7 @@ "type": "tidelift" } ], - "time": "2021-05-26T17:43:10+00:00" + "time": "2021-07-23T15:55:36+00:00" }, { "name": "symfony/service-contracts", @@ -6600,23 +6866,23 @@ }, { "name": "symfony/translation", - "version": "v5.3.3", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "380b8c9e944d0e364b25f28e8e555241eb49c01c" + "reference": "d89ad7292932c2699cbe4af98d72c5c6bbc504c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/380b8c9e944d0e364b25f28e8e555241eb49c01c", - "reference": "380b8c9e944d0e364b25f28e8e555241eb49c01c", + "url": "https://api.github.com/repos/symfony/translation/zipball/d89ad7292932c2699cbe4af98d72c5c6bbc504c1", + "reference": "d89ad7292932c2699cbe4af98d72c5c6bbc504c1", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/translation-contracts": "^2.3" }, "conflict": { @@ -6630,7 +6896,7 @@ "symfony/translation-implementation": "2.3" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^4.4|^5.0", "symfony/console": "^4.4|^5.0", "symfony/dependency-injection": "^5.0", @@ -6675,7 +6941,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.3.3" + "source": "https://github.com/symfony/translation/tree/v5.3.4" }, "funding": [ { @@ -6691,7 +6957,7 @@ "type": "tidelift" } ], - "time": "2021-06-27T12:22:47+00:00" + "time": "2021-07-25T09:39:16+00:00" }, { "name": "symfony/translation-contracts", @@ -6773,22 +7039,22 @@ }, { "name": "symfony/var-dumper", - "version": "v5.3.3", + "version": "v5.3.6", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "46aa709affb9ad3355bd7a810f9662d71025c384" + "reference": "3dd8ddd1e260e58ecc61bb78da3b6584b3bfcba0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/46aa709affb9ad3355bd7a810f9662d71025c384", - "reference": "46aa709affb9ad3355bd7a810f9662d71025c384", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/3dd8ddd1e260e58ecc61bb78da3b6584b3bfcba0", + "reference": "3dd8ddd1e260e58ecc61bb78da3b6584b3bfcba0", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "phpunit/phpunit": "<5.4.3", @@ -6841,7 +7107,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.3" + "source": "https://github.com/symfony/var-dumper/tree/v5.3.6" }, "funding": [ { @@ -6857,61 +7123,7 @@ "type": "tidelift" } ], - "time": "2021-06-24T08:13:00+00:00" - }, - { - "name": "tightenco/collect", - "version": "v8.34.0", - "source": { - "type": "git", - "url": "https://github.com/tighten/collect.git", - "reference": "b069783ab0c547bb894ebcf8e7f6024bb401f9d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/tighten/collect/zipball/b069783ab0c547bb894ebcf8e7f6024bb401f9d2", - "reference": "b069783ab0c547bb894ebcf8e7f6024bb401f9d2", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0", - "symfony/var-dumper": "^3.4 || ^4.0 || ^5.0" - }, - "require-dev": { - "mockery/mockery": "^1.0", - "nesbot/carbon": "^2.23.0", - "phpunit/phpunit": "^8.3" - }, - "type": "library", - "autoload": { - "files": [ - "src/Collect/Support/helpers.php", - "src/Collect/Support/alias.php" - ], - "psr-4": { - "Tightenco\\Collect\\": "src/Collect" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Taylor Otwell", - "email": "taylorotwell@gmail.com" - } - ], - "description": "Collect - Illuminate Collections as a separate package.", - "keywords": [ - "collection", - "laravel" - ], - "support": { - "issues": "https://github.com/tighten/collect/issues", - "source": "https://github.com/tighten/collect/tree/v8.34.0" - }, - "time": "2021-03-29T21:29:00+00:00" + "time": "2021-07-27T01:56:02+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -7564,16 +7776,16 @@ }, { "name": "composer/composer", - "version": "2.1.3", + "version": "2.1.5", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "fc5c4573aafce3a018eb7f1f8f91cea423970f2e" + "reference": "ac679902e9f66b85a8f9d8c1c88180f609a8745d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/fc5c4573aafce3a018eb7f1f8f91cea423970f2e", - "reference": "fc5c4573aafce3a018eb7f1f8f91cea423970f2e", + "url": "https://api.github.com/repos/composer/composer/zipball/ac679902e9f66b85a8f9d8c1c88180f609a8745d", + "reference": "ac679902e9f66b85a8f9d8c1c88180f609a8745d", "shasum": "" }, "require": { @@ -7582,7 +7794,7 @@ "composer/semver": "^3.0", "composer/spdx-licenses": "^1.2", "composer/xdebug-handler": "^2.0", - "justinrainbow/json-schema": "^5.2.10", + "justinrainbow/json-schema": "^5.2.11", "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1.0", "react/promise": "^1.2 || ^2.7", @@ -7642,7 +7854,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.1.3" + "source": "https://github.com/composer/composer/tree/2.1.5" }, "funding": [ { @@ -7658,7 +7870,7 @@ "type": "tidelift" } ], - "time": "2021-06-09T14:31:20+00:00" + "time": "2021-07-23T08:35:47+00:00" }, { "name": "composer/metadata-minifier", @@ -7891,21 +8103,21 @@ }, { "name": "composer/xdebug-handler", - "version": "2.0.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "964adcdd3a28bf9ed5d9ac6450064e0d71ed7496" + "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/964adcdd3a28bf9ed5d9ac6450064e0d71ed7496", - "reference": "964adcdd3a28bf9ed5d9ac6450064e0d71ed7496", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339", + "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0" + "psr/log": "^1 || ^2 || ^3" }, "require-dev": { "phpstan/phpstan": "^0.12.55", @@ -7935,7 +8147,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.1" + "source": "https://github.com/composer/xdebug-handler/tree/2.0.2" }, "funding": [ { @@ -7951,7 +8163,7 @@ "type": "tidelift" } ], - "time": "2021-05-05T19:37:51+00:00" + "time": "2021-07-31T17:03:58+00:00" }, { "name": "doctrine/instantiator", @@ -8101,16 +8313,16 @@ }, { "name": "fakerphp/faker", - "version": "v1.14.1", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/FakerPHP/Faker.git", - "reference": "ed22aee8d17c7b396f74a58b1e7fefa4f90d5ef1" + "reference": "89c6201c74db25fa759ff16e78a4d8f32547770e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/ed22aee8d17c7b396f74a58b1e7fefa4f90d5ef1", - "reference": "ed22aee8d17c7b396f74a58b1e7fefa4f90d5ef1", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/89c6201c74db25fa759ff16e78a4d8f32547770e", + "reference": "89c6201c74db25fa759ff16e78a4d8f32547770e", "shasum": "" }, "require": { @@ -8160,22 +8372,22 @@ ], "support": { "issues": "https://github.com/FakerPHP/Faker/issues", - "source": "https://github.com/FakerPHP/Faker/tree/v.1.14.1" + "source": "https://github.com/FakerPHP/Faker/tree/v1.15.0" }, - "time": "2021-03-30T06:27:33+00:00" + "time": "2021-07-06T20:39:40+00:00" }, { "name": "filp/whoops", - "version": "2.13.0", + "version": "2.14.0", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "2edbc73a4687d9085c8f20f398eebade844e8424" + "reference": "fdf92f03e150ed84d5967a833ae93abffac0315b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/2edbc73a4687d9085c8f20f398eebade844e8424", - "reference": "2edbc73a4687d9085c8f20f398eebade844e8424", + "url": "https://api.github.com/repos/filp/whoops/zipball/fdf92f03e150ed84d5967a833ae93abffac0315b", + "reference": "fdf92f03e150ed84d5967a833ae93abffac0315b", "shasum": "" }, "require": { @@ -8225,7 +8437,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.13.0" + "source": "https://github.com/filp/whoops/tree/2.14.0" }, "funding": [ { @@ -8233,7 +8445,7 @@ "type": "github" } ], - "time": "2021-06-04T12:00:00+00:00" + "time": "2021-07-13T12:00:00+00:00" }, { "name": "hamcrest/hamcrest-php", @@ -8288,16 +8500,16 @@ }, { "name": "justinrainbow/json-schema", - "version": "5.2.10", + "version": "5.2.11", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ab6744b7296ded80f8cc4f9509abbff393399aa", + "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa", "shasum": "" }, "require": { @@ -8352,22 +8564,22 @@ ], "support": { "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.10" + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.11" }, - "time": "2020-05-27T16:41:55+00:00" + "time": "2021-07-22T09:24:00+00:00" }, { "name": "maximebf/debugbar", - "version": "v1.16.5", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/maximebf/php-debugbar.git", - "reference": "6d51ee9e94cff14412783785e79a4e7ef97b9d62" + "reference": "0a3532556be0145603f8a9de23e76dc28eed7054" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/6d51ee9e94cff14412783785e79a4e7ef97b9d62", - "reference": "6d51ee9e94cff14412783785e79a4e7ef97b9d62", + "url": "https://api.github.com/repos/maximebf/php-debugbar/zipball/0a3532556be0145603f8a9de23e76dc28eed7054", + "reference": "0a3532556be0145603f8a9de23e76dc28eed7054", "shasum": "" }, "require": { @@ -8386,7 +8598,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.16-dev" + "dev-master": "1.17-dev" } }, "autoload": { @@ -8417,9 +8629,9 @@ ], "support": { "issues": "https://github.com/maximebf/php-debugbar/issues", - "source": "https://github.com/maximebf/php-debugbar/tree/v1.16.5" + "source": "https://github.com/maximebf/php-debugbar/tree/v1.17.1" }, - "time": "2020-12-07T11:07:24+00:00" + "time": "2021-08-01T09:19:02+00:00" }, { "name": "mockery/mockery", @@ -8553,16 +8765,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.10.5", + "version": "v4.12.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4432ba399e47c66624bc73c8c0f811e5c109576f" + "reference": "6608f01670c3cc5079e18c1dab1104e002579143" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4432ba399e47c66624bc73c8c0f811e5c109576f", - "reference": "4432ba399e47c66624bc73c8c0f811e5c109576f", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", + "reference": "6608f01670c3cc5079e18c1dab1104e002579143", "shasum": "" }, "require": { @@ -8603,22 +8815,22 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.10.5" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" }, - "time": "2021-05-03T19:11:20+00:00" + "time": "2021-07-21T10:44:31+00:00" }, { "name": "nunomaduro/larastan", - "version": "v0.7.8", + "version": "v0.7.12", "source": { "type": "git", "url": "https://github.com/nunomaduro/larastan.git", - "reference": "dc05566a2e7c53049b52223ba45689ecde691206" + "reference": "b2da312efe88d501aeeb867ba857e8c4198d43c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/dc05566a2e7c53049b52223ba45689ecde691206", - "reference": "dc05566a2e7c53049b52223ba45689ecde691206", + "url": "https://api.github.com/repos/nunomaduro/larastan/zipball/b2da312efe88d501aeeb867ba857e8c4198d43c0", + "reference": "b2da312efe88d501aeeb867ba857e8c4198d43c0", "shasum": "" }, "require": { @@ -8634,7 +8846,7 @@ "mockery/mockery": "^0.9 || ^1.0", "php": "^7.2 || ^8.0", "phpstan/phpstan": "^0.12.90", - "symfony/process": "^4.3 || ^5.0" + "symfony/process": "^4.3 || ^5.0 || ^6.0" }, "require-dev": { "orchestra/testbench": "^4.0 || ^5.0 || ^6.0 || ^7.0", @@ -8682,7 +8894,7 @@ ], "support": { "issues": "https://github.com/nunomaduro/larastan/issues", - "source": "https://github.com/nunomaduro/larastan/tree/v0.7.8" + "source": "https://github.com/nunomaduro/larastan/tree/v0.7.12" }, "funding": [ { @@ -8702,20 +8914,20 @@ "type": "patreon" } ], - "time": "2021-07-02T13:17:34+00:00" + "time": "2021-07-26T12:12:39+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { @@ -8760,9 +8972,9 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" + "source": "https://github.com/phar-io/manifest/tree/2.0.3" }, - "time": "2020-06-27T14:33:11+00:00" + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", @@ -9042,16 +9254,16 @@ }, { "name": "phpstan/phpstan", - "version": "0.12.90", + "version": "0.12.94", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "f0e4b56630fc3d4eb5be86606d07212ac212ede4" + "reference": "3d0ba4c198a24e3c3fc489f3ec6ac9612c4be5d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/f0e4b56630fc3d4eb5be86606d07212ac212ede4", - "reference": "f0e4b56630fc3d4eb5be86606d07212ac212ede4", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3d0ba4c198a24e3c3fc489f3ec6ac9612c4be5d6", + "reference": "3d0ba4c198a24e3c3fc489f3ec6ac9612c4be5d6", "shasum": "" }, "require": { @@ -9082,7 +9294,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/0.12.90" + "source": "https://github.com/phpstan/phpstan/tree/0.12.94" }, "funding": [ { @@ -9102,7 +9314,7 @@ "type": "tidelift" } ], - "time": "2021-06-18T07:15:38+00:00" + "time": "2021-07-30T09:05:27+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -9475,16 +9687,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.6", + "version": "9.5.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb" + "reference": "191768ccd5c85513b4068bdbe99bb6390c7d54fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb", - "reference": "fb9b8333f14e3dce976a60ef6a7e05c7c7ed8bfb", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/191768ccd5c85513b4068bdbe99bb6390c7d54fb", + "reference": "191768ccd5c85513b4068bdbe99bb6390c7d54fb", "shasum": "" }, "require": { @@ -9496,7 +9708,7 @@ "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.1", + "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", @@ -9562,7 +9774,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.6" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.8" }, "funding": [ { @@ -9574,7 +9786,7 @@ "type": "github" } ], - "time": "2021-06-23T05:14:38+00:00" + "time": "2021-07-31T15:17:34+00:00" }, { "name": "react/promise", @@ -9632,12 +9844,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "1a08d0c7ab47e57fad0d254951a615f07445e91f" + "reference": "8bbff2bbc495beeebbc3e1090cfba61184bf8ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/1a08d0c7ab47e57fad0d254951a615f07445e91f", - "reference": "1a08d0c7ab47e57fad0d254951a615f07445e91f", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/8bbff2bbc495beeebbc3e1090cfba61184bf8ab1", + "reference": "8bbff2bbc495beeebbc3e1090cfba61184bf8ab1", "shasum": "" }, "conflict": { @@ -9695,6 +9907,7 @@ "endroid/qr-code-bundle": "<3.4.2", "enshrined/svg-sanitize": "<0.13.1", "erusev/parsedown": "<1.7.2", + "ether/logs": "<3.0.4", "ezsystems/demobundle": ">=5.4,<5.4.6.1", "ezsystems/ez-support-tools": ">=2.2,<2.2.3", "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1", @@ -9725,6 +9938,7 @@ "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", "friendsofsymfony/user-bundle": ">=1.2,<1.3.5", "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", + "froala/wysiwyg-editor": "<3.2.7", "fuel/core": "<1.8.1", "getgrav/grav": "<=1.7.10", "getkirby/cms": "<=3.5.6", @@ -9732,6 +9946,7 @@ "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", "gree/jose": "<=2.2", "gregwar/rst": "<1.0.3", + "grumpydictator/firefly-iii": "<5.5.13", "guzzlehttp/guzzle": ">=4-rc.2,<4.2.4|>=5,<5.3.1|>=6,<6.2.1", "illuminate/auth": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.10", "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.99999|>=4.2,<=4.2.99999|>=5,<=5.0.99999|>=5.1,<=5.1.99999|>=5.2,<=5.2.99999|>=5.3,<=5.3.99999|>=5.4,<=5.4.99999|>=5.5,<=5.5.49|>=5.6,<=5.6.99999|>=5.7,<=5.7.99999|>=5.8,<=5.8.99999|>=6,<6.18.31|>=7,<7.22.4", @@ -9753,11 +9968,13 @@ "laminas/laminas-http": "<2.14.2", "laravel/framework": "<6.20.26|>=7,<8.40", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", + "lavalite/cms": "<=5.8", "league/commonmark": "<0.18.3", "league/flysystem": "<1.1.4|>=2,<2.1.1", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", "librenms/librenms": "<21.1", "livewire/livewire": ">2.2.4,<2.2.6", + "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", "magento/community-edition": ">=2,<2.2.10|>=2.3,<2.3.3", "magento/magento1ce": "<1.9.4.3", "magento/magento1ee": ">=1,<1.14.4.3", @@ -9775,6 +9992,7 @@ "neos/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", + "nilsteampassnet/teampass": "<=2.1.27.36", "nukeviet/nukeviet": "<4.3.4", "nystudio107/craft-seomatic": "<3.3", "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", @@ -9796,7 +10014,7 @@ "paragonie/random_compat": "<2", "passbolt/passbolt_api": "<2.11", "paypal/merchant-sdk-php": "<3.12", - "pear/archive_tar": "<1.4.12", + "pear/archive_tar": "<1.4.14", "personnummer/personnummer": "<3.0.2", "phanan/koel": "<5.1.4", "phpfastcache/phpfastcache": ">=5,<5.0.13", @@ -9809,7 +10027,7 @@ "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", - "pimcore/pimcore": "<6.8.8", + "pimcore/pimcore": "<10.0.7", "pocketmine/pocketmine-mp": "<3.15.4", "pressbooks/pressbooks": "<5.18", "prestashop/autoupgrade": ">=4,<4.10.1", @@ -9907,12 +10125,13 @@ "thelia/thelia": ">=2.1-beta.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "titon/framework": ">=0,<9.9.99", + "topthink/think": "<=6.0.9", "tribalsystems/zenario": "<8.8.53370", "truckersmp/phpwhois": "<=4.3.1", "twig/twig": "<1.38|>=2,<2.7", - "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.25|>=10,<10.4.14|>=11,<11.1.1", + "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.32|>=8,<8.7.38|>=9,<9.5.28|>=10,<10.4.18|>=11,<11.3.1", "typo3/cms-backend": ">=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", - "typo3/cms-core": ">=6.2,<=6.2.56|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<9.5.25|>=10,<10.4.14|>=11,<11.1.1", + "typo3/cms-core": ">=6.2,<=6.2.56|>=7,<7.6.52|>=8,<8.7.41|>=9,<9.5.28|>=10,<10.4.18|>=11,<11.3.1", "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.13|>=11,<=11.1", "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", @@ -9999,7 +10218,7 @@ "type": "tidelift" } ], - "time": "2021-07-02T20:02:51+00:00" + "time": "2021-08-09T21:02:34+00:00" }, { "name": "sebastian/cli-parser", @@ -11078,22 +11297,21 @@ }, { "name": "symfony/debug", - "version": "v4.4.25", + "version": "v4.4.27", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "a8d2d5c94438548bff9f998ca874e202bb29d07f" + "reference": "2f9160e92eb64c95da7368c867b663a8e34e980c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/a8d2d5c94438548bff9f998ca874e202bb29d07f", - "reference": "a8d2d5c94438548bff9f998ca874e202bb29d07f", + "url": "https://api.github.com/repos/symfony/debug/zipball/2f9160e92eb64c95da7368c867b663a8e34e980c", + "reference": "2f9160e92eb64c95da7368c867b663a8e34e980c", "shasum": "" }, "require": { "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/polyfill-php80": "^1.15" + "psr/log": "^1|^2|^3" }, "conflict": { "symfony/http-kernel": "<3.4" @@ -11127,7 +11345,7 @@ "description": "Provides tools to ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug/tree/v4.4.25" + "source": "https://github.com/symfony/debug/tree/v4.4.27" }, "funding": [ { @@ -11143,25 +11361,26 @@ "type": "tidelift" } ], - "time": "2021-05-26T17:39:37+00:00" + "time": "2021-07-22T07:21:39+00:00" }, { "name": "symfony/filesystem", - "version": "v5.3.3", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "19b71c8f313b411172dd5f470fd61f24466d79a9" + "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/19b71c8f313b411172dd5f470fd61f24466d79a9", - "reference": "19b71c8f313b411172dd5f470fd61f24466d79a9", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/343f4fe324383ca46792cae728a3b6e2f708fb32", + "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -11189,7 +11408,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.3.3" + "source": "https://github.com/symfony/filesystem/tree/v5.3.4" }, "funding": [ { @@ -11205,7 +11424,7 @@ "type": "tidelift" } ], - "time": "2021-06-30T07:27:52+00:00" + "time": "2021-07-21T12:40:44+00:00" }, { "name": "thecodingmachine/phpstan-strict-rules", @@ -11264,16 +11483,16 @@ }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { @@ -11302,7 +11521,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/master" + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" }, "funding": [ { @@ -11310,7 +11529,7 @@ "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2021-07-28T10:34:58+00:00" } ], "aliases": [], diff --git a/config/app.php b/config/app.php index a5774e4eba..b789433432 100644 --- a/config/app.php +++ b/config/app.php @@ -21,8 +21,6 @@ declare(strict_types=1); -use FireflyIII\Support\Facades\Telemetry; - return [ 'name' => envNonEmpty('APP_NAME', 'Firefly III'), 'env' => envNonEmpty('APP_ENV', 'local'), @@ -143,7 +141,6 @@ return [ 'AccountForm' => \FireflyIII\Support\Facades\AccountForm::class, 'PiggyBankForm' => \FireflyIII\Support\Facades\PiggyBankForm::class, 'RuleForm' => \FireflyIII\Support\Facades\RuleForm::class, - 'Telemetry' => Telemetry::class, 'Google2FA' => PragmaRX\Google2FALaravel\Facade::class, 'Twig' => TwigBridge\Facade\Twig::class, diff --git a/config/bulk.php b/config/bulk.php new file mode 100644 index 0000000000..22ff667693 --- /dev/null +++ b/config/bulk.php @@ -0,0 +1,15 @@ + [ + ClauseType::WHERE => [ + 'source_account_id' => 'required|numeric|belongsToUser:accounts,id', + ], + ClauseType::UPDATE => [ + 'destination_account_id' => 'required|numeric|belongsToUser:accounts,id', + ], + ], +]; diff --git a/config/firefly.php b/config/firefly.php index b6900a3b7b..71f560d3b2 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -101,7 +101,7 @@ return [ 'webhooks' => true, 'handle_debts' => true, ], - 'version' => '5.6.0-alpha.1', + 'version' => '5.6.0-alpha.2', 'api_version' => '1.5.3', 'db_version' => 17, @@ -120,7 +120,6 @@ return [ 'enable_external_map' => env('ENABLE_EXTERNAL_MAP', false), 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), 'disable_csp_header' => env('DISABLE_CSP_HEADER', false), - 'send_telemetry' => env('SEND_TELEMETRY', false), 'allow_webhooks' => env('ALLOW_WEBHOOKS', false), // email flags @@ -134,7 +133,6 @@ return [ 'tracker_site_id' => env('TRACKER_SITE_ID', ''), 'tracker_url' => env('TRACKER_URL', ''), - // LDAP and authentication settings 'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), @@ -143,9 +141,51 @@ return [ // static config (cannot be changed by user) 'update_endpoint' => 'https://version.firefly-iii.org/index.json', - 'telemetry_endpoint' => 'https://telemetry.firefly-iii.org', 'update_minimum_age' => 7, + // enabled languages + 'languages' => [ + // currently enabled languages + 'bg_BG' => ['name_locale' => 'Български', 'name_english' => 'Bulgarian'], + // 'ca_ES' => ['name_locale' => 'Catalan', 'name_english' => 'Catalan'], + 'cs_CZ' => ['name_locale' => 'Czech', 'name_english' => 'Czech'], + // 'da_DK' => ['name_locale' => 'Danish', 'name_english' => 'Danish'], + 'de_DE' => ['name_locale' => 'Deutsch', 'name_english' => 'German'], + 'el_GR' => ['name_locale' => 'Ελληνικά', 'name_english' => 'Greek'], + 'en_GB' => ['name_locale' => 'English (GB)', 'name_english' => 'English (GB)'], + 'en_US' => ['name_locale' => 'English (US)', 'name_english' => 'English (US)'], + 'es_ES' => ['name_locale' => 'Español', 'name_english' => 'Spanish'], + // 'et_EE' => ['name_locale' => 'Estonian', 'name_english' => 'Estonian'], + // 'fa_IR' => ['name_locale' => 'فارسی', 'name_english' => 'Persian'], + 'fi_FI' => ['name_locale' => 'Suomi', 'name_english' => 'Finnish'], + 'fr_FR' => ['name_locale' => 'Français', 'name_english' => 'French'], + // 'he_IL' => ['name_locale' => 'Hebrew', 'name_english' => 'Hebrew'], + 'hu_HU' => ['name_locale' => 'Hungarian', 'name_english' => 'Hungarian'], + // 'id_ID' => ['name_locale' => 'Bahasa Indonesia', 'name_english' => 'Indonesian'], + // 'is_IS' => ['name_locale' => 'Icelandic', 'name_english' => 'Icelandic'], + 'it_IT' => ['name_locale' => 'Italiano', 'name_english' => 'Italian'], + 'ja_JP' => ['name_locale' => 'Japanese', 'name_english' => 'Japanese'], + // 'lt_LT' => ['name_locale' => 'Lietuvių', 'name_english' => 'Lithuanian'], + 'nb_NO' => ['name_locale' => 'Norsk', 'name_english' => 'Norwegian'], + 'nl_NL' => ['name_locale' => 'Nederlands', 'name_english' => 'Dutch'], + 'pl_PL' => ['name_locale' => 'Polski', 'name_english' => 'Polish '], + 'pt_BR' => ['name_locale' => 'Português do Brasil', 'name_english' => 'Portuguese (Brazil)'], + 'pt_PT' => ['name_locale' => 'Português', 'name_english' => 'Portuguese'], + 'ro_RO' => ['name_locale' => 'Română', 'name_english' => 'Romanian'], + 'ru_RU' => ['name_locale' => 'Русский', 'name_english' => 'Russian'], + // 'si_LK' => ['name_locale' => 'සිංහල', 'name_english' => 'Sinhala (Sri Lanka)'], + 'sk_SK' => ['name_locale' => 'Slovenčina', 'name_english' => 'Slovak'], + // 'sl_SI' => ['name_locale' => 'Slovenian', 'name_english' => 'Slovenian'], + // 'sr_CS' => ['name_locale' => 'Serbian (Latin)', 'name_english' => 'Serbian (Latin)'], + 'sv_SE' => ['name_locale' => 'Svenska', 'name_english' => 'Swedish'], + // 'tlh_AA' => ['name_locale' => 'tlhIngan Hol', 'name_english' => 'Klingon'], + // 'tr_TR' => ['name_locale' => 'Türkçe', 'name_english' => 'Turkish'], + // 'uk_UA' => ['name_locale' => 'Ukranian', 'name_english' => 'Ukranian'], + 'vi_VN' => ['name_locale' => 'Tiếng Việt', 'name_english' => 'Vietnamese'], + 'zh_TW' => ['name_locale' => 'Chinese Traditional', 'name_english' => 'Chinese Traditional'], + 'zh_CN' => ['name_locale' => 'Chinese Simplified', 'name_english' => 'Chinese Simplified'], + ], + // web configuration: 'trusted_proxies' => env('TRUSTED_PROXIES', ''), 'layout' => envNonEmpty('FIREFLY_III_LAYOUT', 'v1'), @@ -157,8 +197,20 @@ return [ 'zoom_level' => env('MAP_DEFAULT_ZOOM', '6'), ], - // internal Firefly III configuration: - // edit me = peligro de muerte + // default user-related values + 'list_length' => 10, // to be removed if v1 is cancelled. + 'default_preferences' => [ + 'frontPageAccounts' => [], + 'listPageSize' => 50, + 'currencyPreference' => 'EUR', + 'language' => 'en_US', + 'locale' => 'equal', + ], + 'default_currency' => 'EUR', + 'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'), + 'default_locale' => envNonEmpty('DEFAULT_LOCALE', 'equal'), + + // "value must be in this list" values 'valid_attachment_models' => [ Account::class, Bill::class, @@ -170,7 +222,6 @@ return [ TransactionJournal::class, Recurrence::class, ], - 'allowed_sort_parameters' => ['order', 'name', 'iban'], 'allowedMimes' => [ /* plain files */ 'text/plain', @@ -232,14 +283,16 @@ return [ 'application/vnd.oasis.opendocument.database', 'application/vnd.oasis.opendocument.image', ], - 'list_length' => 10, // to be removed if v1 is cancelled. - 'bill_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], - 'interest_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], 'accountRoles' => ['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset', 'cashWalletAsset'], 'valid_liabilities' => [AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE], - 'ccTypes' => [ - 'monthlyFull' => 'Full payment every month', - ], + 'ccTypes' => ['monthlyFull' => 'Full payment every month',], + 'credit_card_types' => ['monthlyFull'], + + // "period must be in this list" values + 'bill_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], + 'interest_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], + + // settings to translate X to Y 'range_to_repeat_freq' => [ '1D' => 'weekly', '1W' => 'weekly', @@ -313,50 +366,6 @@ return [ AccountType::DEBT => AccountType::DEBT, AccountType::MORTGAGE => AccountType::MORTGAGE, ], - /** - * Languages configuration. - */ - 'languages' => [ - // currently enabled languages - 'bg_BG' => ['name_locale' => 'Български', 'name_english' => 'Bulgarian'], - // 'ca_ES' => ['name_locale' => 'Catalan', 'name_english' => 'Catalan'], - 'cs_CZ' => ['name_locale' => 'Czech', 'name_english' => 'Czech'], - // 'da_DK' => ['name_locale' => 'Danish', 'name_english' => 'Danish'], - 'de_DE' => ['name_locale' => 'Deutsch', 'name_english' => 'German'], - 'el_GR' => ['name_locale' => 'Ελληνικά', 'name_english' => 'Greek'], - 'en_GB' => ['name_locale' => 'English (GB)', 'name_english' => 'English (GB)'], - 'en_US' => ['name_locale' => 'English (US)', 'name_english' => 'English (US)'], - 'es_ES' => ['name_locale' => 'Español', 'name_english' => 'Spanish'], - // 'et_EE' => ['name_locale' => 'Estonian', 'name_english' => 'Estonian'], - // 'fa_IR' => ['name_locale' => 'فارسی', 'name_english' => 'Persian'], - 'fi_FI' => ['name_locale' => 'Suomi', 'name_english' => 'Finnish'], - 'fr_FR' => ['name_locale' => 'Français', 'name_english' => 'French'], - // 'he_IL' => ['name_locale' => 'Hebrew', 'name_english' => 'Hebrew'], - 'hu_HU' => ['name_locale' => 'Hungarian', 'name_english' => 'Hungarian'], - // 'id_ID' => ['name_locale' => 'Bahasa Indonesia', 'name_english' => 'Indonesian'], - // 'is_IS' => ['name_locale' => 'Icelandic', 'name_english' => 'Icelandic'], - 'it_IT' => ['name_locale' => 'Italiano', 'name_english' => 'Italian'], - // 'ja_JA' => ['name_locale' => 'Japanese', 'name_english' => 'Japanese'], - // 'lt_LT' => ['name_locale' => 'Lietuvių', 'name_english' => 'Lithuanian'], - 'nb_NO' => ['name_locale' => 'Norsk', 'name_english' => 'Norwegian'], - 'nl_NL' => ['name_locale' => 'Nederlands', 'name_english' => 'Dutch'], - 'pl_PL' => ['name_locale' => 'Polski', 'name_english' => 'Polish '], - 'pt_BR' => ['name_locale' => 'Português do Brasil', 'name_english' => 'Portuguese (Brazil)'], - 'pt_PT' => ['name_locale' => 'Português', 'name_english' => 'Portuguese'], - 'ro_RO' => ['name_locale' => 'Română', 'name_english' => 'Romanian'], - 'ru_RU' => ['name_locale' => 'Русский', 'name_english' => 'Russian'], - // 'si_LK' => ['name_locale' => 'සිංහල', 'name_english' => 'Sinhala (Sri Lanka)'], - 'sk_SK' => ['name_locale' => 'Slovenčina', 'name_english' => 'Slovak'], - // 'sl_SI' => ['name_locale' => 'Slovenian', 'name_english' => 'Slovenian'], - // 'sr_CS' => ['name_locale' => 'Serbian (Latin)', 'name_english' => 'Serbian (Latin)'], - 'sv_SE' => ['name_locale' => 'Svenska', 'name_english' => 'Swedish'], - // 'tlh_AA' => ['name_locale' => 'tlhIngan Hol', 'name_english' => 'Klingon'], - // 'tr_TR' => ['name_locale' => 'Türkçe', 'name_english' => 'Turkish'], - // 'uk_UA' => ['name_locale' => 'Ukranian', 'name_english' => 'Ukranian'], - 'vi_VN' => ['name_locale' => 'Tiếng Việt', 'name_english' => 'Vietnamese'], - 'zh_TW' => ['name_locale' => 'Chinese Traditional', 'name_english' => 'Chinese Traditional'], - 'zh_CN' => ['name_locale' => 'Chinese Simplified', 'name_english' => 'Chinese Simplified'], - ], 'transactionTypesByType' => [ 'expenses' => ['Withdrawal'], 'withdrawal' => ['Withdrawal'], @@ -379,8 +388,8 @@ return [ 'deposit' => 'fa-long-arrow-right', 'transfer' => 'fa-exchange', 'transfers' => 'fa-exchange', - ], + 'bindables' => [ // models 'account' => Account::class, @@ -480,9 +489,7 @@ return [ 'limit' => 10, 'range' => 200, ], - 'default_currency' => 'EUR', - 'default_language' => envNonEmpty('DEFAULT_LANGUAGE', 'en_US'), - 'default_locale' => envNonEmpty('DEFAULT_LOCALE', 'equal'), + 'search' => [ 'operators' => [ @@ -654,14 +661,15 @@ return [ // expected source types for each transaction type, in order of preference. 'expected_source_types' => [ 'source' => [ - TransactionTypeModel::WITHDRAWAL => [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], - TransactionTypeModel::DEPOSIT => [AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], - TransactionTypeModel::TRANSFER => [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], - TransactionTypeModel::OPENING_BALANCE => [AccountType::INITIAL_BALANCE, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, - AccountType::MORTGAGE,], - TransactionTypeModel::RECONCILIATION => [AccountType::RECONCILIATION, AccountType::ASSET], + TransactionTypeModel::WITHDRAWAL => [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], + TransactionTypeModel::DEPOSIT => [AccountType::REVENUE, AccountType::CASH, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], + TransactionTypeModel::TRANSFER => [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], + TransactionTypeModel::OPENING_BALANCE => [AccountType::INITIAL_BALANCE, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, + AccountType::MORTGAGE,], + TransactionTypeModel::RECONCILIATION => [AccountType::RECONCILIATION, AccountType::ASSET], + TransactionTypeModel::LIABILITY_CREDIT => [AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE], // in case no transaction type is known yet, it could be anything. - 'none' => [ + 'none' => [ AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE, @@ -890,11 +898,7 @@ return [ 'valid_asset_fields' => ['account_role', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], 'valid_cc_fields' => ['account_role', 'cc_monthly_payment_date', 'cc_type', 'account_number', 'currency_id', 'BIC', 'include_net_worth'], 'valid_account_fields' => ['account_number', 'currency_id', 'BIC', 'interest', 'interest_period', 'include_net_worth', 'liability_direction'], - 'default_preferences' => [ - 'frontPageAccounts' => [], - 'listPageSize' => 50, - 'currencyPreference' => 'EUR', - 'language' => 'en_US', - 'locale' => 'equal', - ], + + // only used in v1 + 'allowed_sort_parameters' => ['order', 'name', 'iban'], ]; diff --git a/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php b/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php index 7ae7fda50e..17d54fa8bd 100644 --- a/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php +++ b/database/migrations/2021_05_09_064644_add_ldap_columns_to_users_table.php @@ -1,29 +1,54 @@ . + */ + declare(strict_types=1); -use Illuminate\Support\Facades\Schema; -use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; +use Illuminate\Database\Schema\Blueprint; +use Illuminate\Support\Facades\Schema; class AddLdapColumnsToUsersTable extends Migration { - /** - * Run the migrations. - */ - public function up() - { - Schema::table('users', function (Blueprint $table) { - $table->string('domain')->nullable(); - }); - } - /** * Reverse the migrations. */ public function down() { - Schema::table('users', function (Blueprint $table) { + Schema::table( + 'users', function (Blueprint $table) { $table->dropColumn(['domain']); - }); + } + ); + } + + /** + * Run the migrations. + */ + public function up() + { + Schema::table( + 'users', function (Blueprint $table) { + $table->string('domain')->nullable(); + } + ); } } diff --git a/database/migrations/2021_05_13_053836_extend_currency_info.php b/database/migrations/2021_05_13_053836_extend_currency_info.php index f5fdacddc2..1eeea51fa5 100644 --- a/database/migrations/2021_05_13_053836_extend_currency_info.php +++ b/database/migrations/2021_05_13_053836_extend_currency_info.php @@ -1,4 +1,25 @@ . + */ + declare(strict_types=1); use Illuminate\Database\Migrations\Migration; diff --git a/app/Events/StoredTransactionLink.php b/database/migrations/2021_07_05_193044_drop_tele_table.php similarity index 61% rename from app/Events/StoredTransactionLink.php rename to database/migrations/2021_07_05_193044_drop_tele_table.php index 6bce61a13b..2d5f7e8823 100644 --- a/app/Events/StoredTransactionLink.php +++ b/database/migrations/2021_07_05_193044_drop_tele_table.php @@ -1,7 +1,8 @@ link = $link; + Schema::dropIfExists('telemetry'); } } diff --git a/frontend/mix-manifest.json b/frontend/mix-manifest.json index 942b7d10f9..ea8b85ae3e 100644 --- a/frontend/mix-manifest.json +++ b/frontend/mix-manifest.json @@ -4,6 +4,9 @@ "/public/js/accounts/delete.js": "/public/js/accounts/delete.js", "/public/js/accounts/show.js": "/public/js/accounts/show.js", "/public/js/accounts/create.js": "/public/js/accounts/create.js", + "/public/js/accounts/edit.js": "/public/js/accounts/edit.js", + "/public/js/bills/index.js": "/public/js/bills/index.js", + "/public/js/bills/create.js": "/public/js/bills/create.js", "/public/js/budgets/index.js": "/public/js/budgets/index.js", "/public/js/transactions/create.js": "/public/js/transactions/create.js", "/public/js/transactions/edit.js": "/public/js/transactions/edit.js", diff --git a/frontend/package.json b/frontend/package.json index 5012e2d193..6e41a78825 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,16 +17,17 @@ "lodash.clonedeep": "^4.5.0", "postcss": "^8.1.14", "resolve-url-loader": "^4.0.0", - "sass": "^1.32.8", + "sass": "^1.37.0", "sass-loader": "^12.0.0", "vue-i18n": "^8.24.2", - "vue-loader": "^15.9.5", + "vue-loader": "^15", "vue-template-compiler": "^2.6.12", "vuex": "^3.6.2", "webpack": "^5.40.0" }, "dependencies": { "@fortawesome/fontawesome-free": "^5.15.3", + "@johmun/vue-tags-input": "^2.1.0", "admin-lte": "^3.1.0", "axios-cache-adapter": "^2.7.3", "bootstrap": "^4.6.0", @@ -38,8 +39,9 @@ "localforage": "^1.9.0", "localforage-memoryStorageDriver": "^0.9.2", "overlayscrollbars": "^1.13.1", - "sortablejs": "^1.13.0", - "v-calendar": "^2.3.0", + "sortablejs": "^1.14.0", + "uiv": "^1.3.1", + "v-calendar": "^2.3.2", "vue-typeahead-bootstrap": "^2.8.0", "vue2-leaflet": "^2.7.1" } diff --git a/frontend/src/bootstrap-basic.js b/frontend/src/bootstrap-basic.js index b6c4373020..9ff4a456d2 100644 --- a/frontend/src/bootstrap-basic.js +++ b/frontend/src/bootstrap-basic.js @@ -23,5 +23,4 @@ window.$ = window.jQuery = require('jquery'); // admin stuff -//require('bootstrap'); - +require('bootstrap'); diff --git a/frontend/src/components/accounts/Create.vue b/frontend/src/components/accounts/Create.vue index 1959e40ede..b6adb10ad5 100644 --- a/frontend/src/components/accounts/Create.vue +++ b/frontend/src/components/accounts/Create.vue @@ -34,9 +34,17 @@
- {{ $t('form.permDeleteWarning') }} + {{ $t('form.permDeleteWarning') }}
@@ -91,7 +91,6 @@ export default {
},
created() {
let pathName = window.location.pathname;
- // console.log(pathName);
let parts = pathName.split('/');
this.accountId = parseInt(parts[parts.length - 1]);
this.getAccount();
@@ -108,7 +107,14 @@ export default {
}
},
moveTransactions: function () {
- axios.post('./api/v1/data/bulk/accounts/transactions', {original_account: this.accountId, destination_account: this.moveToAccount}).then(response => {
+
+ let query =
+ {
+ where: {source_account_id: this.accountId},
+ update: {destination_account_id: this.moveToAccount}
+ };
+
+ axios.post('./api/v1/data/bulk/transactions', {query: JSON.stringify(query)}).then(response => {
this.execDeleteAccount();
});
},
diff --git a/frontend/src/components/accounts/Edit.vue b/frontend/src/components/accounts/Edit.vue
index 8c12ba10e6..48164a17b4 100644
--- a/frontend/src/components/accounts/Edit.vue
+++ b/frontend/src/components/accounts/Edit.vue
@@ -19,12 +19,370 @@
-->
+