diff --git a/.deploy/docker/build-amd64.sh b/.deploy/docker/build-amd64.sh
index 4a80ab83b2..b3cfcb13f5 100755
--- a/.deploy/docker/build-amd64.sh
+++ b/.deploy/docker/build-amd64.sh
@@ -5,13 +5,13 @@ echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
if [ "$TRAVIS_BRANCH" == "develop" ]; then
echo "Build develop amd64"
- docker build -t jc5x/firefly-iii:develop-amd -f Dockerfile .
+ docker build -t jc5x/firefly-iii:develop-amd -f Dockerfile.amd64 .
docker push jc5x/firefly-iii:develop-amd
fi
if [ "$TRAVIS_BRANCH" == "master" ]; then
echo "Build master amd64"
- docker build -t jc5x/firefly-iii:latest-amd -f Dockerfile .
+ docker build -t jc5x/firefly-iii:latest-amd -f Dockerfile.amd64 .
docker tag jc5x/firefly-iii:latest-amd jc5x/firefly-iii:release-$VERSION-amd
docker push jc5x/firefly-iii:latest-amd
docker push jc5x/firefly-iii:release-$VERSION-amd
diff --git a/.deploy/docker/build-arm.sh b/.deploy/docker/build-arm.sh
index 5e2df5c204..893076a747 100755
--- a/.deploy/docker/build-arm.sh
+++ b/.deploy/docker/build-arm.sh
@@ -15,13 +15,13 @@ echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
if [ "$TRAVIS_BRANCH" == "develop" ]; then
echo "Build develop arm"
- docker build --tag jc5x/firefly-iii:develop-arm --file Dockerfile-ARM .
+ docker build --tag jc5x/firefly-iii:develop-arm --file Dockerfile.arm .
docker push jc5x/firefly-iii:develop-arm
fi
if [ "$TRAVIS_BRANCH" == "master" ]; then
echo "Build master arm"
- docker build --tag jc5x/firefly-iii:latest-arm --file Dockerfile-ARM .
+ docker build --tag jc5x/firefly-iii:latest-arm --file Dockerfile.arm .
docker tag jc5x/firefly-iii:latest-arm jc5x/firefly-iii:release-$VERSION-arm
docker push jc5x/firefly-iii:latest-arm
docker push jc5x/firefly-iii:release-$VERSION-arm
diff --git a/.deploy/docker/entrypoint.sh b/.deploy/docker/entrypoint.sh
index 326d932e26..f5978beb77 100755
--- a/.deploy/docker/entrypoint.sh
+++ b/.deploy/docker/entrypoint.sh
@@ -2,6 +2,8 @@
echo "Now in entrypoint.sh for Firefly III"
+lscpu
+
# make sure the correct directories exists (suggested by @chrif):
echo "Making directories..."
mkdir -p $FIREFLY_PATH/storage/app/public
diff --git a/.deploy/docker/manifest.sh b/.deploy/docker/manifest.sh
index 7dc254cc47..f67bf4792f 100755
--- a/.deploy/docker/manifest.sh
+++ b/.deploy/docker/manifest.sh
@@ -1,8 +1,9 @@
#!/usr/bin/env bash
+
if [ "$TRAVIS_BRANCH" == "develop" ]; then
TARGET=jc5x/firefly-iii:develop
ARM=jc5x/firefly-iii:develop-arm
- AMD=jc5x/firefly-iii:develop-amd
+ AMD=jc5x/firefly-iii:develop-amd64
docker manifest create $TARGET $AMD $ARM
docker manifest annotate $TARGET $ARM --arch arm --os linux
@@ -15,7 +16,7 @@ echo "The version is $VERSION"
if [ "$TRAVIS_BRANCH" == "master" ]; then
TARGET=jc5x/firefly-iii:latest
ARM=jc5x/firefly-iii:latest-arm
- AMD=jc5x/firefly-iii:latest-amd
+ AMD=jc5x/firefly-iii:latest-amd64
docker manifest create $TARGET $AMD $ARM
docker manifest annotate $TARGET $ARM --arch arm --os linux
@@ -25,7 +26,7 @@ if [ "$TRAVIS_BRANCH" == "master" ]; then
# and another one for version specific:
TARGET=jc5x/firefly-iii:release-$VERSION
ARM=jc5x/firefly-iii:release-$VERSION-arm
- AMD=jc5x/firefly-iii:release-$VERSION-amd
+ AMD=jc5x/firefly-iii:release-$VERSION-amd64
docker manifest create $TARGET $AMD $ARM
docker manifest annotate $TARGET $ARM --arch arm --os linux
diff --git a/.sandstorm/changelog.md b/.sandstorm/changelog.md
index 75e45b90ad..8e92ce0b68 100644
--- a/.sandstorm/changelog.md
+++ b/.sandstorm/changelog.md
@@ -1,3 +1,15 @@
+# 4.7.11
+- Experimental audit logging channel to track important events (separate from debug logging).
+- [Issue 2003](https://github.com/firefly-iii/firefly-iii/issues/2003), [issue 2006](https://github.com/firefly-iii/firefly-iii/issues/2006) Transactions can be stored with a timestamp. The user-interface does not support this yet. But the API does.
+- Docker image tags a new manifest for arm and amd64.
+- [skuzzle](https://github.com/skuzzle) removed an annoying console.log statement.
+- [Issue 2048](https://github.com/firefly-iii/firefly-iii/issues/2048) Fix "Are you sure?" popup, thanks to @nescafe2002!
+- [Issue 2049](https://github.com/firefly-iii/firefly-iii/issues/2049) Empty preferences would crash Firefly III.
+- [Issue 2052](https://github.com/firefly-iii/firefly-iii/issues/2052) Rules could not auto-covert to liabilities.
+- Webbased upgrade routine will also decrypt the database.
+- Last use date for categories was off.
+- The `date`-field in any transaction object now returns a ISO 8601 timestamp instead of a date.
+
# 4.7.10
- [Issue 2037](https://github.com/firefly-iii/firefly-iii/issues/2037) Added some new magic keywords to reports.
- Added a new currency exchange rate service, [ratesapi.io](https://ratesapi.io/), that does not require expensive API keys. Built by [@BoGnY](https://github.com/BoGnY).
diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp
index 1d58b6858b..dd6219a976 100644
--- a/.sandstorm/sandstorm-pkgdef.capnp
+++ b/.sandstorm/sandstorm-pkgdef.capnp
@@ -15,8 +15,8 @@ const pkgdef :Spk.PackageDefinition = (
manifest = (
appTitle = (defaultText = "Firefly III"),
- appVersion = 20,
- appMarketingVersion = (defaultText = "4.7.10"),
+ appVersion = 21,
+ appMarketingVersion = (defaultText = "4.7.11"),
actions = [
# Define your "new document" handlers here.
diff --git a/.travis.yml b/.travis.yml
index ae31eb4043..f43c7ef671 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,14 +1,16 @@
sudo: required
language: bash
+env:
+ - VERSION=4.7.11
+
+dist: xenial
+
# safelist
branches:
only:
- develop
- master
-env:
- - VERSION=4.7.10
-
services:
- docker
@@ -18,6 +20,7 @@ script:
- sudo service docker restart
- docker version -f '{{.Server.Experimental}}'
- docker version
+ # build everything
- .deploy/docker/build-amd64.sh
- .deploy/docker/build-arm.sh
- - .deploy/docker/manifest.sh
\ No newline at end of file
+ - .deploy/docker/manifest.sh
diff --git a/Dockerfile.amd64 b/Dockerfile.amd64
new file mode 100644
index 0000000000..4b27c86669
--- /dev/null
+++ b/Dockerfile.amd64
@@ -0,0 +1,51 @@
+FROM php:7.2-apache
+ARG ARCH
+ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
+LABEL version="1.3" maintainer="thegrumpydictator@gmail.com"
+
+# Create volumes
+VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
+
+# Install some stuff
+RUN apt-get update && apt-get install -y libpng-dev \
+ libicu-dev \
+ unzip \
+ gettext-base \
+ libldap2-dev \
+ libpq-dev \
+ locales \
+ libmemcached-dev && \
+ apt-get clean && \
+ rm -rf /var/lib/apt/lists/*
+
+# Copy in Firefly III source
+WORKDIR $FIREFLY_PATH
+ADD . $FIREFLY_PATH
+
+# copy ca certs to correct location
+COPY ./.deploy/docker/cacert.pem /usr/local/ssl/cert.pem
+
+# copy Apache config to correct spot.
+COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf
+
+# Enable default site (Firefly III)
+COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
+
+# Run a lot of installation commands:
+RUN chown -R www-data:www-data /var/www && \
+ chmod -R 775 $FIREFLY_PATH/storage && \
+ a2enmod rewrite && a2enmod ssl && \
+ docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ && \
+ docker-php-ext-install -j$(nproc) zip bcmath ldap gd pdo_pgsql pdo_mysql intl opcache && \
+ pecl install memcached-3.1.3 && \
+ docker-php-ext-enable memcached && \
+ curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
+ echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\nzh_TW.UTF-8 UTF-8\nzh_CN.UTF-8 UTF-8\n\n" > /etc/locale.gen && \
+ locale-gen && \
+ composer install --prefer-dist --no-dev --no-scripts --no-suggest
+
+# Expose port 80
+EXPOSE 80
+
+# Run entrypoint thing
+ENTRYPOINT [".deploy/docker/entrypoint.sh"]
diff --git a/Dockerfile-ARM b/Dockerfile.arm
similarity index 99%
rename from Dockerfile-ARM
rename to Dockerfile.arm
index cfe6e0ad31..3860b358af 100644
--- a/Dockerfile-ARM
+++ b/Dockerfile.arm
@@ -1,5 +1,5 @@
FROM arm32v7/php:7.2.8-apache-stretch
-ARG TARGETPLATFORM
+ARG ARCH
COPY tmp/qemu-arm-static /usr/bin/qemu-arm-static
ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
LABEL version="1.3" maintainer="thegrumpydictator@gmail.com"
diff --git a/Dockerfile.arm64 b/Dockerfile.arm64
new file mode 100644
index 0000000000..3860b358af
--- /dev/null
+++ b/Dockerfile.arm64
@@ -0,0 +1,50 @@
+FROM arm32v7/php:7.2.8-apache-stretch
+ARG ARCH
+COPY tmp/qemu-arm-static /usr/bin/qemu-arm-static
+ENV FIREFLY_PATH=/var/www/firefly-iii COMPOSER_ALLOW_SUPERUSER=1
+LABEL version="1.3" maintainer="thegrumpydictator@gmail.com"
+
+# Create volumes
+VOLUME $FIREFLY_PATH/storage/export $FIREFLY_PATH/storage/upload
+
+# Install some stuff
+RUN apt-get update && apt-get install -y libpng-dev \
+ libicu-dev \
+ unzip \
+ gettext-base \
+ libldap2-dev \
+ libpq-dev \
+ locales \
+ libmemcached-dev
+
+# Copy in Firefly III source
+WORKDIR $FIREFLY_PATH
+ADD . $FIREFLY_PATH
+
+# copy ca certs to correct location
+COPY ./.deploy/docker/cacert.pem /usr/local/ssl/cert.pem
+
+# copy Apache config to correct spot.
+COPY ./.deploy/docker/apache2.conf /etc/apache2/apache2.conf
+
+# Enable default site (Firefly III)
+COPY ./.deploy/docker/apache-firefly.conf /etc/apache2/sites-available/000-default.conf
+
+# Run a lot of installation commands:
+RUN chown -R www-data:www-data /var/www && \
+ chmod -R 775 $FIREFLY_PATH/storage && \
+ a2enmod rewrite && a2enmod ssl && \
+ docker-php-ext-configure ldap --with-libdir=lib/$(gcc -dumpmachine)/ && \
+ docker-php-ext-install -j$(nproc) zip bcmath ldap gd pdo_pgsql pdo_mysql intl opcache && \
+ pecl install memcached-3.1.3 && \
+ docker-php-ext-enable memcached && \
+ curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
+ echo "de_DE.UTF-8 UTF-8\nen_US.UTF-8 UTF-8\nes_ES.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8\nid_ID.UTF-8 UTF-8\nit_IT.UTF-8 UTF-8\nnl_NL.UTF-8 UTF-8\npl_PL.UTF-8 UTF-8\npt_BR.UTF-8 UTF-8\nru_RU.UTF-8 UTF-8\ntr_TR.UTF-8 UTF-8\nzh_TW.UTF-8 UTF-8\nzh_CN.UTF-8 UTF-8\n\n" > /etc/locale.gen && \
+ locale-gen && \
+ composer install --prefer-dist --no-dev --no-scripts --no-suggest
+
+# Expose port 80
+EXPOSE 80
+
+# Run entrypoint thing
+ENTRYPOINT [".deploy/docker/entrypoint.sh"]
diff --git a/app/Api/V1/Controllers/Chart/AccountController.php b/app/Api/V1/Controllers/Chart/AccountController.php
index 22c97e13d9..fcb2a0739e 100644
--- a/app/Api/V1/Controllers/Chart/AccountController.php
+++ b/app/Api/V1/Controllers/Chart/AccountController.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Chart;
@@ -324,4 +345,4 @@ class AccountController extends Controller
return $return;
}
-}
\ No newline at end of file
+}
diff --git a/app/Api/V1/Controllers/Chart/AvailableBudgetController.php b/app/Api/V1/Controllers/Chart/AvailableBudgetController.php
index 0f2c2d79a6..8335acc3bc 100644
--- a/app/Api/V1/Controllers/Chart/AvailableBudgetController.php
+++ b/app/Api/V1/Controllers/Chart/AvailableBudgetController.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Chart;
@@ -90,4 +111,4 @@ class AvailableBudgetController extends Controller
return response()->json($chartData);
}
-}
\ No newline at end of file
+}
diff --git a/app/Api/V1/Controllers/Chart/CategoryController.php b/app/Api/V1/Controllers/Chart/CategoryController.php
index 4d7a6a4422..868297af1e 100644
--- a/app/Api/V1/Controllers/Chart/CategoryController.php
+++ b/app/Api/V1/Controllers/Chart/CategoryController.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers\Chart;
@@ -185,4 +206,4 @@ class CategoryController extends Controller
return response()->json($chartData);
}
-}
\ No newline at end of file
+}
diff --git a/app/Api/V1/Controllers/Controller.php b/app/Api/V1/Controllers/Controller.php
index 8e9a8153e6..aa15ba0d17 100644
--- a/app/Api/V1/Controllers/Controller.php
+++ b/app/Api/V1/Controllers/Controller.php
@@ -104,7 +104,7 @@ class Controller extends BaseController
$obj = null;
if (null !== $date) {
try {
- $obj = new Carbon($date);
+ $obj = Carbon::parse($date);
} catch (InvalidDateException $e) {
// don't care
Log::error(sprintf('Invalid date exception in API controller: %s', $e->getMessage()));
diff --git a/app/Api/V1/Controllers/SummaryController.php b/app/Api/V1/Controllers/SummaryController.php
index f617db72b7..a56ccc1671 100644
--- a/app/Api/V1/Controllers/SummaryController.php
+++ b/app/Api/V1/Controllers/SummaryController.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Api\V1\Controllers;
@@ -389,4 +410,4 @@ class SummaryController extends Controller
return $return;
}
-}
\ No newline at end of file
+}
diff --git a/app/Api/V1/Requests/TransactionRequest.php b/app/Api/V1/Requests/TransactionRequest.php
index 9c6820dad7..a9b024cc37 100644
--- a/app/Api/V1/Requests/TransactionRequest.php
+++ b/app/Api/V1/Requests/TransactionRequest.php
@@ -26,6 +26,7 @@ namespace FireflyIII\Api\V1\Requests;
use FireflyIII\Rules\BelongsUser;
use FireflyIII\Rules\IsBoolean;
+use FireflyIII\Rules\IsDateOrTime;
use FireflyIII\Validation\TransactionValidation;
use Illuminate\Validation\Validator;
@@ -59,7 +60,7 @@ class TransactionRequest extends Request
{
$data = [
'type' => $this->string('type'),
- 'date' => $this->date('date'),
+ 'date' => $this->dateTime('date'),
'description' => $this->string('description'),
'piggy_bank_id' => $this->integer('piggy_bank_id'),
'piggy_bank_name' => $this->string('piggy_bank_name'),
@@ -103,7 +104,7 @@ class TransactionRequest extends Request
// basic fields for journal:
'type' => 'required|in:withdrawal,deposit,transfer,opening-balance,reconciliation',
'description' => 'between:1,255',
- 'date' => 'required|date',
+ 'date' => ['required', new IsDateOrTime],
'piggy_bank_id' => ['numeric', 'nullable', 'mustExist:piggy_banks,id', new BelongsUser],
'piggy_bank_name' => ['between:1,255', 'nullable', new BelongsUser],
'bill_id' => ['numeric', 'nullable', 'mustExist:bills,id', new BelongsUser],
diff --git a/app/Console/Commands/DecryptDatabase.php b/app/Console/Commands/DecryptDatabase.php
index 5c7eb3e519..ad8a83e4a3 100644
--- a/app/Console/Commands/DecryptDatabase.php
+++ b/app/Console/Commands/DecryptDatabase.php
@@ -1,5 +1,27 @@
.
+ */
+
+declare(strict_types=1);
+
namespace FireflyIII\Console\Commands;
use Crypt;
diff --git a/app/Factory/TransactionJournalFactory.php b/app/Factory/TransactionJournalFactory.php
index 6c022a0271..9dc5c3c654 100644
--- a/app/Factory/TransactionJournalFactory.php
+++ b/app/Factory/TransactionJournalFactory.php
@@ -24,6 +24,7 @@ declare(strict_types=1);
namespace FireflyIII\Factory;
+use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Services\Internal\Support\JournalServiceTrait;
@@ -70,14 +71,18 @@ class TransactionJournalFactory
Log::debug(sprintf('Going to store a %s', $type->type));
$description = app('steam')->cleanString($data['description']);
$description = str_replace(["\n", "\t", "\r"], "\x20", $description);
- $journal = TransactionJournal::create(
+ /** @var Carbon $carbon */
+ $carbon = $data['date'];
+ $carbon->setTimezone(config('app.timezone'));
+
+ $journal = TransactionJournal::create(
[
'user_id' => $data['user'],
'transaction_type_id' => $type->id,
'bill_id' => null,
'transaction_currency_id' => $defaultCurrency->id,
'description' => $description,
- 'date' => $data['date']->format('Y-m-d'),
+ 'date' => $carbon->format('Y-m-d H:i:s'),
'order' => 0,
'tag_count' => 0,
'completed' => 0,
@@ -92,7 +97,7 @@ class TransactionJournalFactory
/** @var TransactionFactory $factory */
$factory = app(TransactionFactory::class);
$factory->setUser($this->user);
- $totalAmount= '0';
+ $totalAmount = '0';
Log::debug(sprintf('Found %d transactions in array.', \count($data['transactions'])));
/** @var array $trData */
foreach ($data['transactions'] as $index => $trData) {
diff --git a/app/Helpers/Update/UpdateTrait.php b/app/Helpers/Update/UpdateTrait.php
index e01d1b4891..0d040c4a0e 100644
--- a/app/Helpers/Update/UpdateTrait.php
+++ b/app/Helpers/Update/UpdateTrait.php
@@ -50,6 +50,8 @@ trait UpdateTrait
$request->call();
} catch (FireflyException $e) {
Log::error(sprintf('Could not check for updates: %s', $e->getMessage()));
+
+ return null;
}
// get releases from array.
@@ -79,13 +81,16 @@ trait UpdateTrait
public function parseResult(int $versionCheck, Release $release = null): string
{
Log::debug(sprintf('Now in parseResult(%d)', $versionCheck));
- $current = (string)config('firefly.version');
- $return = '';
+ $current = (string)config('firefly.version');
+ $return = '';
+ $triggered = false;
if ($versionCheck === -2) {
Log::debug('-2, so give error.');
- $return = (string)trans('firefly.update_check_error');
+ $return = (string)trans('firefly.update_check_error');
+ $triggered = true;
}
if ($versionCheck === -1 && null !== $release) {
+ $triggered = true;
Log::debug('New version!');
// there is a new FF version!
// has it been released for at least three days?
@@ -106,16 +111,23 @@ trait UpdateTrait
}
if (0 === $versionCheck) {
+ $triggered = true;
Log::debug('User is running current version.');
// you are running the current version!
$return = (string)trans('firefly.update_current_version_alert', ['version' => $current]);
}
if (1 === $versionCheck && null !== $release) {
+ $triggered = true;
Log::debug('User is running NEWER version.');
// you are running a newer version!
$return = (string)trans('firefly.update_newer_version_alert', ['your_version' => $current, 'new_version' => $release->getTitle()]);
}
+ if (false === $triggered) {
+ Log::debug('No option was triggered.');
+ $return = (string)trans('firefly.update_check_error');
+ }
+
return $return;
}
@@ -131,6 +143,7 @@ trait UpdateTrait
Log::debug('Now in versionCheck()');
if (null === $release) {
Log::debug('Release is null, return -2.');
+
return -2;
}
$current = (string)config('firefly.version');
diff --git a/app/Http/Controllers/Account/CreateController.php b/app/Http/Controllers/Account/CreateController.php
index 02c32fb94b..50bf7ac4ac 100644
--- a/app/Http/Controllers/Account/CreateController.php
+++ b/app/Http/Controllers/Account/CreateController.php
@@ -111,7 +111,7 @@ class CreateController extends Controller
$this->rememberPreviousUri('accounts.create.uri');
}
$request->session()->forget('accounts.create.fromStore');
-
+ Log::channel('audit')->info('Create new account.');
return view('accounts.create', compact('subTitleIcon', 'what', 'interestPeriods', 'subTitle', 'roles', 'liabilityTypes'));
}
@@ -131,7 +131,7 @@ class CreateController extends Controller
$request->session()->flash('success', (string)trans('firefly.stored_new_account', ['name' => $account->name]));
app('preferences')->mark();
-
+ Log::channel('audit')->info('Store new account.', $data);
// update preferences if necessary:
$frontPage = app('preferences')->get('frontPageAccounts', [])->data;
diff --git a/app/Http/Controllers/Admin/ConfigurationController.php b/app/Http/Controllers/Admin/ConfigurationController.php
index 9292f8c387..159b717e3b 100644
--- a/app/Http/Controllers/Admin/ConfigurationController.php
+++ b/app/Http/Controllers/Admin/ConfigurationController.php
@@ -29,6 +29,7 @@ use FireflyIII\Http\Middleware\IsSandStormUser;
use FireflyIII\Http\Requests\ConfigurationRequest;
use FireflyIII\Support\Facades\FireflyConfig;
use Illuminate\Http\RedirectResponse;
+use Log;
/**
* Class ConfigurationController.
@@ -64,6 +65,8 @@ class ConfigurationController extends Controller
$subTitle = (string)trans('firefly.instance_configuration');
$subTitleIcon = 'fa-wrench';
+ Log::channel('audit')->info('User visits admin config index.');
+
// all available configuration and their default value in case
// they don't exist yet.
$singleUserMode = FireflyConfig::get('single_user_mode', config('firefly.configuration.single_user_mode'))->data;
@@ -88,6 +91,8 @@ class ConfigurationController extends Controller
// get config values:
$data = $request->getConfigurationData();
+ Log::channel('audit')->info('User updates global configuration.', $data);
+
// store config values
FireflyConfig::set('single_user_mode', $data['single_user_mode']);
FireflyConfig::set('is_demo_site', $data['is_demo_site']);
diff --git a/app/Http/Controllers/Admin/HomeController.php b/app/Http/Controllers/Admin/HomeController.php
index 2373143b9a..16733d64f5 100644
--- a/app/Http/Controllers/Admin/HomeController.php
+++ b/app/Http/Controllers/Admin/HomeController.php
@@ -52,6 +52,7 @@ class HomeController extends Controller
*/
public function index()
{
+ Log::channel('audit')->info('User visits admin index.');
$title = (string)trans('firefly.administration');
$mainTitleIcon = 'fa-hand-spock-o';
$sandstorm = 1 === (int)getenv('SANDSTORM');
@@ -68,6 +69,7 @@ class HomeController extends Controller
*/
public function testMessage(Request $request)
{
+ Log::channel('audit')->info('User sends test message.');
/** @var User $user */
$user = auth()->user();
$ipAddress = $request->ip();
diff --git a/app/Http/Controllers/Admin/LinkController.php b/app/Http/Controllers/Admin/LinkController.php
index 01b1814138..4a3a3afcea 100644
--- a/app/Http/Controllers/Admin/LinkController.php
+++ b/app/Http/Controllers/Admin/LinkController.php
@@ -28,6 +28,7 @@ use FireflyIII\Http\Requests\LinkTypeFormRequest;
use FireflyIII\Models\LinkType;
use FireflyIII\Repositories\LinkType\LinkTypeRepositoryInterface;
use Illuminate\Http\Request;
+use Log;
use View;
/**
@@ -63,6 +64,8 @@ class LinkController extends Controller
$subTitle = (string)trans('firefly.create_new_link_type');
$subTitleIcon = 'fa-link';
+ Log::channel('audit')->info('User visits link index.');
+
// put previous url in session if not redirect from store (not "create another").
if (true !== session('link-types.create.fromStore')) {
$this->rememberPreviousUri('link-types.create.uri');
@@ -88,6 +91,8 @@ class LinkController extends Controller
return redirect(route('admin.links.index'));
}
+ Log::channel('audit')->info(sprintf('User wants to delete link type #%d', $linkType->id));
+
$subTitle = (string)trans('firefly.delete_link_type', ['name' => $linkType->name]);
$otherTypes = $repository->get();
$count = $repository->countJournals($linkType);
@@ -116,6 +121,7 @@ class LinkController extends Controller
*/
public function destroy(Request $request, LinkTypeRepositoryInterface $repository, LinkType $linkType)
{
+ Log::channel('audit')->info(sprintf('User destroyed link type #%d', $linkType->id));
$name = $linkType->name;
$moveTo = $repository->findNull((int)$request->get('move_link_type_before_delete'));
$repository->destroy($linkType, $moveTo);
@@ -144,6 +150,8 @@ class LinkController extends Controller
$subTitle = (string)trans('firefly.edit_link_type', ['name' => $linkType->name]);
$subTitleIcon = 'fa-link';
+ Log::channel('audit')->info(sprintf('User wants to edit link type #%d', $linkType->id));
+
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('link-types.edit.fromUpdate')) {
$this->rememberPreviousUri('link-types.edit.uri'); // @codeCoverageIgnore
@@ -165,6 +173,8 @@ class LinkController extends Controller
$subTitle = (string)trans('firefly.journal_link_configuration');
$subTitleIcon = 'fa-link';
$linkTypes = $repository->get();
+
+ Log::channel('audit')->info('User on index of link types in admin.');
$linkTypes->each(
function (LinkType $linkType) use ($repository) {
$linkType->journalCount = $repository->countJournals($linkType);
@@ -187,6 +197,8 @@ class LinkController extends Controller
$subTitleIcon = 'fa-link';
$links = $linkType->transactionJournalLinks()->get();
+ Log::channel('audit')->info(sprintf('User viewing link type #%d', $linkType->id));
+
return view('admin.link.show', compact('subTitle', 'subTitleIcon', 'linkType', 'links'));
}
@@ -206,6 +218,9 @@ class LinkController extends Controller
'outward' => $request->string('outward'),
];
$linkType = $repository->store($data);
+
+ Log::channel('audit')->info('User stored new link type.', $linkType->toArray());
+
$request->session()->flash('success', (string)trans('firefly.stored_new_link_type', ['name' => $linkType->name]));
$redirect = redirect($this->getPreviousUri('link-types.create.uri'));
if (1 === (int)$request->get('create_another')) {
@@ -243,6 +258,8 @@ class LinkController extends Controller
];
$repository->update($linkType, $data);
+ Log::channel('audit')->info(sprintf('User update link type #%d.', $linkType->id), $data);
+
$request->session()->flash('success', (string)trans('firefly.updated_link_type', ['name' => $linkType->name]));
app('preferences')->mark();
$redirect = redirect($this->getPreviousUri('link-types.edit.uri'));
diff --git a/app/Http/Controllers/CurrencyController.php b/app/Http/Controllers/CurrencyController.php
index 4c72b09e3e..622ca191e6 100644
--- a/app/Http/Controllers/CurrencyController.php
+++ b/app/Http/Controllers/CurrencyController.php
@@ -91,6 +91,8 @@ class CurrencyController extends Controller
}
$request->session()->forget('currencies.create.fromStore');
+ Log::channel('audit')->info('Create new currency.');
+
return view('currencies.create', compact('subTitleIcon', 'subTitle'));
}
@@ -107,6 +109,8 @@ class CurrencyController extends Controller
app('preferences')->set('currencyPreference', $currency->code);
app('preferences')->mark();
+ Log::channel('audit')->info(sprintf('Make %s the default currency.', $currency->code));
+
$this->repository->enable($currency);
$request->session()->flash('success', (string)trans('firefly.new_default_currency', ['name' => $currency->name]));
@@ -128,6 +132,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
+ Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@@ -135,6 +140,7 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
$request->session()->flash('error', (string)trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
+ Log::channel('audit')->info(sprintf('Tried to visit page to delete currency %s but currency is in use.', $currency->code));
return redirect(route('currencies.index'));
}
@@ -142,6 +148,7 @@ class CurrencyController extends Controller
// put previous url in session
$this->rememberPreviousUri('currencies.delete.uri');
$subTitle = (string)trans('form.delete_currency', ['name' => $currency->name]);
+ Log::channel('audit')->info(sprintf('Visit page to delete currency %s.', $currency->code));
return view('currencies.delete', compact('currency', 'subTitle'));
}
@@ -161,6 +168,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
+ Log::channel('audit')->info(sprintf('Tried to delete currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@@ -168,11 +176,13 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
$request->session()->flash('error', (string)trans('firefly.cannot_delete_currency', ['name' => $currency->name]));
+ Log::channel('audit')->info(sprintf('Tried to delete currency %s but is in use.', $currency->code));
return redirect(route('currencies.index'));
}
-
+ Log::channel('audit')->info(sprintf('Deleted currency %s.', $currency->code));
$this->repository->destroy($currency);
+
$request->session()->flash('success', (string)trans('firefly.deleted_currency', ['name' => $currency->name]));
return redirect($this->getPreviousUri('currencies.delete.uri'));
@@ -193,6 +203,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
+ Log::channel('audit')->info(sprintf('Tried to disable currency %s but is not site owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@@ -200,20 +211,23 @@ class CurrencyController extends Controller
if ($this->repository->currencyInUse($currency)) {
$request->session()->flash('error', (string)trans('firefly.cannot_disable_currency', ['name' => $currency->name]));
+ Log::channel('audit')->info(sprintf('Tried to disable currency %s but is in use.', $currency->code));
return redirect(route('currencies.index'));
}
$this->repository->disable($currency);
-
+ Log::channel('audit')->info(sprintf('Disabled currency %s.', $currency->code));
// if no currencies are enabled, enable the first one in the DB (usually the EUR)
if (0 === $this->repository->get()->count()) {
+ /** @var TransactionCurrency $first */
$first = $this->repository->getAll()->first();
if (null === $first) {
throw new FireflyException('No currencies found.');
}
+ Log::channel('audit')->info(sprintf('Auto-enabled currency %s.', $first->code));
$this->repository->enable($first);
- app('preferences')->set('currencyPreference', $currency->code);
+ app('preferences')->set('currencyPreference', $first->code);
app('preferences')->mark();
}
@@ -237,6 +251,7 @@ class CurrencyController extends Controller
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
+ Log::channel('audit')->info(sprintf('Tried to edit currency %s but is not owner.', $currency->code));
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
@@ -253,7 +268,7 @@ class CurrencyController extends Controller
];
$request->session()->flash('preFilled', $preFilled);
-
+ Log::channel('audit')->info('Edit currency.', $currency->toArray());
// put previous url in session if not redirect from store (not "return_to_edit").
if (true !== session('currencies.edit.fromUpdate')) {
@@ -275,6 +290,7 @@ class CurrencyController extends Controller
$this->repository->enable($currency);
session()->flash('success', (string)trans('firefly.currency_is_now_enabled', ['name' => $currency->name]));
+ Log::channel('audit')->info(sprintf('Enabled currency %s.', $currency->code));
return redirect(route('currencies.index'));
}
@@ -329,21 +345,23 @@ class CurrencyController extends Controller
{
/** @var User $user */
$user = auth()->user();
+ $data = $request->getCurrencyData();
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
Log::error('User ' . auth()->user()->id . ' is not admin, but tried to store a currency.');
+ Log::channel('audit')->info('Tried to create (POST) currency without admin rights.', $data);
return redirect($this->getPreviousUri('currencies.create.uri'));
// @codeCoverageIgnoreEnd
}
- $data = $request->getCurrencyData();
$data['enabled'] = true;
$currency = $this->repository->store($data);
$redirect = redirect($this->getPreviousUri('currencies.create.uri'));
+
if (null !== $currency) {
$request->session()->flash('success', (string)trans('firefly.created_currency', ['name' => $currency->name]));
-
+ Log::channel('audit')->info('Created (POST) currency.', $data);
if (1 === (int)$request->get('create_another')) {
// @codeCoverageIgnoreStart
$request->session()->put('currencies.create.fromStore', true);
@@ -353,6 +371,7 @@ class CurrencyController extends Controller
}
}
if (null === $currency) {
+ Log::channel('audit')->info('Could not store (POST) currency without admin rights.', $data);
$request->session()->flash('error', (string)trans('firefly.could_not_store_currency'));
}
@@ -372,16 +391,19 @@ class CurrencyController extends Controller
{
/** @var User $user */
$user = auth()->user();
+ $data = $request->getCurrencyData();
if (!$this->userRepository->hasRole($user, 'owner')) {
// @codeCoverageIgnoreStart
$request->session()->flash('error', (string)trans('firefly.ask_site_owner', ['owner' => config('firefly.site_owner')]));
+ Log::channel('audit')->info('Tried to update (POST) currency without admin rights.', $data);
return redirect(route('currencies.index'));
// @codeCoverageIgnoreEnd
}
- $data = $request->getCurrencyData();
+
$currency = $this->repository->update($currency, $data);
+ Log::channel('audit')->info('Updated (POST) currency.', $data);
$request->session()->flash('success', (string)trans('firefly.updated_currency', ['name' => $currency->name]));
app('preferences')->mark();
diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php
index 804deca82b..703e53aa53 100644
--- a/app/Http/Controllers/HomeController.php
+++ b/app/Http/Controllers/HomeController.php
@@ -67,6 +67,7 @@ class HomeController extends Controller
Log::debug('Received dateRange', ['start' => $request->get('start'), 'end' => $request->get('end'), 'label' => $request->get('label')]);
+
// check if the label is "everything" or "Custom range" which will betray
// a possible problem with the budgets.
if ($label === (string)trans('firefly.everything') || $label === (string)trans('firefly.customRange')) {
@@ -103,6 +104,8 @@ class HomeController extends Controller
$types = config('firefly.accountTypesByIdentifier.asset');
$count = $repository->count($types);
+ Log::channel('audit')->info('User visits homepage.');
+
if (0 === $count) {
return redirect(route('new-user.index'));
}
diff --git a/app/Http/Controllers/System/InstallController.php b/app/Http/Controllers/System/InstallController.php
index 711f091db4..c4c779c1db 100644
--- a/app/Http/Controllers/System/InstallController.php
+++ b/app/Http/Controllers/System/InstallController.php
@@ -153,6 +153,34 @@ class InstallController extends Controller
return response()->json(['error' => false, 'message' => 'OK']);
}
+ /**
+ * Do database decrypt.
+ *
+ * @return \Illuminate\Http\JsonResponse
+ */
+ public function decrypt(): JsonResponse
+ {
+ if ($this->hasForbiddenFunctions()) {
+ return response()->json(['error' => true, 'message' => self::FORBIDDEN_ERROR]);
+ }
+ try {
+ Log::debug('Am now calling decrypt database routine...');
+ Artisan::call('firefly:decrypt-all');
+ Log::debug(Artisan::output());
+ } catch (Exception $e) {
+ Log::error($e->getMessage());
+ Log::error($e->getTraceAsString());
+ if (strpos($e->getMessage(), 'open_basedir restriction in effect')) {
+ return response()->json(['error' => true, 'message' => self::BASEDIR_ERROR]);
+ }
+
+ return response()->json(['error' => true, 'message' => self::OTHER_ERROR . ' ' . $e->getMessage()]);
+ }
+
+ return response()->json(['error' => false, 'message' => 'OK']);
+ }
+
+
/**
* Do database verification.
*
diff --git a/app/Http/Requests/Request.php b/app/Http/Requests/Request.php
index 6bd87f2af6..be04cca2ba 100644
--- a/app/Http/Requests/Request.php
+++ b/app/Http/Requests/Request.php
@@ -23,7 +23,9 @@ declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
+use Carbon\Exceptions\InvalidDateException;
use Illuminate\Foundation\Http\FormRequest;
+use Log;
/**
* Class Request.
@@ -130,4 +132,42 @@ class Request extends FormRequest
{
return $this->get($field) ? new Carbon($this->get($field)) : null;
}
+
+ /**
+ * Return date time or NULL.
+ *
+ * @param string $field
+ *
+ * @return Carbon|null
+ */
+ protected function dateTime(string $field): ?Carbon
+ {
+ if (null === $this->get($field)) {
+ return null;
+ }
+ $value = (string)$this->get($field);
+ if (10 === \strlen($value)) {
+ // probably a date format.
+ try {
+ $result = Carbon::createFromFormat('Y-m-d', $value);
+ } catch (InvalidDateException $e) {
+ Log::error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage()));
+
+ return null;
+ }
+
+ return $result;
+ }
+ // is an atom string, I hope?
+ try {
+ $result = Carbon::parse($value);
+ } catch (InvalidDateException $e) {
+ Log::error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage()));
+
+ return null;
+ }
+
+ return $result;
+ }
+
}
diff --git a/app/Import/Converter/BankDebitCredit.php b/app/Import/Converter/BankDebitCredit.php
index 7b91ef895a..3e131f4aaf 100644
--- a/app/Import/Converter/BankDebitCredit.php
+++ b/app/Import/Converter/BankDebitCredit.php
@@ -55,4 +55,4 @@ class BankDebitCredit implements ConverterInterface
return 1;
}
-}
\ No newline at end of file
+}
diff --git a/app/Import/Specifics/RabobankDescription.php b/app/Import/Specifics/RabobankDescription.php
index d27392ca80..7dea7e493a 100644
--- a/app/Import/Specifics/RabobankDescription.php
+++ b/app/Import/Specifics/RabobankDescription.php
@@ -38,7 +38,7 @@ class RabobankDescription implements SpecificInterface
*/
public static function getDescription(): string
{
- return 'import.specific_pres_descr';
+ return 'import.specific_rabo_descr';
}
/**
diff --git a/app/Import/Storage/ImportArrayStorage.php b/app/Import/Storage/ImportArrayStorage.php
index 6da281f269..eb1299a6ce 100644
--- a/app/Import/Storage/ImportArrayStorage.php
+++ b/app/Import/Storage/ImportArrayStorage.php
@@ -457,7 +457,7 @@ class ImportArrayStorage
Log::debug(sprintf('Going to store entry %d of %d', $index + 1, $count));
// convert the date to an object:
- $store['date'] = Carbon::createFromFormat('Y-m-d', $store['date']);
+ $store['date'] = Carbon::parse($store['date'], config('app.timezone'));
$store['description'] = '' === $store['description'] ? '(empty description)' : $store['description'];
// store the journal.
try {
@@ -556,7 +556,7 @@ class ImportArrayStorage
Log::debug(sprintf('Comparison is a hit! (%s)', $hits));
// compare date:
- $transferDate = $transfer->date->format('Y-m-d');
+ $transferDate = $transfer->date->format('Y-m-d H:i:s');
Log::debug(sprintf('Comparing dates "%s" to "%s"', $transaction['date'], $transferDate));
if ($transaction['date'] !== $transferDate) {
continue; // @codeCoverageIgnore
diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php
index 1cba19f5ed..458b4c7c13 100644
--- a/app/Models/TransactionJournal.php
+++ b/app/Models/TransactionJournal.php
@@ -84,7 +84,7 @@ class TransactionJournal extends Model
'created_at' => 'datetime',
'updated_at' => 'datetime',
'deleted_at' => 'datetime',
- 'date' => 'date',
+ 'date' => 'datetime',
'interest_date' => 'date',
'book_date' => 'date',
'process_date' => 'date',
diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php
index 9bb76ab7b4..a4b318d529 100644
--- a/app/Repositories/Category/CategoryRepository.php
+++ b/app/Repositories/Category/CategoryRepository.php
@@ -292,7 +292,7 @@ class CategoryRepository implements CategoryRepositoryInterface
return $lastTransactionDate;
}
- if ($lastTransactionDate < $lastJournalDate) {
+ if ($lastTransactionDate > $lastJournalDate) {
return $lastTransactionDate;
}
diff --git a/app/Rules/IsDateOrTime.php b/app/Rules/IsDateOrTime.php
new file mode 100644
index 0000000000..a8c76eb604
--- /dev/null
+++ b/app/Rules/IsDateOrTime.php
@@ -0,0 +1,82 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Rules;
+
+use Carbon\Carbon;
+use Carbon\Exceptions\InvalidDateException;
+use Illuminate\Contracts\Validation\Rule;
+use Log;
+
+/**
+ * Class IsDateOrTime
+ */
+class IsDateOrTime implements Rule
+{
+
+ /**
+ * Get the validation error message.
+ *
+ * @return string|array
+ */
+ public function message()
+ {
+ return (string)trans('validation.date_or_time');
+ }
+
+ /**
+ * Determine if the validation rule passes.
+ *
+ * @param string $attribute
+ * @param mixed $value
+ *
+ * @return bool
+ */
+ public function passes($attribute, $value): bool
+ {
+ $value = (string)$value;
+ if (10 === \strlen($value)) {
+ // probably a date format.
+ try {
+ Carbon::createFromFormat('Y-m-d', $value);
+ } catch (InvalidDateException $e) {
+ Log::error(sprintf('"%s" is not a valid date: %s', $value, $e->getMessage()));
+
+ return false;
+ }
+
+ return true;
+ }
+ // is an atom string, I hope?
+ try {
+ Carbon::parse($value);
+ } catch (InvalidDateException $e) {
+ Log::error(sprintf('"%s" is not a valid date or time: %s', $value, $e->getMessage()));
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/app/Services/Github/Request/UpdateRequest.php b/app/Services/Github/Request/UpdateRequest.php
index 1616db8701..d49a982874 100644
--- a/app/Services/Github/Request/UpdateRequest.php
+++ b/app/Services/Github/Request/UpdateRequest.php
@@ -62,7 +62,7 @@ class UpdateRequest implements GithubRequest
$releaseXml = new SimpleXMLElement($res->getBody()->getContents(), LIBXML_NOCDATA);
} catch (RuntimeException $e) {
Log::error(sprintf('Could not get body from github updat result: %s', $e->getMessage()));
- $releaseXml = new SimpleXMLElement('');
+ throw new FireflyException(sprintf('Could not get body from github updat result: %s', $e->getMessage()));
}
//fetch the products for each category
diff --git a/app/Support/Http/Controllers/ChartGeneration.php b/app/Support/Http/Controllers/ChartGeneration.php
index ddf24454f9..efdcc4198c 100644
--- a/app/Support/Http/Controllers/ChartGeneration.php
+++ b/app/Support/Http/Controllers/ChartGeneration.php
@@ -259,4 +259,4 @@ trait ChartGeneration
return $data;
}
-}
\ No newline at end of file
+}
diff --git a/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php b/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php
index 7c7c402cf1..a781e1fb4d 100644
--- a/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php
+++ b/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php
@@ -151,7 +151,7 @@ class ChooseAccountsHandler implements SpectreJobConfigurationInterface
}
// list the users accounts:
- $accounts = $this->accountRepository->getAccountsByType([AccountType::ASSET]);
+ $accounts = $this->accountRepository->getAccountsByType([AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE]);
$array = [];
/** @var AccountModel $account */
diff --git a/app/Support/Import/Routine/Bunq/PaymentConverter.php b/app/Support/Import/Routine/Bunq/PaymentConverter.php
index cff39a747a..e37da1ecaf 100644
--- a/app/Support/Import/Routine/Bunq/PaymentConverter.php
+++ b/app/Support/Import/Routine/Bunq/PaymentConverter.php
@@ -105,7 +105,10 @@ class PaymentConverter
$type = TransactionType::TRANSFER;
Log::debug('Because both transctions are asset, will make it a transfer.');
}
- $created = new Carbon($payment->getCreated());
+ Log::debug(sprintf('Bunq created = %s', $payment->getCreated()));
+ $created = new Carbon($payment->getCreated(), 'UTC');
+ // correct timezone to system timezone.
+ $created->setTimezone(config('app.timezone'));
$description = $payment->getDescription();
if ('' === $payment->getDescription() && 'SAVINGS' === $payment->getType()) {
@@ -115,7 +118,7 @@ class PaymentConverter
$storeData = [
'user' => $this->importJob->user_id,
'type' => $type,
- 'date' => $created->format('Y-m-d'),
+ 'date' => $created->format('Y-m-d H:i:s'),
'timestamp' => $created->toAtomString(),
'description' => $description,
'piggy_bank_id' => null,
@@ -151,7 +154,7 @@ class PaymentConverter
],
],
];
- Log::info(sprintf('Parsed %s: "%s" (%s).', $created->format('Y-m-d'), $storeData['description'], $storeData['transactions'][0]['amount']));
+ Log::info(sprintf('Parsed %s: "%s" (%s).', $created->format('Y-m-d H:i:s'), $storeData['description'], $storeData['transactions'][0]['amount']));
return $storeData;
diff --git a/app/Support/Import/Routine/File/ImportableConverter.php b/app/Support/Import/Routine/File/ImportableConverter.php
index 1fc0103725..99c33680d6 100644
--- a/app/Support/Import/Routine/File/ImportableConverter.php
+++ b/app/Support/Import/Routine/File/ImportableConverter.php
@@ -140,8 +140,14 @@ class ImportableConverter
$result = null;
if (null !== $date) {
try {
- $object = Carbon::createFromFormat($this->config['date-format'] ?? 'Ymd', $date);
- $result = $object->format('Y-m-d');
+ // add exclamation mark for better parsing. http://php.net/manual/en/datetime.createfromformat.php
+ $dateFormat = $this->config['date-format'] ?? 'Ymd';
+ if ('!' !== $dateFormat{0}) {
+ $dateFormat = '!' . $dateFormat;
+ }
+ $object = Carbon::createFromFormat($dateFormat, $date);
+ $result = $object->format('Y-m-d H:i:s');
+ Log::debug(sprintf('createFromFormat: Turning "%s" into "%s" using "%s"', $date, $result, $this->config['date-format'] ?? 'Ymd'));
} catch (InvalidDateException|InvalidArgumentException $e) {
Log::error($e->getMessage());
Log::error($e->getTraceAsString());
@@ -213,7 +219,7 @@ class ImportableConverter
return [
'type' => $transactionType,
- 'date' => $this->convertDateValue($importable->date) ?? Carbon::now()->format('Y-m-d'),
+ 'date' => $this->convertDateValue($importable->date) ?? Carbon::now()->format('Y-m-d H:i:s'),
'tags' => $importable->tags,
'user' => $this->importJob->user_id,
'notes' => $importable->note,
diff --git a/app/Support/Import/Routine/Spectre/StageImportDataHandler.php b/app/Support/Import/Routine/Spectre/StageImportDataHandler.php
index 66d6cc8518..443b889fd6 100644
--- a/app/Support/Import/Routine/Spectre/StageImportDataHandler.php
+++ b/app/Support/Import/Routine/Spectre/StageImportDataHandler.php
@@ -233,8 +233,8 @@ class StageImportDataHandler
if (null === $account) {
throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore
}
- if ($account->accountType->type !== AccountType::ASSET) {
- throw new FireflyException(sprintf('Account with ID #%d is not an asset account. Job must stop now.', $accountId)); // @codeCoverageIgnore
+ if (!\in_array($account->accountType->type ,[AccountType::ASSET, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT], true)) {
+ throw new FireflyException(sprintf('Account with ID #%d is not an asset/loan/mortgage/debt account. Job must stop now.', $accountId)); // @codeCoverageIgnore
}
return $account;
diff --git a/app/Support/Logging/AuditLogger.php b/app/Support/Logging/AuditLogger.php
new file mode 100644
index 0000000000..1f303c63cf
--- /dev/null
+++ b/app/Support/Logging/AuditLogger.php
@@ -0,0 +1,44 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Logging;
+
+/**
+ * Class AuditLogger
+ */
+class AuditLogger
+{
+ /**
+ * Customize the given logger instance.
+ *
+ * @param \Illuminate\Log\Logger $logger
+ *
+ * @return void
+ */
+ public function __invoke($logger)
+ {
+ $processor = new AuditProcessor;
+ $logger->pushProcessor($processor);
+ }
+}
diff --git a/app/Support/Logging/AuditProcessor.php b/app/Support/Logging/AuditProcessor.php
new file mode 100644
index 0000000000..823f5e57ff
--- /dev/null
+++ b/app/Support/Logging/AuditProcessor.php
@@ -0,0 +1,49 @@
+.
+ */
+
+declare(strict_types=1);
+
+namespace FireflyIII\Support\Logging;
+
+/**
+ * Class AuditProcessor
+ */
+class AuditProcessor
+{
+ /**
+ * @param array $record
+ *
+ * @return array
+ */
+ public function __invoke(array $record): array
+ {
+ $record['extra']['path'] = request()->method() . ':' . request()->url();
+
+ $record['extra']['IP'] = app('request')->ip();
+ if (auth()->check()) {
+ $record['extra']['user'] = auth()->user()->email;
+ }
+
+
+ return $record;
+ }
+}
diff --git a/app/Support/Preferences.php b/app/Support/Preferences.php
index f86340ded9..09106f4c9a 100644
--- a/app/Support/Preferences.php
+++ b/app/Support/Preferences.php
@@ -216,8 +216,22 @@ class Preferences
{
$fullName = sprintf('preference%s%s', $user->id, $name);
Cache::forget($fullName);
+ /** @var Preference $pref */
$pref = Preference::where('user_id', $user->id)->where('name', $name)->first(['id', 'name', 'data', 'updated_at', 'created_at']);
+ if (null !== $pref && null === $value) {
+ try {
+ $pref->delete();
+ } catch (Exception $e) {
+ Log::error(sprintf('Could not delete preference: %s', $e->getMessage()));
+ }
+
+ return new Preference;
+ }
+ if (null === $value) {
+ return new Preference;
+ }
+
if (null !== $pref) {
$pref->data = $value;
$pref->save();
diff --git a/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php b/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php
index bb19a14ac7..4f8dfb0d62 100644
--- a/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php
+++ b/app/Support/Repositories/Recurring/CalculateRangeOccurrences.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Support\Repositories\Recurring;
@@ -200,4 +221,4 @@ trait CalculateRangeOccurrences
return $return;
}
-}
\ No newline at end of file
+}
diff --git a/app/Support/Repositories/Recurring/CalculateXOccurrences.php b/app/Support/Repositories/Recurring/CalculateXOccurrences.php
index 9d586ad4d1..b640b1475d 100644
--- a/app/Support/Repositories/Recurring/CalculateXOccurrences.php
+++ b/app/Support/Repositories/Recurring/CalculateXOccurrences.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Support\Repositories\Recurring;
@@ -199,4 +220,4 @@ trait CalculateXOccurrences
return $return;
}
-}
\ No newline at end of file
+}
diff --git a/app/Support/Repositories/Recurring/FiltersWeekends.php b/app/Support/Repositories/Recurring/FiltersWeekends.php
index 1c0e1c8e87..b46daf1105 100644
--- a/app/Support/Repositories/Recurring/FiltersWeekends.php
+++ b/app/Support/Repositories/Recurring/FiltersWeekends.php
@@ -1,4 +1,25 @@
.
+ */
+
declare(strict_types=1);
namespace FireflyIII\Support\Repositories\Recurring;
@@ -75,4 +96,4 @@ trait FiltersWeekends
return $return;
}
-}
\ No newline at end of file
+}
diff --git a/app/TransactionRules/Actions/ConvertToTransfer.php b/app/TransactionRules/Actions/ConvertToTransfer.php
index b4dbe20d50..6194cc8a24 100644
--- a/app/TransactionRules/Actions/ConvertToTransfer.php
+++ b/app/TransactionRules/Actions/ConvertToTransfer.php
@@ -72,7 +72,9 @@ class ConvertToTransfer implements ActionInterface
/** @var AccountRepositoryInterface $repository */
$repository = app(AccountRepositoryInterface::class);
$repository->setUser($journal->user);
- $asset = $repository->findByName($this->action->action_value, [AccountType::ASSET, AccountType::DEFAULT]);
+ $asset = $repository->findByName(
+ $this->action->action_value, [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]
+ );
if (null === $asset) {
// @codeCoverageIgnoreStart
Log::error(
@@ -129,6 +131,7 @@ class ConvertToTransfer implements ActionInterface
return false; // @codeCoverageIgnore
}
+
/**
* A deposit is from Revenue to Asset.
* We replace the Revenue with another asset.
diff --git a/app/TransactionRules/Actions/SetCategory.php b/app/TransactionRules/Actions/SetCategory.php
index 754f663e15..500d7bd559 100644
--- a/app/TransactionRules/Actions/SetCategory.php
+++ b/app/TransactionRules/Actions/SetCategory.php
@@ -76,7 +76,7 @@ class SetCategory implements ActionInterface
$journal->touch();
- Log::debug(sprintf('RuleAction SetCategory set the category of journal #%d to budget #%d ("%s").', $journal->id, $category->id, $category->name));
+ Log::debug(sprintf('RuleAction SetCategory set the category of journal #%d to category #%d ("%s").', $journal->id, $category->id, $category->name));
return true;
}
diff --git a/app/Transformers/TransactionTransformer.php b/app/Transformers/TransactionTransformer.php
index 80e9ff8e9f..353b9fffa6 100644
--- a/app/Transformers/TransactionTransformer.php
+++ b/app/Transformers/TransactionTransformer.php
@@ -77,7 +77,7 @@ class TransactionTransformer extends AbstractTransformer
'description' => $transaction->description,
'journal_description' => $transaction->description,
'transaction_description' => $transaction->transaction_description,
- 'date' => $transaction->date->format('Y-m-d'),
+ 'date' => $transaction->date->toAtomString(),
'type' => $transaction->transaction_type_type,
'identifier' => $transaction->identifier,
'journal_id' => (int)$transaction->journal_id,
diff --git a/changelog.md b/changelog.md
index 26960597e4..e42f67ffc2 100644
--- a/changelog.md
+++ b/changelog.md
@@ -2,6 +2,28 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
+## [4.7.11 (API 0.9.2)] - 2019-02-10
+### Added
+- Experimental audit logging channel to track important events (separate from debug logging).
+
+### Changed
+- [Issue 2003](https://github.com/firefly-iii/firefly-iii/issues/2003), [issue 2006](https://github.com/firefly-iii/firefly-iii/issues/2006) Transactions can be stored with a timestamp. The user-interface does not support this yet. But the API does.
+- Docker image tags a new manifest for arm and amd64.
+
+### Removed
+- [skuzzle](https://github.com/skuzzle) removed an annoying console.log statement.
+
+### Fixed
+- [Issue 2048](https://github.com/firefly-iii/firefly-iii/issues/2048) Fix "Are you sure?" popup, thanks to @nescafe2002!
+- [Issue 2049](https://github.com/firefly-iii/firefly-iii/issues/2049) Empty preferences would crash Firefly III.
+- [Issue 2052](https://github.com/firefly-iii/firefly-iii/issues/2052) Rules could not auto-covert to liabilities.
+- Webbased upgrade routine will also decrypt the database.
+- Last use date for categories was off.
+
+### API
+- The `date`-field in any transaction object now returns a ISO 8601 timestamp instead of a date.
+
+
## [4.7.10] - 2019-02-03
### Added
- [Issue 2037](https://github.com/firefly-iii/firefly-iii/issues/2037) Added some new magic keywords to reports.
@@ -18,7 +40,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- I will no longer accept PR's that introduce new currencies.
### Removed
-- Firefly III no longer encrypts the database and will [decrypt the database]() on its first run.
+- Firefly III no longer encrypts the database and will [decrypt the database](https://github.com/firefly-iii/help/wiki/Database-encryption) on its first run.
### Fixed
- [Issue 1923](https://github.com/firefly-iii/firefly-iii/issues/1923) Broken window position for date picker.
@@ -42,7 +64,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- [Issue 2009](https://github.com/firefly-iii/firefly-iii/issues/2009) Could not change recurrence back to "forever".
- [Issue 2033](https://github.com/firefly-iii/firefly-iii/issues/2033) Longitude can go from -180 to 180.
- [Issue 2034](https://github.com/firefly-iii/firefly-iii/issues/2034) Rules were not being triggered in mass-edit.
-- #2043 In rare instances the repetition of a recurring transaction was displayed incorrectly.
+- [Issue 2043](https://github.com/firefly-iii/firefly-iii/issues/2043) In rare instances the repetition of a recurring transaction was displayed incorrectly.
- Fixed broken translations in the recurring transactions overview.
- When you create a recurring transfer you make make it fill (or empty) a piggy bank. This was not working, despite a fix in 4.7.8.
- Fixed a bug where the importer would not be capable of creating new currencies.
diff --git a/composer.lock b/composer.lock
index e8cc91569d..0b1923ef29 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1303,16 +1303,16 @@
},
{
"name": "laravel/framework",
- "version": "v5.7.24",
+ "version": "v5.7.25",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
- "reference": "2ede55db4b8201ed0450fa7e7a4d7220aa29bc34"
+ "reference": "f8fb354878064b94a3ff09a6ffd48ee9a8d712cf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laravel/framework/zipball/2ede55db4b8201ed0450fa7e7a4d7220aa29bc34",
- "reference": "2ede55db4b8201ed0450fa7e7a4d7220aa29bc34",
+ "url": "https://api.github.com/repos/laravel/framework/zipball/f8fb354878064b94a3ff09a6ffd48ee9a8d712cf",
+ "reference": "f8fb354878064b94a3ff09a6ffd48ee9a8d712cf",
"shasum": ""
},
"require": {
@@ -1445,7 +1445,7 @@
"framework",
"laravel"
],
- "time": "2019-01-29T22:13:46+00:00"
+ "time": "2019-02-05T14:28:43+00:00"
},
{
"name": "laravel/nexmo-notification-channel",
@@ -2470,16 +2470,16 @@
},
{
"name": "nexmo/client",
- "version": "1.6.1",
+ "version": "1.6.2",
"source": {
"type": "git",
"url": "https://github.com/Nexmo/nexmo-php.git",
- "reference": "3dc03ca1dab726a23b757110897740e54304fc65"
+ "reference": "2f79f67f24225ea627ee14578e98c96276cdd4c5"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Nexmo/nexmo-php/zipball/3dc03ca1dab726a23b757110897740e54304fc65",
- "reference": "3dc03ca1dab726a23b757110897740e54304fc65",
+ "url": "https://api.github.com/repos/Nexmo/nexmo-php/zipball/2f79f67f24225ea627ee14578e98c96276cdd4c5",
+ "reference": "2f79f67f24225ea627ee14578e98c96276cdd4c5",
"shasum": ""
},
"require": {
@@ -2514,7 +2514,7 @@
}
],
"description": "PHP Client for using Nexmo's API.",
- "time": "2019-01-02T09:06:47+00:00"
+ "time": "2019-02-07T11:14:34+00:00"
},
{
"name": "opis/closure",
@@ -3523,16 +3523,16 @@
},
{
"name": "symfony/console",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522"
+ "reference": "1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522",
- "reference": "b0a03c1bb0fcbe288629956cf2f1dd3f1dc97522",
+ "url": "https://api.github.com/repos/symfony/console/zipball/1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4",
+ "reference": "1f0ad51dfde4da8a6070f06adc58b4e37cbb37a4",
"shasum": ""
},
"require": {
@@ -3544,6 +3544,9 @@
"symfony/dependency-injection": "<3.4",
"symfony/process": "<3.3"
},
+ "provide": {
+ "psr/log-implementation": "1.0"
+ },
"require-dev": {
"psr/log": "~1.0",
"symfony/config": "~3.4|~4.0",
@@ -3553,7 +3556,7 @@
"symfony/process": "~3.4|~4.0"
},
"suggest": {
- "psr/log-implementation": "For using the console logger",
+ "psr/log": "For using the console logger",
"symfony/event-dispatcher": "",
"symfony/lock": "",
"symfony/process": ""
@@ -3588,7 +3591,7 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
- "time": "2019-01-04T15:13:53+00:00"
+ "time": "2019-01-25T14:35:16+00:00"
},
{
"name": "symfony/contracts",
@@ -3660,16 +3663,16 @@
},
{
"name": "symfony/css-selector",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
- "reference": "76dac1dbe2830213e95892c7c2ec1edd74113ea4"
+ "reference": "48eddf66950fa57996e1be4a55916d65c10c604a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/css-selector/zipball/76dac1dbe2830213e95892c7c2ec1edd74113ea4",
- "reference": "76dac1dbe2830213e95892c7c2ec1edd74113ea4",
+ "url": "https://api.github.com/repos/symfony/css-selector/zipball/48eddf66950fa57996e1be4a55916d65c10c604a",
+ "reference": "48eddf66950fa57996e1be4a55916d65c10c604a",
"shasum": ""
},
"require": {
@@ -3709,20 +3712,20 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-16T20:31:39+00:00"
},
{
"name": "symfony/debug",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
- "reference": "64cb33c81e37d19b7715d4a6a4d49c1c382066dd"
+ "reference": "cf9b2e33f757deb884ce474e06d2647c1c769b65"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/debug/zipball/64cb33c81e37d19b7715d4a6a4d49c1c382066dd",
- "reference": "64cb33c81e37d19b7715d4a6a4d49c1c382066dd",
+ "url": "https://api.github.com/repos/symfony/debug/zipball/cf9b2e33f757deb884ce474e06d2647c1c769b65",
+ "reference": "cf9b2e33f757deb884ce474e06d2647c1c769b65",
"shasum": ""
},
"require": {
@@ -3765,20 +3768,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-25T14:35:16+00:00"
},
{
"name": "symfony/event-dispatcher",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "887de6d34c86cf0cb6cbf910afb170cdb743cb5e"
+ "reference": "bd09ad265cd50b2b9d09d65ce6aba2d29bc81fe1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/887de6d34c86cf0cb6cbf910afb170cdb743cb5e",
- "reference": "887de6d34c86cf0cb6cbf910afb170cdb743cb5e",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bd09ad265cd50b2b9d09d65ce6aba2d29bc81fe1",
+ "reference": "bd09ad265cd50b2b9d09d65ce6aba2d29bc81fe1",
"shasum": ""
},
"require": {
@@ -3829,20 +3832,20 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
- "time": "2019-01-05T16:37:49+00:00"
+ "time": "2019-01-16T20:35:37+00:00"
},
{
"name": "symfony/finder",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "9094d69e8c6ee3fe186a0ec5a4f1401e506071ce"
+ "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/9094d69e8c6ee3fe186a0ec5a4f1401e506071ce",
- "reference": "9094d69e8c6ee3fe186a0ec5a4f1401e506071ce",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/ef71816cbb264988bb57fe6a73f610888b9aa70c",
+ "reference": "ef71816cbb264988bb57fe6a73f610888b9aa70c",
"shasum": ""
},
"require": {
@@ -3878,20 +3881,20 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-16T20:35:37+00:00"
},
{
"name": "symfony/http-foundation",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
- "reference": "a633d422a09242064ba24e44a6e1494c5126de86"
+ "reference": "8d2318b73e0a1bc75baa699d00ebe2ae8b595a39"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a633d422a09242064ba24e44a6e1494c5126de86",
- "reference": "a633d422a09242064ba24e44a6e1494c5126de86",
+ "url": "https://api.github.com/repos/symfony/http-foundation/zipball/8d2318b73e0a1bc75baa699d00ebe2ae8b595a39",
+ "reference": "8d2318b73e0a1bc75baa699d00ebe2ae8b595a39",
"shasum": ""
},
"require": {
@@ -3932,20 +3935,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
- "time": "2019-01-05T16:37:49+00:00"
+ "time": "2019-01-29T09:49:29+00:00"
},
{
"name": "symfony/http-kernel",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
- "reference": "83de6543328917c18d5498eeb6bb6d36f7aab31b"
+ "reference": "d56b1706abaa771eb6acd894c6787cb88f1dc97d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/http-kernel/zipball/83de6543328917c18d5498eeb6bb6d36f7aab31b",
- "reference": "83de6543328917c18d5498eeb6bb6d36f7aab31b",
+ "url": "https://api.github.com/repos/symfony/http-kernel/zipball/d56b1706abaa771eb6acd894c6787cb88f1dc97d",
+ "reference": "d56b1706abaa771eb6acd894c6787cb88f1dc97d",
"shasum": ""
},
"require": {
@@ -4021,7 +4024,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
- "time": "2019-01-06T16:19:23+00:00"
+ "time": "2019-02-03T12:47:33+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -4305,16 +4308,16 @@
},
{
"name": "symfony/process",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "ea043ab5d8ed13b467a9087d81cb876aee7f689a"
+ "reference": "6c05edb11fbeff9e2b324b4270ecb17911a8b7ad"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/ea043ab5d8ed13b467a9087d81cb876aee7f689a",
- "reference": "ea043ab5d8ed13b467a9087d81cb876aee7f689a",
+ "url": "https://api.github.com/repos/symfony/process/zipball/6c05edb11fbeff9e2b324b4270ecb17911a8b7ad",
+ "reference": "6c05edb11fbeff9e2b324b4270ecb17911a8b7ad",
"shasum": ""
},
"require": {
@@ -4350,7 +4353,7 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T14:48:52+00:00"
+ "time": "2019-01-24T22:05:03+00:00"
},
{
"name": "symfony/psr-http-message-bridge",
@@ -4415,16 +4418,16 @@
},
{
"name": "symfony/routing",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
- "reference": "e69b7a13a0b58af378a49b49dd7084462de16cee"
+ "reference": "7f8e44fc498972466f0841c3e48dc555f23bdf53"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/routing/zipball/e69b7a13a0b58af378a49b49dd7084462de16cee",
- "reference": "e69b7a13a0b58af378a49b49dd7084462de16cee",
+ "url": "https://api.github.com/repos/symfony/routing/zipball/7f8e44fc498972466f0841c3e48dc555f23bdf53",
+ "reference": "7f8e44fc498972466f0841c3e48dc555f23bdf53",
"shasum": ""
},
"require": {
@@ -4488,20 +4491,20 @@
"uri",
"url"
],
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-29T09:49:29+00:00"
},
{
"name": "symfony/translation",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
- "reference": "939fb792d73f2ce80e6ae9019d205fc480f1c9a0"
+ "reference": "23fd7aac70d99a17a8e6473a41fec8fab3331050"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/translation/zipball/939fb792d73f2ce80e6ae9019d205fc480f1c9a0",
- "reference": "939fb792d73f2ce80e6ae9019d205fc480f1c9a0",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/23fd7aac70d99a17a8e6473a41fec8fab3331050",
+ "reference": "23fd7aac70d99a17a8e6473a41fec8fab3331050",
"shasum": ""
},
"require": {
@@ -4561,20 +4564,20 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-27T23:11:39+00:00"
},
{
"name": "symfony/var-dumper",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
- "reference": "85bde661b178173d85c6f11ea9d03b61d1212bb2"
+ "reference": "223bda89f9be41cf7033eeaf11bc61a280489c17"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/var-dumper/zipball/85bde661b178173d85c6f11ea9d03b61d1212bb2",
- "reference": "85bde661b178173d85c6f11ea9d03b61d1212bb2",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/223bda89f9be41cf7033eeaf11bc61a280489c17",
+ "reference": "223bda89f9be41cf7033eeaf11bc61a280489c17",
"shasum": ""
},
"require": {
@@ -4637,7 +4640,7 @@
"debug",
"dump"
],
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-30T11:44:30+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
@@ -5624,16 +5627,16 @@
},
{
"name": "mockery/mockery",
- "version": "1.2.0",
+ "version": "1.2.1",
"source": {
"type": "git",
"url": "https://github.com/mockery/mockery.git",
- "reference": "100633629bf76d57430b86b7098cd6beb996a35a"
+ "reference": "dc4f10b6b1148744facb784015e4b339d7feec23"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mockery/mockery/zipball/100633629bf76d57430b86b7098cd6beb996a35a",
- "reference": "100633629bf76d57430b86b7098cd6beb996a35a",
+ "url": "https://api.github.com/repos/mockery/mockery/zipball/dc4f10b6b1148744facb784015e4b339d7feec23",
+ "reference": "dc4f10b6b1148744facb784015e4b339d7feec23",
"shasum": ""
},
"require": {
@@ -5642,7 +5645,7 @@
"php": ">=5.6.0"
},
"require-dev": {
- "phpunit/phpunit": "~5.7.10|~6.5|~7.0"
+ "phpunit/phpunit": "~5.7.10|~6.5|~7.0|~8.0"
},
"type": "library",
"extra": {
@@ -5685,7 +5688,7 @@
"test double",
"testing"
],
- "time": "2018-10-02T21:52:37+00:00"
+ "time": "2019-02-08T14:43:54+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -6389,16 +6392,16 @@
},
{
"name": "phpunit/phpunit",
- "version": "7.5.3",
+ "version": "7.5.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "2cb759721e53bc05f56487f628c6b9fbb6c18746"
+ "reference": "2896657da5fb237bc316bdfc18c2650efeee0dc0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2cb759721e53bc05f56487f628c6b9fbb6c18746",
- "reference": "2cb759721e53bc05f56487f628c6b9fbb6c18746",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2896657da5fb237bc316bdfc18c2650efeee0dc0",
+ "reference": "2896657da5fb237bc316bdfc18c2650efeee0dc0",
"shasum": ""
},
"require": {
@@ -6469,7 +6472,7 @@
"testing",
"xunit"
],
- "time": "2019-02-01T05:24:07+00:00"
+ "time": "2019-02-07T14:15:04+00:00"
},
{
"name": "roave/security-advisories",
@@ -6477,12 +6480,12 @@
"source": {
"type": "git",
"url": "https://github.com/Roave/SecurityAdvisories.git",
- "reference": "db876706aacd4ffbd1c253358d19a651e50e65c2"
+ "reference": "344bf4ed1263c75e7f96b87b80c52e8373561e19"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/db876706aacd4ffbd1c253358d19a651e50e65c2",
- "reference": "db876706aacd4ffbd1c253358d19a651e50e65c2",
+ "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/344bf4ed1263c75e7f96b87b80c52e8373561e19",
+ "reference": "344bf4ed1263c75e7f96b87b80c52e8373561e19",
"shasum": ""
},
"conflict": {
@@ -6517,8 +6520,8 @@
"doctrine/mongodb-odm-bundle": ">=2,<3.0.1",
"doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1",
"dompdf/dompdf": ">=0.6,<0.6.2",
- "drupal/core": ">=7,<7.60|>=8,<8.5.8|>=8.6,<8.6.2",
- "drupal/drupal": ">=7,<7.60|>=8,<8.5.8|>=8.6,<8.6.2",
+ "drupal/core": ">=7,<7.62|>=8,<8.5.9|>=8.6,<8.6.6",
+ "drupal/drupal": ">=7,<7.62|>=8,<8.5.9|>=8.6,<8.6.6",
"erusev/parsedown": "<1.7",
"ezsystems/ezpublish-kernel": ">=5.3,<5.3.12.1|>=5.4,<5.4.13.1|>=6,<6.7.9.1|>=6.8,<6.13.5.1|>=7,<7.2.4.1|>=7.3,<7.3.2.1",
"ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.6|>=5.4,<5.4.12.3|>=2011,<2017.12.4.3|>=2018.6,<2018.6.1.4|>=2018.9,<2018.9.1.3",
@@ -6615,7 +6618,7 @@
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
"tecnickcom/tcpdf": "<6.2.22",
"thelia/backoffice-default-template": ">=2.1,<2.1.2",
- "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
+ "thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3",
"theonedemon/phpwhois": "<=4.2.5",
"titon/framework": ">=0,<9.9.99",
"truckersmp/phpwhois": "<=4.3.1",
@@ -6673,7 +6676,7 @@
}
],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
- "time": "2019-01-22T18:37:22+00:00"
+ "time": "2019-02-05T19:58:17+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
@@ -6786,23 +6789,23 @@
},
{
"name": "sebastian/diff",
- "version": "3.0.1",
+ "version": "3.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "366541b989927187c4ca70490a35615d3fef2dce"
+ "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce",
- "reference": "366541b989927187c4ca70490a35615d3fef2dce",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
+ "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
"shasum": ""
},
"require": {
"php": "^7.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.0",
+ "phpunit/phpunit": "^7.5 || ^8.0",
"symfony/process": "^2 || ^3.3 || ^4"
},
"type": "library",
@@ -6838,7 +6841,7 @@
"unidiff",
"unified diff"
],
- "time": "2018-06-10T07:54:39+00:00"
+ "time": "2019-02-04T06:01:07+00:00"
},
{
"name": "sebastian/environment",
@@ -7336,16 +7339,16 @@
},
{
"name": "symfony/config",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/config.git",
- "reference": "a7a7d0a0244cfc82f040729ccf769e6cf55a78fb"
+ "reference": "25a2e7abe0d97e70282537292e3df45cf6da7b98"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/config/zipball/a7a7d0a0244cfc82f040729ccf769e6cf55a78fb",
- "reference": "a7a7d0a0244cfc82f040729ccf769e6cf55a78fb",
+ "url": "https://api.github.com/repos/symfony/config/zipball/25a2e7abe0d97e70282537292e3df45cf6da7b98",
+ "reference": "25a2e7abe0d97e70282537292e3df45cf6da7b98",
"shasum": ""
},
"require": {
@@ -7395,20 +7398,20 @@
],
"description": "Symfony Config Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-30T11:44:30+00:00"
},
{
"name": "symfony/filesystem",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "c2ffd9a93f2d6c5be2f68a0aa7953cc229f871f8"
+ "reference": "7c16ebc2629827d4ec915a52ac809768d060a4ee"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/c2ffd9a93f2d6c5be2f68a0aa7953cc229f871f8",
- "reference": "c2ffd9a93f2d6c5be2f68a0aa7953cc229f871f8",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/7c16ebc2629827d4ec915a52ac809768d060a4ee",
+ "reference": "7c16ebc2629827d4ec915a52ac809768d060a4ee",
"shasum": ""
},
"require": {
@@ -7445,20 +7448,20 @@
],
"description": "Symfony Filesystem Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-16T20:35:37+00:00"
},
{
"name": "symfony/stopwatch",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
- "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472"
+ "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/af62b35760fc92c8dbdce659b4eebdfe0e6a0472",
- "reference": "af62b35760fc92c8dbdce659b4eebdfe0e6a0472",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b1a5f646d56a3290230dbc8edf2a0d62cda23f67",
+ "reference": "b1a5f646d56a3290230dbc8edf2a0d62cda23f67",
"shasum": ""
},
"require": {
@@ -7495,20 +7498,20 @@
],
"description": "Symfony Stopwatch Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-16T20:31:39+00:00"
},
{
"name": "symfony/yaml",
- "version": "v4.2.2",
+ "version": "v4.2.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
- "reference": "d0aa6c0ea484087927b49fd513383a7d36190ca6"
+ "reference": "d461670ee145092b7e2a56c1da7118f19cadadb0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/d0aa6c0ea484087927b49fd513383a7d36190ca6",
- "reference": "d0aa6c0ea484087927b49fd513383a7d36190ca6",
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/d461670ee145092b7e2a56c1da7118f19cadadb0",
+ "reference": "d461670ee145092b7e2a56c1da7118f19cadadb0",
"shasum": ""
},
"require": {
@@ -7554,7 +7557,7 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
- "time": "2019-01-03T09:07:35+00:00"
+ "time": "2019-01-16T20:35:37+00:00"
},
{
"name": "theseer/tokenizer",
diff --git a/config/firefly.php b/config/firefly.php
index 2056381f44..0332c36569 100644
--- a/config/firefly.php
+++ b/config/firefly.php
@@ -93,9 +93,9 @@ return [
'is_demo_site' => false,
],
'encryption' => null === env('USE_ENCRYPTION') || env('USE_ENCRYPTION') === true,
- 'version' => '4.7.10',
- 'api_version' => '0.9.1',
- 'db_version' => 7,
+ 'version' => '4.7.11',
+ 'api_version' => '0.9.2',
+ 'db_version' => 8,
'maxUploadSize' => 15242880,
'send_error_message' => env('SEND_ERROR_MESSAGE', true),
'site_owner' => env('SITE_OWNER', ''),
diff --git a/config/logging.php b/config/logging.php
index 1ac3fb0284..5c5d39ec08 100644
--- a/config/logging.php
+++ b/config/logging.php
@@ -19,8 +19,11 @@
* along with Firefly III. If not, see
- {{ trans('import.global_config_text') }} -
-- {{ trans('import.can_config_title') }} -
-