diff --git a/.env.docker b/.env.docker new file mode 100644 index 0000000000..69765bff51 --- /dev/null +++ b/.env.docker @@ -0,0 +1,55 @@ +APP_ENV=${FF_APP_ENV} +APP_DEBUG=false +APP_FORCE_SSL=false +APP_FORCE_ROOT= +APP_KEY=${FF_APP_KEY} +APP_LOG=daily +APP_LOG_LEVEL=warning +APP_URL=http://localhost + +DB_CONNECTION=mysql +DB_HOST=${FF_DB_HOST} +DB_PORT=3306 +DB_DATABASE=${FF_DB_NAME} +DB_USERNAME=${FF_DB_USER} +DB_PASSWORD=${FF_DB_PASSWORD} + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +SESSION_DRIVER=file +QUEUE_DRIVER=sync + +COOKIE_PATH="/" +COOKIE_DOMAIN= +COOKIE_SECURE=false + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=mailtrap.io +MAIL_PORT=2525 +MAIL_FROM=changeme@example.com +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null + +SEND_REGISTRATION_MAIL=true +SEND_ERROR_MESSAGE=true +SHOW_INCOMPLETE_TRANSLATIONS=false + +CACHE_PREFIX=firefly + +GOOGLE_MAPS_API_KEY= +ANALYTICS_ID= +SITE_OWNER=mail@example.com +USE_ENCRYPTION=true + +PUSHER_KEY= +PUSHER_SECRET= +PUSHER_APP_ID= + +DEMO_USERNAME= +DEMO_PASSWORD= + diff --git a/.env.example b/.env.example index 04528da7fc..eaa69b5d82 100755 --- a/.env.example +++ b/.env.example @@ -3,6 +3,7 @@ APP_DEBUG=false APP_FORCE_SSL=false APP_FORCE_ROOT= APP_KEY=SomeRandomStringOf32CharsExactly +APP_LOG=daily APP_LOG_LEVEL=warning APP_URL=http://localhost diff --git a/.env.sandstorm b/.env.sandstorm new file mode 100755 index 0000000000..ed8d9d511b --- /dev/null +++ b/.env.sandstorm @@ -0,0 +1,55 @@ +APP_ENV=production +APP_DEBUG=true +APP_FORCE_SSL=false +APP_FORCE_ROOT= +APP_KEY=SomeRandomStringOf32CharsExactly +APP_LOG=syslog +APP_LOG_LEVEL=debug +APP_URL=http://localhost + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=firefly +DB_USERNAME=firefly +DB_PASSWORD=firefly + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +SESSION_DRIVER=file +QUEUE_DRIVER=sync + +COOKIE_PATH="/" +COOKIE_DOMAIN= +COOKIE_SECURE=false + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_DRIVER=smtp +MAIL_HOST=mailtrap.io +MAIL_PORT=2525 +MAIL_FROM=changeme@example.com +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null + +SEND_REGISTRATION_MAIL=true +SEND_ERROR_MESSAGE=true +SHOW_INCOMPLETE_TRANSLATIONS=false + +CACHE_PREFIX=firefly + +GOOGLE_MAPS_API_KEY= +ANALYTICS_ID= +SITE_OWNER=mail@example.com +USE_ENCRYPTION=true + +PUSHER_KEY= +PUSHER_SECRET= +PUSHER_APP_ID= + +DEMO_USERNAME= +DEMO_PASSWORD= + diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index f7ef4c3bb3..612661a00f 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -8,7 +8,7 @@ If you are requesting a new feature, please check out the list of [often request ## Bugs -If you find a bug, include as many log files and details as you think are necessary. +If you find a bug, please take the time and see if the [demo site](https://firefly-iii.nder.be/) is also suffering from this bug. Include as many log files and details as you think are necessary. ## Installation problems @@ -16,4 +16,4 @@ Take the time to read the [installation guide FAQ](https://firefly-iii.github.io ## Pull requests -I can only accept pull requests against the `develop` branch, never the `master` branch +I can only accept pull requests against the `develop` branch, never the `master` branch. diff --git a/.sandstorm/.gitattributes b/.sandstorm/.gitattributes new file mode 100644 index 0000000000..5a533b9f62 --- /dev/null +++ b/.sandstorm/.gitattributes @@ -0,0 +1,5 @@ + + +# vagrant-spk creates shell scripts, which must end in \n, even on a \r\n system. +*.sh text eol=lf + diff --git a/.sandstorm/.gitignore b/.sandstorm/.gitignore new file mode 100644 index 0000000000..d70e1e39e4 --- /dev/null +++ b/.sandstorm/.gitignore @@ -0,0 +1,5 @@ + + +# This file stores a list of sub-paths of .sandstorm/ that should be ignored by git. +.vagrant + diff --git a/.sandstorm/Vagrantfile b/.sandstorm/Vagrantfile new file mode 100644 index 0000000000..20c01b674b --- /dev/null +++ b/.sandstorm/Vagrantfile @@ -0,0 +1,103 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +# Guess at a reasonable name for the VM based on the folder vagrant-spk is +# run from. The timestamp is there to avoid conflicts if you have multiple +# folders with the same name. +VM_NAME = File.basename(File.dirname(File.dirname(__FILE__))) + "_sandstorm_#{Time.now.utc.to_i}" + +# Vagrantfile API/syntax version. Don't touch unless you know what you're doing! +VAGRANTFILE_API_VERSION = "2" + +Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| + # Base on the Sandstorm snapshots of the official Debian 8 (jessie) box. + config.vm.box = "sandstorm/debian-jessie64" + + if Vagrant.has_plugin?("vagrant-vbguest") then + # vagrant-vbguest is a Vagrant plugin that upgrades + # the version of VirtualBox Guest Additions within each + # guest. If you have the vagrant-vbguest plugin, then it + # needs to know how to compile kernel modules, etc., and so + # we give it this hint about operating system type. + config.vm.guest = "debian" + end + + # We forward port 6080, the Sandstorm web port, so that developers can + # visit their sandstorm app from their browser as local.sandstorm.io:6080 + # (aka 127.0.0.1:6080). + config.vm.network :forwarded_port, guest: 6080, host: 6080 + + # Use a shell script to "provision" the box. This installs Sandstorm using + # the bundled installer. + config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/global-setup.sh", keep_color: true + # Then, do stack-specific and app-specific setup. + config.vm.provision "shell", inline: "sudo bash /opt/app/.sandstorm/setup.sh", keep_color: true + + # Shared folders are configured per-provider since vboxsf can't handle >4096 open files, + # NFS requires privilege escalation every time you bring a VM up, + # and 9p is only available on libvirt. + + # Calculate the number of CPUs and the amount of RAM the system has, + # in a platform-dependent way; further logic below. + cpus = nil + total_kB_ram = nil + + host = RbConfig::CONFIG['host_os'] + if host =~ /darwin/ + cpus = `sysctl -n hw.ncpu`.to_i + total_kB_ram = `sysctl -n hw.memsize`.to_i / 1024 + elsif host =~ /linux/ + cpus = `nproc`.to_i + total_kB_ram = `grep MemTotal /proc/meminfo | awk '{print $2}'`.to_i + elsif host =~ /mingw/ + # powershell may not be available on Windows XP and Vista, so wrap this in a rescue block + begin + cpus = `powershell -Command "(Get-WmiObject Win32_Processor -Property NumberOfLogicalProcessors | Select-Object -Property NumberOfLogicalProcessors | Measure-Object NumberOfLogicalProcessors -Sum).Sum"`.to_i + total_kB_ram = `powershell -Command "Get-CimInstance -class cim_physicalmemory | % $_.Capacity}"`.to_i / 1024 + rescue + end + end + # Use the same number of CPUs within Vagrant as the system, with 1 + # as a default. + # + # Use at least 512MB of RAM, and if the system has more than 2GB of + # RAM, use 1/4 of the system RAM. This seems a reasonable compromise + # between having the Vagrant guest operating system not run out of + # RAM entirely (which it basically would if we went much lower than + # 512MB) and also allowing it to use up a healthily large amount of + # RAM so it can run faster on systems that can afford it. + if cpus.nil? or cpus.zero? + cpus = 1 + end + if total_kB_ram.nil? or total_kB_ram < 2048000 + assign_ram_mb = 512 + else + assign_ram_mb = (total_kB_ram / 1024 / 4) + end + # Actually apply these CPU/memory values to the providers. + config.vm.provider :virtualbox do |vb, override| + vb.cpus = cpus + vb.memory = assign_ram_mb + vb.name = VM_NAME + vb.customize ["modifyvm", :id, "--nictype1", "Am79C973"] + + # /opt/app and /host-dot-sandstorm are used by vagrant-spk + override.vm.synced_folder "..", "/opt/app" + override.vm.synced_folder ENV["HOME"] + "/.sandstorm", "/host-dot-sandstorm" + # /vagrant is not used by vagrant-spk; we need this line so it gets disabled; if we removed the + # line, vagrant would automatically insert a synced folder in /vagrant, which is not what we want. + override.vm.synced_folder "..", "/vagrant", disabled: true + end + config.vm.provider :libvirt do |libvirt, override| + libvirt.cpus = cpus + libvirt.memory = assign_ram_mb + libvirt.default_prefix = VM_NAME + + # /opt/app and /host-dot-sandstorm are used by vagrant-spk + override.vm.synced_folder "..", "/opt/app", type: "9p", accessmode: "passthrough" + override.vm.synced_folder ENV["HOME"] + "/.sandstorm", "/host-dot-sandstorm", type: "9p", accessmode: "passthrough" + # /vagrant is not used by vagrant-spk; we need this line so it gets disabled; if we removed the + # line, vagrant would automatically insert a synced folder in /vagrant, which is not what we want. + override.vm.synced_folder "..", "/vagrant", type: "9p", accessmode: "passthrough", disabled: true + end +end diff --git a/.sandstorm/app-graphics/firefly-iii-128.png b/.sandstorm/app-graphics/firefly-iii-128.png new file mode 100644 index 0000000000..70de2bc75a Binary files /dev/null and b/.sandstorm/app-graphics/firefly-iii-128.png differ diff --git a/.sandstorm/app-graphics/firefly-iii-150.png b/.sandstorm/app-graphics/firefly-iii-150.png new file mode 100644 index 0000000000..0d97be4768 Binary files /dev/null and b/.sandstorm/app-graphics/firefly-iii-150.png differ diff --git a/.sandstorm/app-graphics/firefly-iii-24.png b/.sandstorm/app-graphics/firefly-iii-24.png new file mode 100644 index 0000000000..a727ae4992 Binary files /dev/null and b/.sandstorm/app-graphics/firefly-iii-24.png differ diff --git a/.sandstorm/app-graphics/firefly-iii-48.png b/.sandstorm/app-graphics/firefly-iii-48.png new file mode 100644 index 0000000000..6f81c5731b Binary files /dev/null and b/.sandstorm/app-graphics/firefly-iii-48.png differ diff --git a/.sandstorm/build.sh b/.sandstorm/build.sh new file mode 100755 index 0000000000..93daf1ba86 --- /dev/null +++ b/.sandstorm/build.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# Checks if there's a composer.json, and if so, installs/runs composer. +# This script only runs once, when the app connects to sandstorm. +set -euo pipefail + + + +cd /opt/app + +cp .env.sandstorm .env + +if [ -f /opt/app/composer.json ] ; then + if [ ! -f composer.phar ] ; then + curl -sS https://getcomposer.org/installer | php + fi + php composer.phar install --no-dev --no-suggest +fi + +# link storage folder +rm -rf /opt/app/storage +ln -s /var/storage /opt/app \ No newline at end of file diff --git a/.sandstorm/changelog.md b/.sandstorm/changelog.md new file mode 100644 index 0000000000..58249de976 --- /dev/null +++ b/.sandstorm/changelog.md @@ -0,0 +1,3 @@ +# 3.4.3 + +* Initial release on Sandstorm.io \ No newline at end of file diff --git a/.sandstorm/description.md b/.sandstorm/description.md new file mode 100644 index 0000000000..e9f6874f3f --- /dev/null +++ b/.sandstorm/description.md @@ -0,0 +1,3 @@ +"Firefly III" is a financial manager. It can help you keep track of expenses, income, budgets and everything in between. It even supports credit cards, shared household accounts and savings accounts! It’s pretty fancy. You should use it to save and organise money. + +Firefly works on the principle that if you know where you’re money is going, you can stop it from going there. \ No newline at end of file diff --git a/.sandstorm/global-setup.sh b/.sandstorm/global-setup.sh new file mode 100755 index 0000000000..219c770f63 --- /dev/null +++ b/.sandstorm/global-setup.sh @@ -0,0 +1,44 @@ +#!/bin/bash +set -euo pipefail + +# Set options for curl. Since we only want to show errors from these curl commands, we also use +# 'cat' to buffer the output; for more information: +# https://github.com/sandstorm-io/vagrant-spk/issues/158 + +CURL_OPTS="--silent --show-error" +echo localhost > /etc/hostname +hostname localhost + +# The following line copies stderr through stderr to cat without accidentally leaving it in the +# output file. Be careful when changing. See: https://github.com/sandstorm-io/vagrant-spk/pull/159 +curl $CURL_OPTS https://install.sandstorm.io/ 2>&1 > /host-dot-sandstorm/caches/install.sh | cat + +SANDSTORM_CURRENT_VERSION=$(curl $CURL_OPTS -f "https://install.sandstorm.io/dev?from=0&type=install") +SANDSTORM_PACKAGE="sandstorm-$SANDSTORM_CURRENT_VERSION.tar.xz" +if [[ ! -f /host-dot-sandstorm/caches/$SANDSTORM_PACKAGE ]] ; then + echo -n "Downloading Sandstorm version ${SANDSTORM_CURRENT_VERSION}..." + curl $CURL_OPTS --output "/host-dot-sandstorm/caches/$SANDSTORM_PACKAGE.partial" "https://dl.sandstorm.io/$SANDSTORM_PACKAGE" 2>&1 | cat + mv "/host-dot-sandstorm/caches/$SANDSTORM_PACKAGE.partial" "/host-dot-sandstorm/caches/$SANDSTORM_PACKAGE" + echo "...done." +fi +if [ ! -e /opt/sandstorm/latest/sandstorm ] ; then + echo -n "Installing Sandstorm version ${SANDSTORM_CURRENT_VERSION}..." + bash /host-dot-sandstorm/caches/install.sh -d -e "/host-dot-sandstorm/caches/$SANDSTORM_PACKAGE" >/dev/null + echo "...done." +fi +modprobe ip_tables +# Make the vagrant user part of the sandstorm group so that commands like +# `spk dev` work. +usermod -a -G 'sandstorm' 'vagrant' +# Bind to all addresses, so the vagrant port-forward works. +sudo sed --in-place='' \ + --expression='s/^BIND_IP=.*/BIND_IP=0.0.0.0/' \ + /opt/sandstorm/sandstorm.conf +sudo service sandstorm restart +# Enable apt-cacher-ng proxy to make things faster if one appears to be running on the gateway IP +GATEWAY_IP=$(ip route | grep ^default | cut -d ' ' -f 3) +if nc -z "$GATEWAY_IP" 3142 ; then + echo "Acquire::http::Proxy \"http://$GATEWAY_IP:3142\";" > /etc/apt/apt.conf.d/80httpproxy +fi +# Configure apt to retry fetching things that fail to download. +echo "APT::Acquire::Retries \"10\";" > /etc/apt/apt.conf.d/80sandstorm-retry diff --git a/.sandstorm/launcher.sh b/.sandstorm/launcher.sh new file mode 100755 index 0000000000..f6fb9c13bc --- /dev/null +++ b/.sandstorm/launcher.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Runs every time we create a new grain! + +# Create a bunch of folders under the clean /var that php, nginx, and mysql expect to exist +mkdir -p /var/lib/mysql +mkdir -p /var/lib/nginx +mkdir -p /var/lib/php/sessions/ +mkdir -p /var/log +mkdir -p /var/log/mysql +mkdir -p /var/log/nginx +# Wipe /var/run, since pidfiles and socket files from previous launches should go away +# TODO someday: I'd prefer a tmpfs for these. +rm -rf /var/run +mkdir -p /var/run +rm -rf /var/tmp +mkdir -p /var/tmp +mkdir -p /var/run/mysqld + +# make storage directories +rm -rf /var/storage +mkdir -p /var/storage/app/public +mkdir -p /var/storage/build +mkdir -p /var/storage/database +mkdir -p /var/storage/debugbar +mkdir -p /var/storage/export +mkdir -p /var/storage/framework/cache +mkdir -p /var/storage/framework/sessions +mkdir -p /var/storage/framework/views +mkdir -p /var/storage/logs +mkdir -p /var/storage/upload + + +# Ensure mysql tables created +HOME=/etc/mysql /usr/bin/mysql_install_db --force + +# Spawn mysqld, php +HOME=/etc/mysql /usr/sbin/mysqld & + +/usr/sbin/php-fpm7.0 --nodaemonize --fpm-config /etc/php/7.0/fpm/php-fpm.conf & + +# Wait until mysql and php have bound their sockets, indicating readiness +while [ ! -e /var/run/mysqld/mysqld.sock ] ; do + echo "waiting for mysql to be available at /var/run/mysqld/mysqld.sock" + sleep .5 +done +while [ ! -e /var/run/php7.0-fpm.sock ] ; do + echo "waiting for php7.0-fpm to be available at /var/run/php7.0-fpm.sock" + sleep .5 +done + +echo "Installing database.." +# Install database for Firefly III +echo "CREATE DATABASE IF NOT EXISTS firefly; GRANT ALL on firefly.* TO 'firefly'@'localhost' IDENTIFIED BY 'firefly';" | mysql -uroot +echo "Done!" + +echo "Migrating..." +php /opt/app/artisan migrate --seed --force +echo "Done!" + +# Start nginx. +/usr/sbin/nginx -c /opt/app/.sandstorm/service-config/nginx.conf -g "daemon off;" diff --git a/.sandstorm/pgp-keyring b/.sandstorm/pgp-keyring new file mode 100644 index 0000000000..b0dec3c169 Binary files /dev/null and b/.sandstorm/pgp-keyring differ diff --git a/.sandstorm/pgp-signature b/.sandstorm/pgp-signature new file mode 100644 index 0000000000..82e5fc8a52 Binary files /dev/null and b/.sandstorm/pgp-signature differ diff --git a/.sandstorm/sandstorm-files.list b/.sandstorm/sandstorm-files.list new file mode 100644 index 0000000000..91b1256d53 --- /dev/null +++ b/.sandstorm/sandstorm-files.list @@ -0,0 +1,1430 @@ +# *** WARNING: GENERATED FILE *** +# This file is automatically updated and rewritten in sorted order every time +# the app runs in dev mode. You may manually add or remove files, but don't +# expect comments or ordering to be retained. +bin/bash +bin/cat +bin/chmod +bin/cp +bin/dash +bin/grep +bin/hostname +bin/ln +bin/ls +bin/mkdir +bin/rm +bin/sed +bin/sh +bin/sleep +bin/stty +etc/alternatives/php +etc/bash.bashrc +etc/bindresvport.blacklist +etc/default/nss +etc/hosts.allow +etc/hosts.deny +etc/inputrc +etc/ld.so.cache +etc/locale.alias +etc/localtime +etc/mysql/conf.d +etc/mysql/conf.d/mysqld_safe_syslog.cnf +etc/mysql/conf.d/sandstorm.cnf +etc/mysql/my.cnf +etc/php/7.0/cli/conf.d +etc/php/7.0/cli/conf.d/10-mysqlnd.ini +etc/php/7.0/cli/conf.d/10-opcache.ini +etc/php/7.0/cli/conf.d/10-pdo.ini +etc/php/7.0/cli/conf.d/15-xml.ini +etc/php/7.0/cli/conf.d/20-bcmath.ini +etc/php/7.0/cli/conf.d/20-calendar.ini +etc/php/7.0/cli/conf.d/20-ctype.ini +etc/php/7.0/cli/conf.d/20-curl.ini +etc/php/7.0/cli/conf.d/20-dom.ini +etc/php/7.0/cli/conf.d/20-exif.ini +etc/php/7.0/cli/conf.d/20-fileinfo.ini +etc/php/7.0/cli/conf.d/20-ftp.ini +etc/php/7.0/cli/conf.d/20-gettext.ini +etc/php/7.0/cli/conf.d/20-iconv.ini +etc/php/7.0/cli/conf.d/20-intl.ini +etc/php/7.0/cli/conf.d/20-json.ini +etc/php/7.0/cli/conf.d/20-mbstring.ini +etc/php/7.0/cli/conf.d/20-mysqli.ini +etc/php/7.0/cli/conf.d/20-pdo_mysql.ini +etc/php/7.0/cli/conf.d/20-phar.ini +etc/php/7.0/cli/conf.d/20-posix.ini +etc/php/7.0/cli/conf.d/20-readline.ini +etc/php/7.0/cli/conf.d/20-shmop.ini +etc/php/7.0/cli/conf.d/20-simplexml.ini +etc/php/7.0/cli/conf.d/20-sockets.ini +etc/php/7.0/cli/conf.d/20-sysvmsg.ini +etc/php/7.0/cli/conf.d/20-sysvsem.ini +etc/php/7.0/cli/conf.d/20-sysvshm.ini +etc/php/7.0/cli/conf.d/20-tokenizer.ini +etc/php/7.0/cli/conf.d/20-wddx.ini +etc/php/7.0/cli/conf.d/20-xmlreader.ini +etc/php/7.0/cli/conf.d/20-xmlwriter.ini +etc/php/7.0/cli/conf.d/20-xsl.ini +etc/php/7.0/cli/php.ini +etc/php/7.0/fpm/conf.d +etc/php/7.0/fpm/conf.d/10-mysqlnd.ini +etc/php/7.0/fpm/conf.d/10-opcache.ini +etc/php/7.0/fpm/conf.d/10-pdo.ini +etc/php/7.0/fpm/conf.d/15-xml.ini +etc/php/7.0/fpm/conf.d/20-bcmath.ini +etc/php/7.0/fpm/conf.d/20-calendar.ini +etc/php/7.0/fpm/conf.d/20-ctype.ini +etc/php/7.0/fpm/conf.d/20-curl.ini +etc/php/7.0/fpm/conf.d/20-dom.ini +etc/php/7.0/fpm/conf.d/20-exif.ini +etc/php/7.0/fpm/conf.d/20-fileinfo.ini +etc/php/7.0/fpm/conf.d/20-ftp.ini +etc/php/7.0/fpm/conf.d/20-gettext.ini +etc/php/7.0/fpm/conf.d/20-iconv.ini +etc/php/7.0/fpm/conf.d/20-intl.ini +etc/php/7.0/fpm/conf.d/20-json.ini +etc/php/7.0/fpm/conf.d/20-mbstring.ini +etc/php/7.0/fpm/conf.d/20-mysqli.ini +etc/php/7.0/fpm/conf.d/20-pdo_mysql.ini +etc/php/7.0/fpm/conf.d/20-phar.ini +etc/php/7.0/fpm/conf.d/20-posix.ini +etc/php/7.0/fpm/conf.d/20-readline.ini +etc/php/7.0/fpm/conf.d/20-shmop.ini +etc/php/7.0/fpm/conf.d/20-simplexml.ini +etc/php/7.0/fpm/conf.d/20-sockets.ini +etc/php/7.0/fpm/conf.d/20-sysvmsg.ini +etc/php/7.0/fpm/conf.d/20-sysvsem.ini +etc/php/7.0/fpm/conf.d/20-sysvshm.ini +etc/php/7.0/fpm/conf.d/20-tokenizer.ini +etc/php/7.0/fpm/conf.d/20-wddx.ini +etc/php/7.0/fpm/conf.d/20-xmlreader.ini +etc/php/7.0/fpm/conf.d/20-xmlwriter.ini +etc/php/7.0/fpm/conf.d/20-xsl.ini +etc/php/7.0/fpm/php-fpm.conf +etc/php/7.0/fpm/php.ini +etc/php/7.0/fpm/pool.d +etc/php/7.0/fpm/pool.d/www.conf +etc/php/7.0/mods-available/bcmath.ini +etc/php/7.0/mods-available/calendar.ini +etc/php/7.0/mods-available/ctype.ini +etc/php/7.0/mods-available/curl.ini +etc/php/7.0/mods-available/dom.ini +etc/php/7.0/mods-available/exif.ini +etc/php/7.0/mods-available/fileinfo.ini +etc/php/7.0/mods-available/ftp.ini +etc/php/7.0/mods-available/gettext.ini +etc/php/7.0/mods-available/iconv.ini +etc/php/7.0/mods-available/intl.ini +etc/php/7.0/mods-available/json.ini +etc/php/7.0/mods-available/mbstring.ini +etc/php/7.0/mods-available/mysqli.ini +etc/php/7.0/mods-available/mysqlnd.ini +etc/php/7.0/mods-available/opcache.ini +etc/php/7.0/mods-available/pdo.ini +etc/php/7.0/mods-available/pdo_mysql.ini +etc/php/7.0/mods-available/phar.ini +etc/php/7.0/mods-available/posix.ini +etc/php/7.0/mods-available/readline.ini +etc/php/7.0/mods-available/shmop.ini +etc/php/7.0/mods-available/simplexml.ini +etc/php/7.0/mods-available/sockets.ini +etc/php/7.0/mods-available/sysvmsg.ini +etc/php/7.0/mods-available/sysvsem.ini +etc/php/7.0/mods-available/sysvshm.ini +etc/php/7.0/mods-available/tokenizer.ini +etc/php/7.0/mods-available/wddx.ini +etc/php/7.0/mods-available/xml.ini +etc/php/7.0/mods-available/xmlreader.ini +etc/php/7.0/mods-available/xmlwriter.ini +etc/php/7.0/mods-available/xsl.ini +etc/services +etc/ssl/openssl.cnf +lib/terminfo/d/dumb +lib/x86_64-linux-gnu/ld-2.19.so +lib/x86_64-linux-gnu/libacl.so.1 +lib/x86_64-linux-gnu/libacl.so.1.1.0 +lib/x86_64-linux-gnu/libaio.so.1 +lib/x86_64-linux-gnu/libaio.so.1.0.1 +lib/x86_64-linux-gnu/libattr.so.1 +lib/x86_64-linux-gnu/libattr.so.1.1.0 +lib/x86_64-linux-gnu/libaudit.so.1 +lib/x86_64-linux-gnu/libaudit.so.1.0.0 +lib/x86_64-linux-gnu/libbsd.so.0 +lib/x86_64-linux-gnu/libbsd.so.0.7.0 +lib/x86_64-linux-gnu/libbz2.so.1.0 +lib/x86_64-linux-gnu/libbz2.so.1.0.4 +lib/x86_64-linux-gnu/libc-2.19.so +lib/x86_64-linux-gnu/libc.so.6 +lib/x86_64-linux-gnu/libcom_err.so.2 +lib/x86_64-linux-gnu/libcom_err.so.2.1 +lib/x86_64-linux-gnu/libcrypt-2.19.so +lib/x86_64-linux-gnu/libcrypt.so.1 +lib/x86_64-linux-gnu/libdl-2.19.so +lib/x86_64-linux-gnu/libdl.so.2 +lib/x86_64-linux-gnu/libexpat.so.1 +lib/x86_64-linux-gnu/libexpat.so.1.6.0 +lib/x86_64-linux-gnu/libgcc_s.so.1 +lib/x86_64-linux-gnu/libgcrypt.so.20 +lib/x86_64-linux-gnu/libgcrypt.so.20.0.3 +lib/x86_64-linux-gnu/libgpg-error.so.0 +lib/x86_64-linux-gnu/libgpg-error.so.0.13.0 +lib/x86_64-linux-gnu/libjson-c.so.2 +lib/x86_64-linux-gnu/libjson-c.so.2.0.0 +lib/x86_64-linux-gnu/libkeyutils.so.1 +lib/x86_64-linux-gnu/libkeyutils.so.1.5 +lib/x86_64-linux-gnu/liblzma.so.5 +lib/x86_64-linux-gnu/liblzma.so.5.0.0 +lib/x86_64-linux-gnu/libm-2.19.so +lib/x86_64-linux-gnu/libm.so.6 +lib/x86_64-linux-gnu/libncurses.so.5 +lib/x86_64-linux-gnu/libncurses.so.5.9 +lib/x86_64-linux-gnu/libnsl-2.19.so +lib/x86_64-linux-gnu/libnsl.so.1 +lib/x86_64-linux-gnu/libnss_compat-2.19.so +lib/x86_64-linux-gnu/libnss_compat.so.2 +lib/x86_64-linux-gnu/libnss_dns-2.19.so +lib/x86_64-linux-gnu/libnss_dns.so.2 +lib/x86_64-linux-gnu/libnss_files-2.19.so +lib/x86_64-linux-gnu/libnss_files.so.2 +lib/x86_64-linux-gnu/libnss_nis-2.19.so +lib/x86_64-linux-gnu/libnss_nis.so.2 +lib/x86_64-linux-gnu/libpam.so.0 +lib/x86_64-linux-gnu/libpam.so.0.83.1 +lib/x86_64-linux-gnu/libpcre.so.3 +lib/x86_64-linux-gnu/libpcre.so.3.13.3 +lib/x86_64-linux-gnu/libpng12.so.0 +lib/x86_64-linux-gnu/libpng12.so.0.50.0 +lib/x86_64-linux-gnu/libpthread-2.19.so +lib/x86_64-linux-gnu/libpthread.so.0 +lib/x86_64-linux-gnu/libreadline.so.6 +lib/x86_64-linux-gnu/libreadline.so.6.3 +lib/x86_64-linux-gnu/libresolv-2.19.so +lib/x86_64-linux-gnu/libresolv.so.2 +lib/x86_64-linux-gnu/librt-2.19.so +lib/x86_64-linux-gnu/librt.so.1 +lib/x86_64-linux-gnu/libselinux.so.1 +lib/x86_64-linux-gnu/libsystemd.so.0 +lib/x86_64-linux-gnu/libsystemd.so.0.3.1 +lib/x86_64-linux-gnu/libtinfo.so.5 +lib/x86_64-linux-gnu/libtinfo.so.5.9 +lib/x86_64-linux-gnu/libutil-2.19.so +lib/x86_64-linux-gnu/libutil.so.1 +lib/x86_64-linux-gnu/libwrap.so.0 +lib/x86_64-linux-gnu/libwrap.so.0.7.6 +lib/x86_64-linux-gnu/libz.so.1 +lib/x86_64-linux-gnu/libz.so.1.2.8 +lib64/ld-linux-x86-64.so.2 +opt/app +opt/app/.env +opt/app/.sandstorm/launcher.sh +opt/app/.sandstorm/service-config/mime.types +opt/app/.sandstorm/service-config/nginx.conf +opt/app/app/Bootstrap/ConfigureLogging.php +opt/app/app/Console/Commands/CreateImport.php +opt/app/app/Console/Commands/EncryptFile.php +opt/app/app/Console/Commands/Import.php +opt/app/app/Console/Commands/ScanAttachments.php +opt/app/app/Console/Commands/UpgradeDatabase.php +opt/app/app/Console/Commands/UpgradeFireflyInstructions.php +opt/app/app/Console/Commands/UseEncryption.php +opt/app/app/Console/Commands/VerifyDatabase.php +opt/app/app/Console/Kernel.php +opt/app/app/Exceptions/Handler.php +opt/app/app/Generator/Chart/Basic/ChartJsGenerator.php +opt/app/app/Generator/Chart/Basic/GeneratorInterface.php +opt/app/app/Helpers/Attachments/AttachmentHelper.php +opt/app/app/Helpers/Attachments/AttachmentHelperInterface.php +opt/app/app/Helpers/Collector/JournalCollector.php +opt/app/app/Helpers/Collector/JournalCollectorInterface.php +opt/app/app/Helpers/FiscalHelper.php +opt/app/app/Helpers/FiscalHelperInterface.php +opt/app/app/Helpers/Report/ReportHelper.php +opt/app/app/Helpers/Report/ReportHelperInterface.php +opt/app/app/Http/Controllers/Auth/LoginController.php +opt/app/app/Http/Controllers/BudgetController.php +opt/app/app/Http/Controllers/Chart/AccountController.php +opt/app/app/Http/Controllers/Chart/BudgetController.php +opt/app/app/Http/Controllers/Chart/CategoryController.php +opt/app/app/Http/Controllers/Controller.php +opt/app/app/Http/Controllers/HomeController.php +opt/app/app/Http/Controllers/JavascriptController.php +opt/app/app/Http/Controllers/JsonController.php +opt/app/app/Http/Controllers/NewUserController.php +opt/app/app/Http/Controllers/ProfileController.php +opt/app/app/Http/Controllers/ReportController.php +opt/app/app/Http/Controllers/Transaction/SingleController.php +opt/app/app/Http/Kernel.php +opt/app/app/Http/Middleware/Authenticate.php +opt/app/app/Http/Middleware/AuthenticateTwoFactor.php +opt/app/app/Http/Middleware/Binder.php +opt/app/app/Http/Middleware/EncryptCookies.php +opt/app/app/Http/Middleware/Range.php +opt/app/app/Http/Middleware/RedirectIfAuthenticated.php +opt/app/app/Http/Middleware/Sandstorm.php +opt/app/app/Http/Middleware/StartFireflySession.php +opt/app/app/Http/Middleware/VerifyCsrfToken.php +opt/app/app/Http/Requests/JournalFormRequest.php +opt/app/app/Http/Requests/NewUserFormRequest.php +opt/app/app/Http/Requests/ProfileFormRequest.php +opt/app/app/Http/Requests/Request.php +opt/app/app/Http/breadcrumbs.php +opt/app/app/Jobs/Job.php +opt/app/app/Jobs/MailError.php +opt/app/app/Models/Account.php +opt/app/app/Models/AccountMeta.php +opt/app/app/Models/AccountType.php +opt/app/app/Models/AvailableBudget.php +opt/app/app/Models/Bill.php +opt/app/app/Models/Budget.php +opt/app/app/Models/BudgetLimit.php +opt/app/app/Models/Category.php +opt/app/app/Models/Configuration.php +opt/app/app/Models/PiggyBank.php +opt/app/app/Models/Preference.php +opt/app/app/Models/Role.php +opt/app/app/Models/Tag.php +opt/app/app/Models/Transaction.php +opt/app/app/Models/TransactionCurrency.php +opt/app/app/Models/TransactionJournal.php +opt/app/app/Models/TransactionType.php +opt/app/app/Providers/AccountServiceProvider.php +opt/app/app/Providers/AppServiceProvider.php +opt/app/app/Providers/AttachmentServiceProvider.php +opt/app/app/Providers/AuthServiceProvider.php +opt/app/app/Providers/BillServiceProvider.php +opt/app/app/Providers/BudgetServiceProvider.php +opt/app/app/Providers/CategoryServiceProvider.php +opt/app/app/Providers/CurrencyServiceProvider.php +opt/app/app/Providers/EventServiceProvider.php +opt/app/app/Providers/ExportJobServiceProvider.php +opt/app/app/Providers/FireflyServiceProvider.php +opt/app/app/Providers/FireflySessionProvider.php +opt/app/app/Providers/JournalServiceProvider.php +opt/app/app/Providers/LogServiceProvider.php +opt/app/app/Providers/PiggyBankServiceProvider.php +opt/app/app/Providers/RouteServiceProvider.php +opt/app/app/Providers/RuleGroupServiceProvider.php +opt/app/app/Providers/RuleServiceProvider.php +opt/app/app/Providers/SearchServiceProvider.php +opt/app/app/Providers/TagServiceProvider.php +opt/app/app/Repositories/Account/AccountRepository.php +opt/app/app/Repositories/Account/AccountRepositoryInterface.php +opt/app/app/Repositories/Account/AccountTasker.php +opt/app/app/Repositories/Account/AccountTaskerInterface.php +opt/app/app/Repositories/Bill/BillRepository.php +opt/app/app/Repositories/Bill/BillRepositoryInterface.php +opt/app/app/Repositories/Budget/BudgetRepository.php +opt/app/app/Repositories/Budget/BudgetRepositoryInterface.php +opt/app/app/Repositories/Category/CategoryRepository.php +opt/app/app/Repositories/Category/CategoryRepositoryInterface.php +opt/app/app/Repositories/Journal/JournalRepository.php +opt/app/app/Repositories/Journal/JournalRepositoryInterface.php +opt/app/app/Repositories/PiggyBank/PiggyBankRepository.php +opt/app/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +opt/app/app/Repositories/Tag/TagRepository.php +opt/app/app/Repositories/Tag/TagRepositoryInterface.php +opt/app/app/Repositories/User/UserRepositoryInterface.php +opt/app/app/Support/Amount.php +opt/app/app/Support/CacheProperties.php +opt/app/app/Support/Domain.php +opt/app/app/Support/ExpandedForm.php +opt/app/app/Support/Facades/Amount.php +opt/app/app/Support/Facades/ExpandedForm.php +opt/app/app/Support/Facades/FireflyConfig.php +opt/app/app/Support/Facades/Navigation.php +opt/app/app/Support/Facades/Preferences.php +opt/app/app/Support/Facades/Steam.php +opt/app/app/Support/FireflyConfig.php +opt/app/app/Support/Models/TagSupport.php +opt/app/app/Support/Models/TransactionJournalSupport.php +opt/app/app/Support/Navigation.php +opt/app/app/Support/Preferences.php +opt/app/app/Support/Steam.php +opt/app/app/Support/Twig/General.php +opt/app/app/Support/Twig/Journal.php +opt/app/app/Support/Twig/PiggyBank.php +opt/app/app/Support/Twig/Rule.php +opt/app/app/Support/Twig/Transaction.php +opt/app/app/Support/Twig/Translation.php +opt/app/app/User.php +opt/app/app/Validation/FireflyValidator.php +opt/app/artisan +opt/app/bootstrap/app.php +opt/app/bootstrap/autoload.php +opt/app/bootstrap/cache/services.php +opt/app/config +opt/app/config/app.php +opt/app/config/auth.php +opt/app/config/broadcasting.php +opt/app/config/cache.php +opt/app/config/compile.php +opt/app/config/csv.php +opt/app/config/database.php +opt/app/config/filesystems.php +opt/app/config/firefly.php +opt/app/config/mail.php +opt/app/config/queue.php +opt/app/config/services.php +opt/app/config/session.php +opt/app/config/twigbridge.php +opt/app/config/upgrade.php +opt/app/config/view.php +opt/app/database/migrations +opt/app/database/migrations/2016_06_16_000000_create_support_tables.php +opt/app/database/migrations/2016_06_16_000001_create_users_table.php +opt/app/database/migrations/2016_06_16_000002_create_main_tables.php +opt/app/database/migrations/2016_08_25_091522_changes_for_3101.php +opt/app/database/migrations/2016_09_12_121359_fix_nullables.php +opt/app/database/migrations/2016_10_09_150037_expand_transactions_table.php +opt/app/database/migrations/2016_10_22_075804_changes_for_v410.php +opt/app/database/migrations/2016_11_24_210552_changes_for_v420.php +opt/app/database/migrations/2016_12_22_150431_changes_for_v430.php +opt/app/database/migrations/2016_12_28_203205_changes_for_v431.php +opt/app/database/seeds/AccountTypeSeeder.php +opt/app/database/seeds/DatabaseSeeder.php +opt/app/database/seeds/PermissionSeeder.php +opt/app/database/seeds/TransactionCurrencySeeder.php +opt/app/database/seeds/TransactionTypeSeeder.php +opt/app/public/css/bootstrap-multiselect.css +opt/app/public/css/bootstrap-tagsinput.css +opt/app/public/css/bootstrap-tour.min.css +opt/app/public/css/daterangepicker.css +opt/app/public/css/firefly.css +opt/app/public/css/jquery-ui/jquery-ui.structure.min.css +opt/app/public/css/jquery-ui/jquery-ui.theme.min.css +opt/app/public/index.php +opt/app/public/js/ff/budgets/index.js +opt/app/public/js/ff/charts.defaults.js +opt/app/public/js/ff/charts.js +opt/app/public/js/ff/firefly.js +opt/app/public/js/ff/guest.js +opt/app/public/js/ff/help.js +opt/app/public/js/ff/index.js +opt/app/public/js/ff/reports/index.js +opt/app/public/js/ff/transactions/single/create.js +opt/app/public/js/lib/Chart.bundle.min.js +opt/app/public/js/lib/accounting.min.js +opt/app/public/js/lib/bootstrap-multiselect.js +opt/app/public/js/lib/bootstrap-tagsinput.min.js +opt/app/public/js/lib/bootstrap-tour.min.js +opt/app/public/js/lib/bootstrap3-typeahead.min.js +opt/app/public/js/lib/daterangepicker.js +opt/app/public/js/lib/jquery-3.1.1.min.js +opt/app/public/js/lib/jquery-ui.min.js +opt/app/public/js/lib/modernizr-custom.js +opt/app/public/js/lib/moment.min.js +opt/app/public/lib/adminlte/css/AdminLTE.min.css +opt/app/public/lib/adminlte/css/skins/skin-blue-light.min.css +opt/app/public/lib/adminlte/js/app.min.js +opt/app/public/lib/bootstrap/css/bootstrap.min.css +opt/app/public/lib/bootstrap/js/bootstrap.min.js +opt/app/public/lib/font-awesome/css/font-awesome.min.css +opt/app/public/lib/font-awesome/fonts/fontawesome-webfont.woff2 +opt/app/resources/lang/en_US/breadcrumbs.php +opt/app/resources/lang/en_US/config.php +opt/app/resources/lang/en_US/firefly.php +opt/app/resources/lang/en_US/form.php +opt/app/resources/lang/en_US/help.php +opt/app/resources/lang/en_US/validation.php +opt/app/resources/views/auth/login.twig +opt/app/resources/views/budgets/index.twig +opt/app/resources/views/emails/error-html.twig +opt/app/resources/views/emails/error-text.twig +opt/app/resources/views/emails/footer-html.twig +opt/app/resources/views/emails/footer-text.twig +opt/app/resources/views/emails/header-html.twig +opt/app/resources/views/emails/header-text.twig +opt/app/resources/views/error.twig +opt/app/resources/views/form/amount.twig +opt/app/resources/views/form/balance.twig +opt/app/resources/views/form/date.twig +opt/app/resources/views/form/feedback.twig +opt/app/resources/views/form/help.twig +opt/app/resources/views/form/options.twig +opt/app/resources/views/form/select.twig +opt/app/resources/views/form/text.twig +opt/app/resources/views/index.twig +opt/app/resources/views/javascript/variables.twig +opt/app/resources/views/json/tour.twig +opt/app/resources/views/layout/default.twig +opt/app/resources/views/layout/guest.twig +opt/app/resources/views/list/journals-tiny-tasker.twig +opt/app/resources/views/new-user/index.twig +opt/app/resources/views/partials/boxes.twig +opt/app/resources/views/partials/control-bar.twig +opt/app/resources/views/partials/favicons.twig +opt/app/resources/views/partials/flashes.twig +opt/app/resources/views/partials/menu-sidebar.twig +opt/app/resources/views/partials/page-header.twig +opt/app/resources/views/profile/change-password.twig +opt/app/resources/views/profile/delete-account.twig +opt/app/resources/views/profile/index.twig +opt/app/resources/views/reports/index.twig +opt/app/resources/views/reports/options/no-options.twig +opt/app/resources/views/transactions/single/create.twig +opt/app/routes/api.php +opt/app/routes/console.php +opt/app/routes/web.php +opt/app/storage +opt/app/vendor/autoload.php +opt/app/vendor/composer/ClassLoader.php +opt/app/vendor/composer/autoload_real.php +opt/app/vendor/composer/autoload_static.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/config/breadcrumbs.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/src/CurrentRoute.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/src/Facade.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/src/Generator.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/src/Manager.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/src/ServiceProvider.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/src/View.php +opt/app/vendor/davejamesmiller/laravel-breadcrumbs/views/bootstrap3.blade.php +opt/app/vendor/doctrine/common/lib/Doctrine/Common/EventManager.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Configuration.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/AbstractMySQLDriver.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/DriverException.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ExceptionConverterDriver.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOException.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOMySql/Driver.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ServerInfoAwareConnection.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Events.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/KeywordList.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/Keywords/MySQLKeywords.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Query/Expression/ExpressionBuilder.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractAsset.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/AbstractSchemaManager.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Column.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Comparator.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Constraint.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/ForeignKeyConstraint.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Identifier.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Index.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/MySqlSchemaManager.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/Table.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Schema/TableDiff.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ArrayType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BigIntType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BinaryType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BlobType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/BooleanType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateTimeTzType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DateType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/DecimalType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/FloatType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/GuidType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/IntegerType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/JsonArrayType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/ObjectType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SimpleArrayType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/SmallIntType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/StringType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TextType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/TimeType.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/Types/Type.php +opt/app/vendor/doctrine/dbal/lib/Doctrine/DBAL/VersionAwarePlatformDriver.php +opt/app/vendor/doctrine/inflector/lib/Doctrine/Common/Inflector/Inflector.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Access/Gate.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Access/HandlesAuthorization.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/AuthManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/AuthServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Authenticatable.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Console/ClearResetsCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Console/MakeAuthCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/CreatesUserProviders.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Events/Authenticated.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Events/Login.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/GuardHelpers.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Passwords/CanResetPassword.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordResetServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Auth/SessionGuard.php +opt/app/vendor/laravel/framework/src/Illuminate/Broadcasting/BroadcastServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Bus/BusServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Bus/Dispatcher.php +opt/app/vendor/laravel/framework/src/Illuminate/Bus/Queueable.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/CacheServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Console/CacheTableCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Console/ClearCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Console/ForgetCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Events/CacheEvent.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Events/CacheHit.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Events/CacheMissed.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Events/KeyForgotten.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Events/KeyWritten.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/FileStore.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/Repository.php +opt/app/vendor/laravel/framework/src/Illuminate/Cache/RetrievesMultipleKeys.php +opt/app/vendor/laravel/framework/src/Illuminate/Config/Repository.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Application.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Command.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/ConfirmableTrait.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/DetectsApplicationNamespace.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Events/ArtisanStarting.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/GeneratorCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/OutputStyle.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Parser.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/Schedule.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleFinishCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Console/Scheduling/ScheduleRunCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php +opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/Access/Authorizable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/Access/Gate.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/Authenticatable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/CanResetPassword.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/Guard.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/StatefulGuard.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/SupportsBasicAuth.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Auth/UserProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Bus/Dispatcher.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Bus/QueueingDispatcher.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Cache/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Cache/Repository.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Cache/Store.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Config/Repository.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Console/Application.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Console/Kernel.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Container/Container.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Cookie/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Cookie/QueueingFactory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Debug/ExceptionHandler.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Encryption/DecryptException.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Encryption/Encrypter.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Events/Dispatcher.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Filesystem/Cloud.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Filesystem/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Filesystem/FileNotFoundException.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Filesystem/Filesystem.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Foundation/Application.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Hashing/Hasher.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Http/Kernel.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Logging/Log.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Mail/MailQueue.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Mail/Mailer.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Pagination/Paginator.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Pipeline/Pipeline.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/Job.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/Monitor.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/Queue.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/QueueableCollection.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/QueueableEntity.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Queue/ShouldQueue.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Routing/BindingRegistrar.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Routing/Registrar.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Routing/ResponseFactory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Routing/UrlGenerator.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Routing/UrlRoutable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Session/Session.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Support/Arrayable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Support/Htmlable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Support/Jsonable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Support/MessageBag.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Support/MessageProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Support/Renderable.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Translation/Translator.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Validation/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Validation/ValidatesWhenResolved.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/Validation/Validator.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/View/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Contracts/View/View.php +opt/app/vendor/laravel/framework/src/Illuminate/Cookie/CookieJar.php +opt/app/vendor/laravel/framework/src/Illuminate/Cookie/CookieServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php +opt/app/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Concerns/ManagesTransactions.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/ConnectionInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/ConnectionResolverInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectionFactory.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Connectors/ConnectorInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Connectors/MySqlConnector.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/BaseCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/InstallCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/MigrateMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/RefreshCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/ResetCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/RollbackCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/StatusCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeedCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Console/Seeds/SeederMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/DatabaseServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/DetectsDeadlocks.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/DetectsLostConnections.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Collection.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/GuardsAttributes.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasEvents.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasGlobalScopes.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasRelationships.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HasTimestamps.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/HidesAttributes.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsTo.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Concerns/InteractsWithPivotTable.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasMany.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasManyThrough.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/HasOneOrMany.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Relations/Relation.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Scope.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/SoftDeletes.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/SoftDeletingScope.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Events/QueryExecuted.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Events/StatementPrepared.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Grammar.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/MigrationServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Migrations/DatabaseMigrationRepository.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migration.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Migrations/MigrationCreator.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Migrations/MigrationRepositoryInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/MySqlConnection.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/Expression.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/Grammar.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/Grammars/MySqlGrammar.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/JoinClause.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/Processors/MySqlProcessor.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Query/Processors/Processor.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/QueryException.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/Builder.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/Grammars/ChangeColumn.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/Grammars/Grammar.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/Grammars/RenameColumn.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Schema/MySqlBuilder.php +opt/app/vendor/laravel/framework/src/Illuminate/Database/Seeder.php +opt/app/vendor/laravel/framework/src/Illuminate/Encryption/Encrypter.php +opt/app/vendor/laravel/framework/src/Illuminate/Encryption/EncryptionServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Events/Dispatcher.php +opt/app/vendor/laravel/framework/src/Illuminate/Events/EventServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php +opt/app/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemAdapter.php +opt/app/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/AliasLoader.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Auth/Access/Authorizable.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Auth/Access/AuthorizesRequests.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Auth/RedirectsUsers.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Auth/ThrottlesLogins.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Auth/User.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/BootProviders.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/LoadConfiguration.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/LoadEnvironmentVariables.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/RegisterFacades.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/RegisterProviders.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/SetRequestForConsole.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Bus/DispatchesJobs.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/AppNameCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ClearCompiledCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ConfigCacheCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ConfigClearCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ConsoleMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/DownCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/EnvironmentCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/EventGenerateCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/EventMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/JobMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/KeyGenerateCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ListenerMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/MailMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ModelMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/NotificationMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/OptimizeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/PolicyMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ProviderMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/RequestMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/RouteCacheCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/RouteClearCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/RouteListCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ServeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/StorageLinkCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/TestMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/UpCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/VendorPublishCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/ViewClearCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/EnvironmentDetector.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Events/LocaleUpdated.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Events/RequestHandled.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/FormRequest.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Providers/ArtisanServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Providers/ComposerServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Providers/ConsoleSupportServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Providers/FormRequestServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Providers/FoundationServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/AuthServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/EventServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Support/Providers/RouteServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Validation/ValidatesRequests.php +opt/app/vendor/laravel/framework/src/Illuminate/Foundation/helpers.php +opt/app/vendor/laravel/framework/src/Illuminate/Hashing/BcryptHasher.php +opt/app/vendor/laravel/framework/src/Illuminate/Hashing/HashServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithContentTypes.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithFlashData.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/Concerns/InteractsWithInput.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/JsonResponse.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/RedirectResponse.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/Request.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/Response.php +opt/app/vendor/laravel/framework/src/Illuminate/Http/ResponseTrait.php +opt/app/vendor/laravel/framework/src/Illuminate/Log/Events/MessageLogged.php +opt/app/vendor/laravel/framework/src/Illuminate/Log/LogServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Log/Writer.php +opt/app/vendor/laravel/framework/src/Illuminate/Mail/Events/MessageSending.php +opt/app/vendor/laravel/framework/src/Illuminate/Mail/MailServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Mail/Mailer.php +opt/app/vendor/laravel/framework/src/Illuminate/Mail/Message.php +opt/app/vendor/laravel/framework/src/Illuminate/Mail/TransportManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Notifications/Console/NotificationTableCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Notifications/HasDatabaseNotifications.php +opt/app/vendor/laravel/framework/src/Illuminate/Notifications/Notifiable.php +opt/app/vendor/laravel/framework/src/Illuminate/Notifications/NotificationServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php +opt/app/vendor/laravel/framework/src/Illuminate/Pagination/AbstractPaginator.php +opt/app/vendor/laravel/framework/src/Illuminate/Pagination/PaginationServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Pagination/Paginator.php +opt/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php +opt/app/vendor/laravel/framework/src/Illuminate/Pipeline/PipelineServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/CallQueuedHandler.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Connectors/ConnectorInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Connectors/SyncConnector.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/FailedTableCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/FlushFailedCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/ForgetFailedCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/ListFailedCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/ListenCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/RestartCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/RetryCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/TableCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Console/WorkCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Events/JobProcessed.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Events/JobProcessing.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/InteractsWithQueue.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Jobs/Job.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Jobs/SyncJob.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Listener.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Queue.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/QueueManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/QueueServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/SerializesAndRestoresModelIdentifiers.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/SerializesModels.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/SyncQueue.php +opt/app/vendor/laravel/framework/src/Illuminate/Queue/Worker.php +opt/app/vendor/laravel/framework/src/Illuminate/Redis/RedisServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/ControllerMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Console/MiddlewareMakeCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerMiddlewareOptions.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Events/RouteMatched.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/ImplicitRouteBinding.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/HostValidator.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/MethodValidator.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/SchemeValidator.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/UriValidator.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Matching/ValidatorInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/MiddlewareNameResolver.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Redirector.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/ResponseFactory.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Route.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteAction.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteCompiler.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteGroup.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteParameterBinder.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteSignatureParameters.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RouteUrlGenerator.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/RoutingServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/SortedMiddleware.php +opt/app/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/Console/SessionTableCommand.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/EncryptedStore.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/FileSessionHandler.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/SessionManager.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/SessionServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/Store.php +opt/app/vendor/laravel/framework/src/Illuminate/Session/TokenMismatchException.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/AggregateServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Arr.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Collection.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Composer.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/App.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Auth.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Cache.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Config.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Crypt.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/DB.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Event.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Gate.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Input.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Log.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Mail.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Request.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Response.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Route.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Schema.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Session.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Storage.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/URL.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/Validator.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Facades/View.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Fluent.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/HtmlString.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Manager.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/MessageBag.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/NamespacedItemResolver.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Pluralizer.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/ServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Str.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/Traits/Macroable.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/ViewErrorBag.php +opt/app/vendor/laravel/framework/src/Illuminate/Support/helpers.php +opt/app/vendor/laravel/framework/src/Illuminate/Translation/FileLoader.php +opt/app/vendor/laravel/framework/src/Illuminate/Translation/LoaderInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Translation/TranslationServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Translation/Translator.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/Concerns/FormatsMessages.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/Concerns/ReplacesAttributes.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/DatabasePresenceVerifier.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/PresenceVerifierInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/ValidatesWhenResolvedTrait.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/ValidationException.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/ValidationRuleParser.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/ValidationServiceProvider.php +opt/app/vendor/laravel/framework/src/Illuminate/Validation/Validator.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/BladeCompiler.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Compiler.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/CompilerInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesAuthorizations.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesComments.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesComponents.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesEchos.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesIncludes.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesInjections.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesLayouts.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesLoops.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesRawPhp.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesStacks.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Compilers/Concerns/CompilesTranslations.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesComponents.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesEvents.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesLayouts.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesLoops.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesStacks.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Concerns/ManagesTranslations.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Engines/CompilerEngine.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Engines/EngineInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Engines/EngineResolver.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Engines/PhpEngine.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Factory.php +opt/app/vendor/laravel/framework/src/Illuminate/View/FileViewFinder.php +opt/app/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php +opt/app/vendor/laravel/framework/src/Illuminate/View/View.php +opt/app/vendor/laravel/framework/src/Illuminate/View/ViewFinderInterface.php +opt/app/vendor/laravel/framework/src/Illuminate/View/ViewName.php +opt/app/vendor/laravel/framework/src/Illuminate/View/ViewServiceProvider.php +opt/app/vendor/laravelcollective/html/src/Componentable.php +opt/app/vendor/laravelcollective/html/src/FormBuilder.php +opt/app/vendor/laravelcollective/html/src/FormFacade.php +opt/app/vendor/laravelcollective/html/src/HtmlBuilder.php +opt/app/vendor/laravelcollective/html/src/HtmlServiceProvider.php +opt/app/vendor/laravelcollective/html/src/helpers.php +opt/app/vendor/league/flysystem/src/Adapter/AbstractAdapter.php +opt/app/vendor/league/flysystem/src/Adapter/Local.php +opt/app/vendor/league/flysystem/src/AdapterInterface.php +opt/app/vendor/league/flysystem/src/Config.php +opt/app/vendor/league/flysystem/src/ConfigAwareTrait.php +opt/app/vendor/league/flysystem/src/Filesystem.php +opt/app/vendor/league/flysystem/src/FilesystemInterface.php +opt/app/vendor/league/flysystem/src/Plugin/PluggableTrait.php +opt/app/vendor/league/flysystem/src/ReadInterface.php +opt/app/vendor/monolog/monolog/src/Monolog/Formatter/FormatterInterface.php +opt/app/vendor/monolog/monolog/src/Monolog/Formatter/LineFormatter.php +opt/app/vendor/monolog/monolog/src/Monolog/Formatter/NormalizerFormatter.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/HandlerInterface.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php +opt/app/vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php +opt/app/vendor/monolog/monolog/src/Monolog/Logger.php +opt/app/vendor/nesbot/carbon/src/Carbon/Carbon.php +opt/app/vendor/nesbot/carbon/src/Carbon/Lang/en.php +opt/app/vendor/paragonie/random_compat/lib/random.php +opt/app/vendor/pragmarx/google2fa/src/Vendor/Laravel/ServiceProvider.php +opt/app/vendor/psr/log/Psr/Log/LoggerInterface.php +opt/app/vendor/rcrowe/twigbridge/config/twigbridge.php +opt/app/vendor/rcrowe/twigbridge/src/Bridge.php +opt/app/vendor/rcrowe/twigbridge/src/Command/Clean.php +opt/app/vendor/rcrowe/twigbridge/src/Command/Lint.php +opt/app/vendor/rcrowe/twigbridge/src/Command/TwigBridge.php +opt/app/vendor/rcrowe/twigbridge/src/Engine/Compiler.php +opt/app/vendor/rcrowe/twigbridge/src/Engine/Twig.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Auth.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Config.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Dump.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Input.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Session.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Str.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Translator.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Laravel/Url.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Loader/Facade/Caller.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Loader/Facades.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Loader/Filters.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Loader/Functions.php +opt/app/vendor/rcrowe/twigbridge/src/Extension/Loader/Loader.php +opt/app/vendor/rcrowe/twigbridge/src/Facade/Twig.php +opt/app/vendor/rcrowe/twigbridge/src/ServiceProvider.php +opt/app/vendor/rcrowe/twigbridge/src/Twig/Globals.php +opt/app/vendor/rcrowe/twigbridge/src/Twig/Loader.php +opt/app/vendor/rcrowe/twigbridge/src/Twig/Template.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ByteStream/AbstractFilterableInputStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterReaderFactory/SimpleCharacterReaderFactory.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/CharacterStream/NgCharacterStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/DependencyContainer.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/QpEncoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Encoder/Rfc2231Encoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/Event.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventDispatcher.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/EventObject.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/SimpleEventDispatcher.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportChangeEvent.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Events/TransportExceptionEvent.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Filterable.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/InputByteStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/IoException.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/DiskKeyCache.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/KeyCacheInputStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/KeyCache/SimpleKeyCacheInputStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mailer.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Message.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/CharsetObserver.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/NativeQpContentEncoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ContentEncoder/QpContentEncoderProxy.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/EncodingObserver.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Grammar.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Header.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderEncoder/QpHeaderEncoder.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderFactory.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/HeaderSet.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/AbstractHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/DateHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/IdentificationHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/MailboxHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/ParameterizedHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Headers/UnstructuredHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/Message.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimeEntity.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/MimePart.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/ParameterizedHeader.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderFactory.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleHeaderSet.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMessage.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Mime/SimpleMimeEntity.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/MimePart.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/OutputByteStream.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Preferences.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/ReplacementFilterFactory.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SmtpTransport.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilter.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/ByteArrayReplacementFilter.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/StreamFilters/StringReplacementFilterFactory.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/SwiftException.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/AbstractSmtpTransport.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/CramMd5Authenticator.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/LoginAuthenticator.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/NTLMAuthenticator.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/PlainAuthenticator.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Auth/XOAuth2Authenticator.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/AuthHandler.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/Esmtp/Authenticator.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpHandler.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/EsmtpTransport.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/IoBuffer.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/SmtpAgent.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/Transport/StreamBuffer.php +opt/app/vendor/swiftmailer/swiftmailer/lib/classes/Swift/TransportException.php +opt/app/vendor/swiftmailer/swiftmailer/lib/dependency_maps/cache_deps.php +opt/app/vendor/swiftmailer/swiftmailer/lib/dependency_maps/message_deps.php +opt/app/vendor/swiftmailer/swiftmailer/lib/dependency_maps/mime_deps.php +opt/app/vendor/swiftmailer/swiftmailer/lib/dependency_maps/transport_deps.php +opt/app/vendor/swiftmailer/swiftmailer/lib/mime_types.php +opt/app/vendor/swiftmailer/swiftmailer/lib/preferences.php +opt/app/vendor/swiftmailer/swiftmailer/lib/swift_init.php +opt/app/vendor/swiftmailer/swiftmailer/lib/swift_required.php +opt/app/vendor/symfony/console/Application.php +opt/app/vendor/symfony/console/Command/Command.php +opt/app/vendor/symfony/console/Command/HelpCommand.php +opt/app/vendor/symfony/console/Command/ListCommand.php +opt/app/vendor/symfony/console/Formatter/OutputFormatter.php +opt/app/vendor/symfony/console/Formatter/OutputFormatterInterface.php +opt/app/vendor/symfony/console/Formatter/OutputFormatterStyle.php +opt/app/vendor/symfony/console/Formatter/OutputFormatterStyleInterface.php +opt/app/vendor/symfony/console/Formatter/OutputFormatterStyleStack.php +opt/app/vendor/symfony/console/Helper/DebugFormatterHelper.php +opt/app/vendor/symfony/console/Helper/FormatterHelper.php +opt/app/vendor/symfony/console/Helper/Helper.php +opt/app/vendor/symfony/console/Helper/HelperInterface.php +opt/app/vendor/symfony/console/Helper/HelperSet.php +opt/app/vendor/symfony/console/Helper/ProcessHelper.php +opt/app/vendor/symfony/console/Helper/QuestionHelper.php +opt/app/vendor/symfony/console/Input/ArgvInput.php +opt/app/vendor/symfony/console/Input/ArrayInput.php +opt/app/vendor/symfony/console/Input/Input.php +opt/app/vendor/symfony/console/Input/InputArgument.php +opt/app/vendor/symfony/console/Input/InputDefinition.php +opt/app/vendor/symfony/console/Input/InputInterface.php +opt/app/vendor/symfony/console/Input/InputOption.php +opt/app/vendor/symfony/console/Input/StreamableInputInterface.php +opt/app/vendor/symfony/console/Output/BufferedOutput.php +opt/app/vendor/symfony/console/Output/ConsoleOutput.php +opt/app/vendor/symfony/console/Output/ConsoleOutputInterface.php +opt/app/vendor/symfony/console/Output/Output.php +opt/app/vendor/symfony/console/Output/OutputInterface.php +opt/app/vendor/symfony/console/Output/StreamOutput.php +opt/app/vendor/symfony/console/Style/OutputStyle.php +opt/app/vendor/symfony/console/Style/StyleInterface.php +opt/app/vendor/symfony/console/Style/SymfonyStyle.php +opt/app/vendor/symfony/console/Terminal.php +opt/app/vendor/symfony/debug/Exception/FatalErrorException.php +opt/app/vendor/symfony/debug/Exception/FatalThrowableError.php +opt/app/vendor/symfony/debug/Exception/FlattenException.php +opt/app/vendor/symfony/debug/ExceptionHandler.php +opt/app/vendor/symfony/finder/Comparator/Comparator.php +opt/app/vendor/symfony/finder/Comparator/DateComparator.php +opt/app/vendor/symfony/finder/Finder.php +opt/app/vendor/symfony/finder/Glob.php +opt/app/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php +opt/app/vendor/symfony/finder/Iterator/ExcludeDirectoryFilterIterator.php +opt/app/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php +opt/app/vendor/symfony/finder/Iterator/FilenameFilterIterator.php +opt/app/vendor/symfony/finder/Iterator/FilterIterator.php +opt/app/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php +opt/app/vendor/symfony/finder/Iterator/PathFilterIterator.php +opt/app/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php +opt/app/vendor/symfony/finder/SplFileInfo.php +opt/app/vendor/symfony/http-foundation/AcceptHeader.php +opt/app/vendor/symfony/http-foundation/AcceptHeaderItem.php +opt/app/vendor/symfony/http-foundation/Cookie.php +opt/app/vendor/symfony/http-foundation/FileBag.php +opt/app/vendor/symfony/http-foundation/HeaderBag.php +opt/app/vendor/symfony/http-foundation/JsonResponse.php +opt/app/vendor/symfony/http-foundation/ParameterBag.php +opt/app/vendor/symfony/http-foundation/RedirectResponse.php +opt/app/vendor/symfony/http-foundation/Request.php +opt/app/vendor/symfony/http-foundation/Response.php +opt/app/vendor/symfony/http-foundation/ResponseHeaderBag.php +opt/app/vendor/symfony/http-foundation/ServerBag.php +opt/app/vendor/symfony/http-foundation/Session/SessionBagInterface.php +opt/app/vendor/symfony/http-foundation/Session/SessionInterface.php +opt/app/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php +opt/app/vendor/symfony/http-kernel/HttpKernelInterface.php +opt/app/vendor/symfony/polyfill-mbstring/bootstrap.php +opt/app/vendor/symfony/polyfill-php56/bootstrap.php +opt/app/vendor/symfony/process/ExecutableFinder.php +opt/app/vendor/symfony/process/PhpExecutableFinder.php +opt/app/vendor/symfony/process/ProcessUtils.php +opt/app/vendor/symfony/routing/CompiledRoute.php +opt/app/vendor/symfony/routing/Route.php +opt/app/vendor/symfony/routing/RouteCompiler.php +opt/app/vendor/symfony/routing/RouteCompilerInterface.php +opt/app/vendor/symfony/translation/Loader/ArrayLoader.php +opt/app/vendor/symfony/translation/Loader/LoaderInterface.php +opt/app/vendor/symfony/translation/MessageSelector.php +opt/app/vendor/symfony/translation/Translator.php +opt/app/vendor/symfony/translation/TranslatorBagInterface.php +opt/app/vendor/symfony/translation/TranslatorInterface.php +opt/app/vendor/symfony/var-dumper/Cloner/AbstractCloner.php +opt/app/vendor/symfony/var-dumper/Cloner/ClonerInterface.php +opt/app/vendor/symfony/var-dumper/Cloner/VarCloner.php +opt/app/vendor/symfony/var-dumper/Resources/functions/dump.php +opt/app/vendor/twig/twig/lib/Twig/BaseNodeVisitor.php +opt/app/vendor/twig/twig/lib/Twig/Cache/Filesystem.php +opt/app/vendor/twig/twig/lib/Twig/CacheInterface.php +opt/app/vendor/twig/twig/lib/Twig/Compiler.php +opt/app/vendor/twig/twig/lib/Twig/CompilerInterface.php +opt/app/vendor/twig/twig/lib/Twig/Environment.php +opt/app/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php +opt/app/vendor/twig/twig/lib/Twig/ExpressionParser.php +opt/app/vendor/twig/twig/lib/Twig/Extension.php +opt/app/vendor/twig/twig/lib/Twig/Extension/Core.php +opt/app/vendor/twig/twig/lib/Twig/Extension/Debug.php +opt/app/vendor/twig/twig/lib/Twig/Extension/Escaper.php +opt/app/vendor/twig/twig/lib/Twig/Extension/GlobalsInterface.php +opt/app/vendor/twig/twig/lib/Twig/Extension/Optimizer.php +opt/app/vendor/twig/twig/lib/Twig/Extension/Staging.php +opt/app/vendor/twig/twig/lib/Twig/ExtensionInterface.php +opt/app/vendor/twig/twig/lib/Twig/Lexer.php +opt/app/vendor/twig/twig/lib/Twig/LexerInterface.php +opt/app/vendor/twig/twig/lib/Twig/Loader/Array.php +opt/app/vendor/twig/twig/lib/Twig/Loader/Chain.php +opt/app/vendor/twig/twig/lib/Twig/LoaderInterface.php +opt/app/vendor/twig/twig/lib/Twig/Markup.php +opt/app/vendor/twig/twig/lib/Twig/Node.php +opt/app/vendor/twig/twig/lib/Twig/Node/Block.php +opt/app/vendor/twig/twig/lib/Twig/Node/BlockReference.php +opt/app/vendor/twig/twig/lib/Twig/Node/Body.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Array.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Call.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Function.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Name.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Test.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php +opt/app/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php +opt/app/vendor/twig/twig/lib/Twig/Node/For.php +opt/app/vendor/twig/twig/lib/Twig/Node/ForLoop.php +opt/app/vendor/twig/twig/lib/Twig/Node/If.php +opt/app/vendor/twig/twig/lib/Twig/Node/Include.php +opt/app/vendor/twig/twig/lib/Twig/Node/Module.php +opt/app/vendor/twig/twig/lib/Twig/Node/Print.php +opt/app/vendor/twig/twig/lib/Twig/Node/Set.php +opt/app/vendor/twig/twig/lib/Twig/Node/Text.php +opt/app/vendor/twig/twig/lib/Twig/NodeInterface.php +opt/app/vendor/twig/twig/lib/Twig/NodeOutputInterface.php +opt/app/vendor/twig/twig/lib/Twig/NodeTraverser.php +opt/app/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php +opt/app/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php +opt/app/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php +opt/app/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php +opt/app/vendor/twig/twig/lib/Twig/Parser.php +opt/app/vendor/twig/twig/lib/Twig/ParserInterface.php +opt/app/vendor/twig/twig/lib/Twig/SimpleFilter.php +opt/app/vendor/twig/twig/lib/Twig/SimpleFunction.php +opt/app/vendor/twig/twig/lib/Twig/SimpleTest.php +opt/app/vendor/twig/twig/lib/Twig/Source.php +opt/app/vendor/twig/twig/lib/Twig/SourceContextLoaderInterface.php +opt/app/vendor/twig/twig/lib/Twig/Template.php +opt/app/vendor/twig/twig/lib/Twig/TemplateInterface.php +opt/app/vendor/twig/twig/lib/Twig/Token.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Block.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Do.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Embed.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Extends.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Filter.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Flush.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/For.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/From.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/If.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Import.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Include.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Macro.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Set.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/Use.php +opt/app/vendor/twig/twig/lib/Twig/TokenParser/With.php +opt/app/vendor/twig/twig/lib/Twig/TokenParserBroker.php +opt/app/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php +opt/app/vendor/twig/twig/lib/Twig/TokenParserInterface.php +opt/app/vendor/twig/twig/lib/Twig/TokenStream.php +opt/app/vendor/vlucas/phpdotenv/src/Dotenv.php +opt/app/vendor/vlucas/phpdotenv/src/Loader.php +opt/app/vendor/watson/validating/src/Injectors/UniqueInjector.php +opt/app/vendor/watson/validating/src/ValidatingObserver.php +opt/app/vendor/watson/validating/src/ValidatingTrait.php +proc/cpuinfo +sandstorm-http-bridge +sandstorm-http-bridge-config +sandstorm-manifest +usr/bin/my_print_defaults +usr/bin/mysql +usr/bin/mysql_install_db +usr/bin/php +usr/bin/php7.0 +usr/bin/sudo +usr/lib/locale/locale-archive +usr/lib/php/20151012/bcmath.so +usr/lib/php/20151012/calendar.so +usr/lib/php/20151012/ctype.so +usr/lib/php/20151012/curl.so +usr/lib/php/20151012/dom.so +usr/lib/php/20151012/exif.so +usr/lib/php/20151012/fileinfo.so +usr/lib/php/20151012/ftp.so +usr/lib/php/20151012/gettext.so +usr/lib/php/20151012/iconv.so +usr/lib/php/20151012/intl.so +usr/lib/php/20151012/json.so +usr/lib/php/20151012/mbstring.so +usr/lib/php/20151012/mysqli.so +usr/lib/php/20151012/mysqlnd.so +usr/lib/php/20151012/opcache.so +usr/lib/php/20151012/pdo.so +usr/lib/php/20151012/pdo_mysql.so +usr/lib/php/20151012/phar.so +usr/lib/php/20151012/posix.so +usr/lib/php/20151012/readline.so +usr/lib/php/20151012/shmop.so +usr/lib/php/20151012/simplexml.so +usr/lib/php/20151012/sockets.so +usr/lib/php/20151012/sysvmsg.so +usr/lib/php/20151012/sysvsem.so +usr/lib/php/20151012/sysvshm.so +usr/lib/php/20151012/tokenizer.so +usr/lib/php/20151012/wddx.so +usr/lib/php/20151012/xml.so +usr/lib/php/20151012/xmlreader.so +usr/lib/php/20151012/xmlwriter.so +usr/lib/php/20151012/xsl.so +usr/lib/ssl/openssl.cnf +usr/lib/x86_64-linux-gnu/libGeoIP.so.1 +usr/lib/x86_64-linux-gnu/libGeoIP.so.1.6.2 +usr/lib/x86_64-linux-gnu/libX11.so.6 +usr/lib/x86_64-linux-gnu/libX11.so.6.3.0 +usr/lib/x86_64-linux-gnu/libXau.so.6 +usr/lib/x86_64-linux-gnu/libXau.so.6.0.0 +usr/lib/x86_64-linux-gnu/libXdmcp.so.6 +usr/lib/x86_64-linux-gnu/libXdmcp.so.6.0.0 +usr/lib/x86_64-linux-gnu/libXpm.so.4 +usr/lib/x86_64-linux-gnu/libXpm.so.4.11.0 +usr/lib/x86_64-linux-gnu/libapparmor.so.1 +usr/lib/x86_64-linux-gnu/libapparmor.so.1.2.0 +usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0 +usr/lib/x86_64-linux-gnu/libcurl.so.4 +usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0 +usr/lib/x86_64-linux-gnu/libdb-5.3.so +usr/lib/x86_64-linux-gnu/libedit.so.2 +usr/lib/x86_64-linux-gnu/libedit.so.2.0.51 +usr/lib/x86_64-linux-gnu/libexslt.so.0 +usr/lib/x86_64-linux-gnu/libexslt.so.0.8.17 +usr/lib/x86_64-linux-gnu/libffi.so.6 +usr/lib/x86_64-linux-gnu/libffi.so.6.0.2 +usr/lib/x86_64-linux-gnu/libfontconfig.so.1 +usr/lib/x86_64-linux-gnu/libfontconfig.so.1.8.0 +usr/lib/x86_64-linux-gnu/libfreetype.so.6 +usr/lib/x86_64-linux-gnu/libfreetype.so.6.11.1 +usr/lib/x86_64-linux-gnu/libgd.so.3 +usr/lib/x86_64-linux-gnu/libgd.so.3.0.0 +usr/lib/x86_64-linux-gnu/libgmp.so.10 +usr/lib/x86_64-linux-gnu/libgmp.so.10.2.0 +usr/lib/x86_64-linux-gnu/libgnutls-deb0.so.28 +usr/lib/x86_64-linux-gnu/libgnutls-deb0.so.28.41.0 +usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2 +usr/lib/x86_64-linux-gnu/libgssapi_krb5.so.2.2 +usr/lib/x86_64-linux-gnu/libhogweed.so.2 +usr/lib/x86_64-linux-gnu/libhogweed.so.2.5 +usr/lib/x86_64-linux-gnu/libicudata.so.52 +usr/lib/x86_64-linux-gnu/libicudata.so.52.1 +usr/lib/x86_64-linux-gnu/libicui18n.so.52 +usr/lib/x86_64-linux-gnu/libicui18n.so.52.1 +usr/lib/x86_64-linux-gnu/libicuio.so.52 +usr/lib/x86_64-linux-gnu/libicuio.so.52.1 +usr/lib/x86_64-linux-gnu/libicuuc.so.52 +usr/lib/x86_64-linux-gnu/libicuuc.so.52.1 +usr/lib/x86_64-linux-gnu/libidn.so.11 +usr/lib/x86_64-linux-gnu/libidn.so.11.6.12 +usr/lib/x86_64-linux-gnu/libjbig.so.0 +usr/lib/x86_64-linux-gnu/libjpeg.so.62 +usr/lib/x86_64-linux-gnu/libjpeg.so.62.1.0 +usr/lib/x86_64-linux-gnu/libk5crypto.so.3 +usr/lib/x86_64-linux-gnu/libk5crypto.so.3.1 +usr/lib/x86_64-linux-gnu/libkrb5.so.3 +usr/lib/x86_64-linux-gnu/libkrb5.so.3.3 +usr/lib/x86_64-linux-gnu/libkrb5support.so.0 +usr/lib/x86_64-linux-gnu/libkrb5support.so.0.1 +usr/lib/x86_64-linux-gnu/liblber-2.4.so.2 +usr/lib/x86_64-linux-gnu/liblber-2.4.so.2.10.3 +usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2 +usr/lib/x86_64-linux-gnu/libldap_r-2.4.so.2.10.3 +usr/lib/x86_64-linux-gnu/libmysqlclient.so.18 +usr/lib/x86_64-linux-gnu/libmysqlclient.so.18.0.0 +usr/lib/x86_64-linux-gnu/libnettle.so.4 +usr/lib/x86_64-linux-gnu/libnettle.so.4.7 +usr/lib/x86_64-linux-gnu/libossp-uuid.so.16 +usr/lib/x86_64-linux-gnu/libossp-uuid.so.16.0.22 +usr/lib/x86_64-linux-gnu/libp11-kit.so.0 +usr/lib/x86_64-linux-gnu/libp11-kit.so.0.0.0 +usr/lib/x86_64-linux-gnu/librtmp.so.1 +usr/lib/x86_64-linux-gnu/libsasl2.so.2 +usr/lib/x86_64-linux-gnu/libsasl2.so.2.0.25 +usr/lib/x86_64-linux-gnu/libssh2.so.1 +usr/lib/x86_64-linux-gnu/libssh2.so.1.0.1 +usr/lib/x86_64-linux-gnu/libssl.so.1.0.0 +usr/lib/x86_64-linux-gnu/libstdc++.so.6 +usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.20 +usr/lib/x86_64-linux-gnu/libtasn1.so.6 +usr/lib/x86_64-linux-gnu/libtasn1.so.6.3.2 +usr/lib/x86_64-linux-gnu/libtiff.so.5 +usr/lib/x86_64-linux-gnu/libtiff.so.5.2.0 +usr/lib/x86_64-linux-gnu/libvpx.so.1 +usr/lib/x86_64-linux-gnu/libvpx.so.1.3.0 +usr/lib/x86_64-linux-gnu/libxcb.so.1 +usr/lib/x86_64-linux-gnu/libxcb.so.1.1.0 +usr/lib/x86_64-linux-gnu/libxml2.so.2 +usr/lib/x86_64-linux-gnu/libxml2.so.2.9.1 +usr/lib/x86_64-linux-gnu/libxslt.so.1 +usr/lib/x86_64-linux-gnu/libxslt.so.1.1.28 +usr/sbin/mysqld +usr/sbin/nginx +usr/sbin/php-fpm7.0 +usr/share/locale/locale.alias +usr/share/mysql/charsets/Index.xml +usr/share/mysql/english/errmsg.sys +usr/share/mysql/fill_help_tables.sql +usr/share/mysql/mysql_system_tables.sql +usr/share/mysql/mysql_system_tables_data.sql diff --git a/.sandstorm/sandstorm-pkgdef.capnp b/.sandstorm/sandstorm-pkgdef.capnp new file mode 100644 index 0000000000..c0493e5fb6 --- /dev/null +++ b/.sandstorm/sandstorm-pkgdef.capnp @@ -0,0 +1,188 @@ +@0x9411e6c8b3c8a4b6; + +using Spk = import "/sandstorm/package.capnp"; +# This imports: +# $SANDSTORM_HOME/latest/usr/include/sandstorm/package.capnp +# Check out that file to see the full, documented package definition format. + +const pkgdef :Spk.PackageDefinition = ( + # The package definition. Note that the spk tool looks specifically for the + # "pkgdef" constant. + + id = "uws252ya9mep4t77tevn85333xzsgrpgth8q4y1rhknn1hammw70", + # Your app ID is actually its public key. The private key was placed in + # your keyring. All updates must be signed with the same key. + + manifest = ( + appTitle = (defaultText = "Firefly III"), + appVersion = 1, + appMarketingVersion = (defaultText = "3.4.3"), + actions = [ + # Define your "new document" handlers here. + ( nounPhrase = (defaultText = "administration"), + command = .myCommand + # The command to run when starting for the first time. (".myCommand" + # is just a constant defined at the bottom of the file.) + ) + ], + + continueCommand = .myCommand, + # This is the command called to start your app back up after it has been + # shut down for inactivity. Here we're using the same command as for + # starting a new instance, but you could use different commands for each + # case. + + metadata = ( + icons = ( + appGrid = (png = (dpi1x = embed "app-graphics/firefly-iii-128.png")), + grain = (png = (dpi1x = embed "app-graphics/firefly-iii-24.png", + dpi2x = embed "app-graphics/firefly-iii-48.png")), + market = (png = (dpi1x = embed "app-graphics/firefly-iii-150.png")) + ), + + website = "https://firefly-iii.github.io/", + codeUrl = "https://github.com/firefly-iii/firefly-iii", + #license = (openSource = mit), + license = (proprietary = (defaultText = embed "../LICENSE")), + # The license this package is distributed under. See + # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#license + + categories = [productivity], + # A list of categories/genres to which this app belongs, sorted with best fit first. + # See the list of categories at + # https://docs.sandstorm.io/en/latest/developing/publishing-apps/#categories + + author = ( + contactEmail = "thegrumpydictator@gmail.com", + upstreamAuthor = "James Cole", + pgpSignature = embed "pgp-signature", + ), + + pgpKeyring = embed "pgp-keyring", + description = (defaultText = embed "description.md"), + shortDescription = (defaultText = "Financial management"), + screenshots = [ + # Screenshots to use for marketing purposes. Examples below. + # Sizes are given in device-independent pixels, so if you took these + # screenshots on a Retina-style high DPI screen, divide each dimension by two. + + (width = 1200, height = 1000, png = embed "screenshots/screenshot-1.png"), + (width = 1200, height = 1000, png = embed "screenshots/screenshot-2.png"), + (width = 1200, height = 1518, png = embed "screenshots/screenshot-3.png"), + + ], + changeLog = (defaultText = embed "changelog.md"), + ), + ), + + sourceMap = ( + # Here we defined where to look for files to copy into your package. The + # `spk dev` command actually figures out what files your app needs + # automatically by running it on a FUSE filesystem. So, the mappings + # here are only to tell it where to find files that the app wants. + searchPath = [ + ( sourcePath = "." ), # Search this directory first. + ( sourcePath = "/", # Then search the system root directory. + hidePaths = [ "home", "proc", "sys", + "etc/passwd", "etc/hosts", "etc/host.conf", + "etc/nsswitch.conf", "etc/resolv.conf" ] + # You probably don't want the app pulling files from these places, + # so we hide them. Note that /dev, /var, and /tmp are implicitly + # hidden because Sandstorm itself provides them. + ) + ] + ), + + fileList = "sandstorm-files.list", + # `spk dev` will write a list of all the files your app uses to this file. + # You should review it later, before shipping your app. + + alwaysInclude = [], + # Fill this list with more names of files or directories that should be + # included in your package, even if not listed in sandstorm-files.list. + # Use this to force-include stuff that you know you need but which may + # not have been detected as a dependency during `spk dev`. If you list + # a directory here, its entire contents will be included recursively. + + #bridgeConfig = ( + # # Used for integrating permissions and roles into the Sandstorm shell + # # and for sandstorm-http-bridge to pass to your app. + # # Uncomment this block and adjust the permissions and roles to make + # # sense for your app. + # # For more information, see high-level documentation at + # # https://docs.sandstorm.io/en/latest/developing/auth/ + # # and advanced details in the "BridgeConfig" section of + # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/package.capnp + # viewInfo = ( + # # For details on the viewInfo field, consult "ViewInfo" in + # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp + # + # permissions = [ + # # Permissions which a user may or may not possess. A user's current + # # permissions are passed to the app as a comma-separated list of `name` + # # fields in the X-Sandstorm-Permissions header with each request. + # # + # # IMPORTANT: only ever append to this list! Reordering or removing fields + # # will change behavior and permissions for existing grains! To deprecate a + # # permission, or for more information, see "PermissionDef" in + # # https://github.com/sandstorm-io/sandstorm/blob/master/src/sandstorm/grain.capnp + # ( + # name = "editor", + # # Name of the permission, used as an identifier for the permission in cases where string + # # names are preferred. Used in sandstorm-http-bridge's X-Sandstorm-Permissions HTTP header. + # + # title = (defaultText = "editor"), + # # Display name of the permission, e.g. to display in a checklist of permissions + # # that may be assigned when sharing. + # + # description = (defaultText = "grants ability to modify data"), + # # Prose describing what this role means, suitable for a tool tip or similar help text. + # ), + # ], + # roles = [ + # # Roles are logical collections of permissions. For instance, your app may have + # # a "viewer" role and an "editor" role + # ( + # title = (defaultText = "editor"), + # # Name of the role. Shown in the Sandstorm UI to indicate which users have which roles. + # + # permissions = [true], + # # An array indicating which permissions this role carries. + # # It should be the same length as the permissions array in + # # viewInfo, and the order of the lists must match. + # + # verbPhrase = (defaultText = "can make changes to the document"), + # # Brief explanatory text to show in the sharing UI indicating + # # what a user assigned this role will be able to do with the grain. + # + # description = (defaultText = "editors may view all site data and change settings."), + # # Prose describing what this role means, suitable for a tool tip or similar help text. + # ), + # ( + # title = (defaultText = "viewer"), + # permissions = [false], + # verbPhrase = (defaultText = "can view the document"), + # description = (defaultText = "viewers may view what other users have written."), + # ), + # ], + # ), + # #apiPath = "/api", + # # Apps can export an API to the world. The API is to be used primarily by Javascript + # # code and native apps, so it can't serve out regular HTML to browsers. If a request + # # comes in to your app's API, sandstorm-http-bridge will prefix the request's path with + # # this string, if specified. + #), +); + +const myCommand :Spk.Manifest.Command = ( + # Here we define the command used to start up your server. + argv = ["/sandstorm-http-bridge", "8000", "--", "/opt/app/.sandstorm/launcher.sh"], + environ = [ + # Note that this defines the *entire* environment seen by your app. + (key = "PATH", value = "/usr/local/bin:/usr/bin:/bin"), + (key = "SANDSTORM", value = "1"), + # Export SANDSTORM=1 into the environment, so that apps running within Sandstorm + # can detect if $SANDSTORM="1" at runtime, switching UI and/or backend to use + # the app's Sandstorm-specific integration code. + ] +); diff --git a/.sandstorm/screenshots/screenshot-1.png b/.sandstorm/screenshots/screenshot-1.png new file mode 100644 index 0000000000..f72ceb48e7 Binary files /dev/null and b/.sandstorm/screenshots/screenshot-1.png differ diff --git a/.sandstorm/screenshots/screenshot-2.png b/.sandstorm/screenshots/screenshot-2.png new file mode 100644 index 0000000000..9301851850 Binary files /dev/null and b/.sandstorm/screenshots/screenshot-2.png differ diff --git a/.sandstorm/screenshots/screenshot-3.png b/.sandstorm/screenshots/screenshot-3.png new file mode 100644 index 0000000000..20fcab548f Binary files /dev/null and b/.sandstorm/screenshots/screenshot-3.png differ diff --git a/.sandstorm/service-config/mime.types b/.sandstorm/service-config/mime.types new file mode 100644 index 0000000000..89be9a4cd6 --- /dev/null +++ b/.sandstorm/service-config/mime.types @@ -0,0 +1,89 @@ + +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/png png; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + image/svg+xml svg svgz; + image/webp webp; + + application/font-woff woff; + application/java-archive jar war ear; + application/json json; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.apple.mpegurl m3u8; + application/vnd.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.wap.wmlc wmlc; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xspf+xml xspf; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + application/vnd.openxmlformats-officedocument.wordprocessingml.document docx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx; + application/vnd.openxmlformats-officedocument.presentationml.presentation pptx; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp2t ts; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} diff --git a/.sandstorm/service-config/nginx.conf b/.sandstorm/service-config/nginx.conf new file mode 100644 index 0000000000..b63ddaae07 --- /dev/null +++ b/.sandstorm/service-config/nginx.conf @@ -0,0 +1,87 @@ +worker_processes 4; +pid /var/run/nginx.pid; + +events { + worker_connections 768; + # multi_accept on; +} + +http { + # Basic Settings + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + # server_names_hash_bucket_size 64; + server_tokens off; + server_name_in_redirect off; + + include mime.types; + default_type application/octet-stream; + + # Logging + access_log off; + error_log stderr; + + # Prevent nginx from adding compression; this interacts badly with Sandstorm + # WebSession due to https://github.com/sandstorm-io/sandstorm/issues/289 + gzip off; + + # Trust the sandstorm-http-bridge's X-Forwarded-Proto. + map $http_x_forwarded_proto $fe_https { + default ""; + https on; + } + + server { + listen 8000 default_server; + listen [::]:8000 default_server ipv6only=on; + + # Allow arbitrarily large bodies - Sandstorm can handle them, and requests + # are authenticated already, so there's no reason for apps to add additional + # limits by default. + client_max_body_size 0; + + server_name localhost; + root /opt/app/public; + location / { + index index.php; + try_files $uri $uri/ /index.php?$query_string; + autoindex on; + sendfile off; + } + location ~ \.php$ { + try_files $uri =404; + fastcgi_pass unix:/var/run/php7.0-fpm.sock; + fastcgi_index index.php; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + + + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + + fastcgi_param SCRIPT_NAME $fastcgi_script_name; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param DOCUMENT_URI $document_uri; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SERVER_PROTOCOL $server_protocol; + fastcgi_param HTTPS $fe_https if_not_empty; + + fastcgi_param GATEWAY_INTERFACE CGI/1.1; + fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + + fastcgi_param REMOTE_ADDR $remote_addr; + fastcgi_param REMOTE_PORT $remote_port; + fastcgi_param SERVER_ADDR $server_addr; + fastcgi_param SERVER_PORT $server_port; + fastcgi_param SERVER_NAME $server_name; + + # PHP only, required if PHP was built with --enable-force-cgi-redirect + #fastcgi_param REDIRECT_STATUS 200; + } + } +} diff --git a/.sandstorm/setup.sh b/.sandstorm/setup.sh new file mode 100755 index 0000000000..9af16630f0 --- /dev/null +++ b/.sandstorm/setup.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +# When you change this file, you must take manual action. Read this doc: +# - https://docs.sandstorm.io/en/latest/vagrant-spk/customizing/#setupsh + +set -euo pipefail + +export DEBIAN_FRONTEND=noninteractive + +# install packages so we can install apt-add-repository. +apt-get update +apt-get install -y python-software-properties software-properties-common + +# actually add repository +apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E9C74FEEA2098A6E +add-apt-repository "deb http://packages.dotdeb.org jessie all" + +# install packages. +apt-get update +apt-get install -y nginx php7.0-fpm php7.0-mysql php7.0-cli php7.0-curl git php7.0-dev php7.0-intl php7.0-dom php7.0-mbstring php7.0-bcmath mysql-server +service nginx stop +service php7.0-fpm stop +service mysql stop +systemctl disable nginx +systemctl disable php7.0-fpm +systemctl disable mysql +# patch /etc/php/7.0/fpm/pool.d/www.conf to not change uid/gid to www-data +sed --in-place='' \ + --expression='s/^listen.owner = www-data/;listen.owner = www-data/' \ + --expression='s/^listen.group = www-data/;listen.group = www-data/' \ + /etc/php/7.0/fpm/pool.d/www.conf +# patch /etc/php/7.0/fpm/php-fpm.conf to not have a pidfile +sed --in-place='' \ + --expression='s/^pid =/;pid =/' \ + /etc/php/7.0/fpm/php-fpm.conf + +# move sock file to better dir: +sed --in-place='' \ + --expression='s/^listen = \/run\/php\/php7.0-fpm.sock/listen = \/var\/run\/php7.0-fpm.sock/' \ + /etc/php/7.0/fpm/pool.d/www.conf + +# patch /etc/php/7.0/fpm/pool.d/www.conf to no clear environment variables +# so we can pass in SANDSTORM=1 to apps +sed --in-place='' \ + --expression='s/^;clear_env = no/clear_env=no/' \ + /etc/php/7.0/fpm/pool.d/www.conf +# patch mysql conf to not change uid, and to use /var/tmp over /tmp +# for secure-file-priv see https://github.com/sandstorm-io/vagrant-spk/issues/195 +sed --in-place='' \ + --expression='s/^user\t\t= mysql/#user\t\t= mysql/' \ + --expression='s,^tmpdir\t\t= /tmp,tmpdir\t\t= /var/tmp,' \ + --expression='/\[mysqld]/ a\ secure-file-priv = ""\' \ + /etc/mysql/my.cnf +# patch mysql conf to use smaller transaction logs to save disk space +cat < /etc/mysql/conf.d/sandstorm.cnf +[mysqld] +# Set the transaction log file to the minimum allowed size to save disk space. +# innodb_log_file_size = 1048576 +# Set the main data file to grow by 1MB at a time, rather than 8MB at a time. +innodb_autoextend_increment = 1 +EOF diff --git a/.sandstorm/stack b/.sandstorm/stack new file mode 100644 index 0000000000..79a9408192 --- /dev/null +++ b/.sandstorm/stack @@ -0,0 +1 @@ +lemp diff --git a/CHANGELOG.md b/CHANGELOG.md index 91120fe9b2..e926fc7b54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,42 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [4.3.5] - 2017-02-19 +### Added +- Beta support for Sandstorm.IO +- Docker support by [@schoentoon](https://github.com/schoentoon), [@elohmeier](https://github.com/elohmeier), [@patrickkostjens](https://github.com/patrickkostjens) and [@crash7](https://github.com/crash7)! +- Can now use special keywords in the search to search for specic dates, categories, etc. + +### Changed +- Updated to laravel 5.4! +- User friendly error message +- Updated locales to support more operating systems, first reported in #536 by [dabenzel](https://github.com/dabenzel) +- Updated budget report +- Improved 404 page +- Smooth curves, improved by [elamperti](https://github.com/elamperti). -## [4.3.3] - 2017-02-02 ### Fixed -- Fixed bug #550, reported by @worldworm! -- Fixed bug #551, reported by @t-me! +- #549 +- #553 +- Fixed #559 reported by [elamperti](https://github.com/elamperti). +- #565, as reported by a user over the mail +- #566, as reported by [dspeckmann](https://github.com/dspeckmann) +- #567, as reported by [winsomniak](https://github.com/winsomniak) +- #569, as reported by [winsomniak](https://github.com/winsomniak) +- #572, as reported by [zjean](https://github.com/zjean) +- Many issues with the transaction filters which will fix reports (they tended to display the wrong amount). + +## [4.3.4] - 2017-02-02 +### Fixed +- Fixed bug #550, reported by [worldworm](https://github.com/worldworm)! +- Fixed bug #551, reported by [t-me](https://github.com/t-me)! ## [4.3.3] - 2017-01-30 _The 100th release of Firefly!_ ### Added -- Add locales to Docker (#534) by @elohmeier. +- Add locales to Docker (#534) by [elohmeier](https://github.com/elohmeier). - Optional database encryption. On by default. - Datepicker for Firefox and other browsers. - New instruction block for updating and installing. @@ -44,35 +68,35 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - The password reset routine was broken. -- Issue #522, thanks to @xpfgsyb -- Issue #524, thanks to @worldworm -- Issue #526, thanks to @worldworm -- Issue #528, thanks to @skibbipl +- Issue #522, thanks to [xpfgsyb](https://github.com/xpfgsyb) +- Issue #524, thanks to [worldworm](https://github.com/worldworm) +- Issue #526, thanks to [worldworm](https://github.com/worldworm) +- Issue #528, thanks to [skibbipl](https://github.com/skibbipl) - Various other fixes. ## [4.3.1] - 2017-01-04 ### Added - Support for Russian and Polish. - Support for a proper demo website. -- Support for custom decimal places in currencies (#506, suggested by @xpfgsyb). -- Most amounts are now right-aligned (#511, suggested by @xpfgsyb). +- Support for custom decimal places in currencies (#506, suggested by [xpfgsyb](https://github.com/xpfgsyb)). +- Most amounts are now right-aligned (#511, suggested by [xpfgsyb](https://github.com/xpfgsyb)). - German is now a "complete" language, more than 75% translated! ### Changed - **[New Github repository!](github.com/firefly-iii/firefly-iii)** - Better category overview. -- #502, thanks to @zjean +- #502, thanks to [zjean](https://github.com/zjean) ### Removed - Removed a lot of administration functions. - Removed ability to activate users. ### Fixed -- #501, thanks to @zjean -- #513, thanks to @skibbipl +- #501, thanks to [zjean](https://github.com/zjean) +- #513, thanks to [skibbipl](https://github.com/skibbipl) ### Security -- #519, thanks to @xpfgsyb +- #519, thanks to [xpfgsyb](https://github.com/xpfgsyb) ## [4.3.0] - 2015-12-26 ### Added @@ -105,7 +129,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Various bugs -- Issue #472 thanks to @zjean +- Issue #472 thanks to [zjean](https://github.com/zjean) ## [4.2.1] - 2016-12-09 ### Added @@ -140,10 +164,10 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Issue #408 - Various issues with split journals -- Issue #414, thx @zjean -- Issue #419, thx @schwalberich -- Issue #422, thx @xzaz -- Various import bugs, such as #416 (@zjean) +- Issue #414, thx [zjean](https://github.com/zjean) +- Issue #419, thx [schwalberich](https://github.com/schwalberich) +- Issue #422, thx [xzaz](https://github.com/xzaz) +- Various import bugs, such as #416 ([zjean](https://github.com/zjean)) ### Security @@ -165,9 +189,9 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Made all pages more mobile friendly. -- Fixed #395 found by @marcoveeneman. -- Fixed #398 found by @marcoveeneman. -- Fixed #401 found by @marcoveeneman. +- Fixed #395 found by [marcoveeneman](https://github.com/marcoveeneman). +- Fixed #398 found by [marcoveeneman](https://github.com/marcoveeneman). +- Fixed #401 found by [marcoveeneman](https://github.com/marcoveeneman). - Many optimizations. - Updated many libraries. - Various bugs found by myself. @@ -179,13 +203,13 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Changed - Greatly expanded help pages and their function. -- Built a new transaction collector, which I think was the idea of @roberthorlings originally. +- Built a new transaction collector, which I think was the idea of [roberthorlings](https://github.com/roberthorlings) originally. - Rebuilt seach engine. ### Fixed -- #375, thanks to @schoentoon which made it impossible to resurrect currencies. -- #370 thanks to @ksmolder -- #378, thanks to @HomelessAvatar +- #375, thanks to [schoentoon](https://github.com/schoentoon) which made it impossible to resurrect currencies. +- #370 thanks to [ksmolder](https://github.com/ksmolder) +- #378, thanks to [HomelessAvatar](https://github.com/HomelessAvatar) ## [4.1.5] - 2016-11-01 ### Changed @@ -198,7 +222,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i ## [4.1.4] - 2016-10-30 ### Added -- New Dockerfile thanks to @schoentoon +- New Dockerfile thanks to [schoentoon](https://github.com/schoentoon) - Added changing the destination account as rule action. - Added changing the source account as rule action. - Can convert transactions into different types. @@ -211,10 +235,10 @@ An intermediate release because something in the Twig and Twigbridge libraries i - Change error message to refer to solution. ### Fixed -- #367 thanks to @HungryFeline -- #366 thanks to @3mz3t -- #362 and #341 thanks to @bnw -- #355 thanks to @roberthorlings +- #367 thanks to [HungryFeline](https://github.com/HungryFeline) +- #366 thanks to [3mz3t](https://github.com/3mz3t) +- #362 and #341 thanks to [bnw](https://github.com/bnw) +- #355 thanks to [roberthorlings](https://github.com/roberthorlings) ## [4.1.3] - 2016-10-22 ### Fixed @@ -246,29 +270,29 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - #357, where non utf-8 files would break Firefly. -- Tab delimiter is not properly loaded from import configuration (@roberthorlings) +- Tab delimiter is not properly loaded from import configuration ([roberthorlings](https://github.com/roberthorlings)) - System response to yearly bills ## [4.0.2] - 2016-10-14 ### Added -- Added ``intl`` dependency to composer file to ease installation (thanks @telyn) +- Added ``intl`` dependency to composer file to ease installation (thanks [telyn](https://github.com/telyn)) - Added support for Croatian. ### Changed - Updated all copyright notices to refer to the [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/) - Fixed #344 -- Fixed #346, thanks to @SanderKleykens +- Fixed #346, thanks to [SanderKleykens](https://github.com/SanderKleykens) - #351 - Did some internal remodelling. ### Fixed -- PostgreSQL compatibility thanks to @SanderKleykens -- @RobertHorlings fixed a bug in the ABN Amro import specific. +- PostgreSQL compatibility thanks to [SanderKleykens](https://github.com/SanderKleykens) +- [roberthorlings](https://github.com/roberthorlings) fixed a bug in the ABN Amro import specific. ## [4.0.1] - 2016-10-04 ### Added -- New ING import specific by @tomwerf +- New ING import specific by [tomwerf](https://github.com/tomwerf) - New Presidents Choice specific to fix #307 - Added some trimming (#335) @@ -283,10 +307,10 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Fixed a bug where incoming transactions would not be properly filtered in several reports. -- #334 by @cyberkov +- #334 by [cyberkov](https://github.com/cyberkov) - #337 - #336 -- #338 found by @roberthorlings +- #338 found by [roberthorlings](https://github.com/roberthorlings) ### Security - Initial release. @@ -297,29 +321,29 @@ An intermediate release because something in the Twig and Twigbridge libraries i ## [4.0.0] - 2015-09-26 ### Added - Upgraded to Laravel 5.3, most other libraries upgraded as well. -- Added GBP as currency, thanks to @Mortalife +- Added GBP as currency, thanks to [Mortalife](https://github.com/Mortalife) ### Changed - Jump to version 4.0.0. - Firefly III is now subject to a [Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/) license. Previous versions of this software are still MIT licensed. ### Fixed -- Support for specific decimal places, thanks to @Mortalife +- Support for specific decimal places, thanks to [Mortalife](https://github.com/Mortalife) - Various CSS fixes -- Various bugs, thanks to @fuf, @sandermulders and @vissert +- Various bugs, thanks to [fuf](https://github.com/fuf), [sandermulders](https://github.com/sandermulders) and [vissert](https://github.com/vissert) - Various queries optimized for MySQL 5.7 ## [3.10.4] - 2015-09-14 ### Fixed -- Migration fix by @sandermulders -- Tricky import bug fix thanks to @vissert -- Currency preference will be correctly pulled from user settings, thanks to @fuf +- Migration fix by [sandermulders](https://github.com/sandermulders) +- Tricky import bug fix thanks to [vissert](https://github.com/vissert) +- Currency preference will be correctly pulled from user settings, thanks to [fuf](https://github.com/fuf) - Simplified code for upgrade instructions. ## [3.10.3] - 2016-08-29 ### Added -- More fields for mass-edit, thanks to @Vissert (#282) +- More fields for mass-edit, thanks to [vissert](https://github.com/vissert) (#282) - First start of German translation ### Changed @@ -330,7 +354,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - A bug in the translation routine broke the import. -- It was possible to destroy your Firefly installation by removing all currencies. Thanks @mondjef +- It was possible to destroy your Firefly installation by removing all currencies. Thanks [mondjef](https://github.com/mondjef) - Translation bugs. - Import bug. @@ -350,8 +374,8 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Bug in the mass edit routines. -- Firefly III over a proxy will now work (see [issue #290](https://github.com/firefly-iii/firefly-iii/issues/290)), thanks @dfiel for reporting. -- Sneaky bug in the import routine, fixed by @Bonno +- Firefly III over a proxy will now work (see [issue #290](https://github.com/firefly-iii/firefly-iii/issues/290)), thanks [dfiel](https://github.com/dfiel) for reporting. +- Sneaky bug in the import routine, fixed by [Bonno](https://github.com/Bonno) ## [3.10.1] - 2016-08-25 ### Added @@ -389,15 +413,15 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Issue #264 - Issue #265 -- Fixed amount calculation problems, #266, thanks @xzaz +- Fixed amount calculation problems, #266, thanks [xzaz](https://github.com/xzaz) - Issue #271 -- Issue #278, #273, thanks @StevenReitsma and @rubella +- Issue #278, #273, thanks [StevenReitsma](https://github.com/StevenReitsma) and [rubella](https://github.com/rubella) - Bug in attachment download routine would report the wrong size to the user's browser. - Various NULL errors fixed. - Various strict typing errors fixed. -- Fixed pagination problems, #276, thanks @xzaz +- Fixed pagination problems, #276, thanks [xzaz](https://github.com/xzaz) - Fixed a bug where an expense would be assigned to a piggy bank if you created a transfer first. -- Bulk update problems, #280, thanks @stickgrinder +- Bulk update problems, #280, thanks [stickgrinder](https://github.com/stickgrinder) - Fixed various problems with amount reporting of split transactions. ## [3.9.1] @@ -406,8 +430,8 @@ An intermediate release because something in the Twig and Twigbridge libraries i ## [3.9.0] ### Added -- @zjean has added code that allows you to force "https://"-URL's. -- @tonicospinelli has added Portuguese (Brazil) translations. +- [zjean](https://github.com/zjean) has added code that allows you to force "https://"-URL's. +- [tonicospinelli](https://github.com/tonicospinelli) has added Portuguese (Brazil) translations. - Firefly III supports the *splitting* of transactions: - A withdrawal (expense) can be split into multiple sub-transactions (with multiple destinations) - Likewise for deposits (incomes). You can set multiple sources. @@ -438,7 +462,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Fixed - Several CSV related bugs. - Several other bugs. -- Bugs fixed by @Bonno. +- Bugs fixed by [Bonno](https://github.com/Bonno). ## [3.8.3] - 2016-04-17 ### Added @@ -485,7 +509,7 @@ An intermediate release because something in the Twig and Twigbridge libraries i ### Added - Two factor authentication, thanks to the excellent work of [zjean](https://github.com/zjean). - A new chart showing your net worth in year and multi-year reports. -- You can now see if your current or future rules actually match any transactions, thanks to the excellent work of @roberthorlings. +- You can now see if your current or future rules actually match any transactions, thanks to the excellent work of [roberthorlings](https://github.com/roberthorlings). - New date fields for transactions. They are not used yet in reports or anything, but they can be filled in. - New routine to export your data. - Firefly III will mail the site owner when blocked users try to login, or when blocked domains are used in registrations. diff --git a/Dockerfile b/Dockerfile index 2311881871..7d00a3724b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN apt-get update -y && \ libxml2-dev \ libsqlite3-dev \ libbz2-dev \ + gettext-base \ locales && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* @@ -44,3 +45,5 @@ WORKDIR /var/www/firefly-iii RUN composer install --no-scripts --no-dev USER root + +ENTRYPOINT ["/var/www/firefly-iii/docker/entrypoint.sh"] diff --git a/README.md b/README.md index 5005beca67..5013f18eab 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Firefly works on the principle that if you know where you're money is going, you - Firefly can import any CSV file, so migrating from other systems is easy. - Firefly runs on your own server, so you are fully in control of your data. Remember, there is no such thing as "the cloud", it’s just somebody else’s computer! -- Firefly has lots of features without becoming fancy or bloated. +- Firefly has lots of features without being fancy or bloated. - If you feel you're missing something you can just ask me and I'll add it! Firefly is pretty awesome. [You can read more about Firefly III, and its features, on the Github Pages](https://firefly-iii.github.io/). diff --git a/app/Console/Commands/CreateImport.php b/app/Console/Commands/CreateImport.php index 41fd83d762..d9b51a3b6d 100644 --- a/app/Console/Commands/CreateImport.php +++ b/app/Console/Commands/CreateImport.php @@ -79,8 +79,9 @@ class CreateImport extends Command $this->info(sprintf('Type of import: %s', $type)); /** @var ImportJobRepositoryInterface $jobRepository */ - $jobRepository = app(ImportJobRepositoryInterface::class, [$user]); - $job = $jobRepository->create($type); + $jobRepository = app(ImportJobRepositoryInterface::class); + $jobRepository->setUser($user); + $job = $jobRepository->create($type); $this->line(sprintf('Created job "%s"...', $job->key)); Artisan::call('firefly:encrypt', ['file' => $file, 'key' => $job->key]); diff --git a/app/Console/Commands/UpgradeFireflyInstructions.php b/app/Console/Commands/UpgradeFireflyInstructions.php index a88c8ab79c..03e7761172 100644 --- a/app/Console/Commands/UpgradeFireflyInstructions.php +++ b/app/Console/Commands/UpgradeFireflyInstructions.php @@ -84,21 +84,8 @@ class UpgradeFireflyInstructions extends Command } } - /** - * Show a line - */ - private function showLine() + private function installInstructions() { - $line = '+'; - for ($i = 0; $i < 78; $i++) { - $line .= '-'; - } - $line .= '+'; - $this->line($line); - - } - - private function installInstructions() { /** @var string $version */ $version = config('firefly.version'); $config = config('upgrade.text.install'); @@ -120,6 +107,7 @@ class UpgradeFireflyInstructions extends Command $this->boxed('Firefly III should be ready for use.'); $this->boxed(''); $this->showLine(); + return; } @@ -129,6 +117,20 @@ class UpgradeFireflyInstructions extends Command $this->showLine(); } + /** + * Show a line + */ + private function showLine() + { + $line = '+'; + for ($i = 0; $i < 78; $i++) { + $line .= '-'; + } + $line .= '+'; + $this->line($line); + + } + private function updateInstructions() { /** @var string $version */ @@ -152,6 +154,7 @@ class UpgradeFireflyInstructions extends Command $this->boxed('Firefly III should be ready for use.'); $this->boxed(''); $this->showLine(); + return; } diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 8ea0f88014..f4a1e32559 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -39,9 +39,9 @@ class Kernel extends ConsoleKernel */ protected $bootstrappers = [ - 'Illuminate\Foundation\Bootstrap\DetectEnvironment', + 'Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables', 'Illuminate\Foundation\Bootstrap\LoadConfiguration', - 'FireflyIII\Bootstrap\ConfigureLogging', + //'FireflyIII\Bootstrap\ConfigureLogging', 'Illuminate\Foundation\Bootstrap\HandleExceptions', 'Illuminate\Foundation\Bootstrap\RegisterFacades', 'Illuminate\Foundation\Bootstrap\SetRequestForConsole', diff --git a/app/Export/Collector/AttachmentCollector.php b/app/Export/Collector/AttachmentCollector.php index e068f32585..f65cb72ae3 100644 --- a/app/Export/Collector/AttachmentCollector.php +++ b/app/Export/Collector/AttachmentCollector.php @@ -16,7 +16,6 @@ namespace FireflyIII\Export\Collector; use Carbon\Carbon; use Crypt; use FireflyIII\Models\Attachment; -use FireflyIII\Models\ExportJob; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Support\Collection; @@ -43,10 +42,8 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface /** * AttachmentCollector constructor. - * - * @param ExportJob $job */ - public function __construct(ExportJob $job) + public function __construct() { /** @var AttachmentRepositoryInterface repository */ $this->repository = app(AttachmentRepositoryInterface::class); @@ -54,7 +51,7 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface $this->uploadDisk = Storage::disk('upload'); $this->exportDisk = Storage::disk('export'); - parent::__construct($job); + parent::__construct(); } /** diff --git a/app/Export/Collector/BasicCollector.php b/app/Export/Collector/BasicCollector.php index 4fd571c84d..c80e8ec280 100644 --- a/app/Export/Collector/BasicCollector.php +++ b/app/Export/Collector/BasicCollector.php @@ -31,13 +31,10 @@ class BasicCollector /** * BasicCollector constructor. - * - * @param ExportJob $job */ - public function __construct(ExportJob $job) + public function __construct() { $this->entries = new Collection; - $this->job = $job; } /** @@ -56,5 +53,13 @@ class BasicCollector $this->entries = $entries; } + /** + * @param ExportJob $job + */ + public function setJob(ExportJob $job) + { + $this->job = $job; + } + } diff --git a/app/Export/Collector/CollectorInterface.php b/app/Export/Collector/CollectorInterface.php index f1778e9adc..6cbbac9c2a 100644 --- a/app/Export/Collector/CollectorInterface.php +++ b/app/Export/Collector/CollectorInterface.php @@ -13,6 +13,7 @@ declare(strict_types = 1); namespace FireflyIII\Export\Collector; +use FireflyIII\Models\ExportJob; use Illuminate\Support\Collection; /** @@ -40,4 +41,11 @@ interface CollectorInterface */ public function setEntries(Collection $entries); + /** + * @param ExportJob $job + * + * @return mixed + */ + public function setJob(ExportJob $job); + } diff --git a/app/Export/Collector/JournalExportCollector.php b/app/Export/Collector/JournalExportCollector.php index e9bfbca879..551880ce4f 100644 --- a/app/Export/Collector/JournalExportCollector.php +++ b/app/Export/Collector/JournalExportCollector.php @@ -19,6 +19,7 @@ use DB; use FireflyIII\Models\Transaction; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; +use Steam; /** * Class JournalExportCollector @@ -118,7 +119,7 @@ class JournalExportCollector extends BasicCollector implements CollectorInterfac ); $set->each( function ($obj) { - $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; + $obj->name = Steam::decrypt(intval($obj->encrypted), $obj->name); } ); $array = []; @@ -159,7 +160,7 @@ class JournalExportCollector extends BasicCollector implements CollectorInterfac ); $set->each( function ($obj) { - $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; + $obj->name = Steam::decrypt(intval($obj->encrypted), $obj->name); } ); $array = []; @@ -202,7 +203,7 @@ class JournalExportCollector extends BasicCollector implements CollectorInterfac ); $set->each( function ($obj) { - $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; + $obj->name = Steam::decrypt(intval($obj->encrypted), $obj->name); } ); $array = []; @@ -243,7 +244,7 @@ class JournalExportCollector extends BasicCollector implements CollectorInterfac ); $set->each( function ($obj) { - $obj->name = $obj->encrypted === 1 ? Crypt::decrypt($obj->name) : $obj->name; + $obj->name = Steam::decrypt(intval($obj->encrypted), $obj->name); } ); $array = []; diff --git a/app/Export/Collector/UploadCollector.php b/app/Export/Collector/UploadCollector.php index 1895cb8a5e..35c2e75188 100644 --- a/app/Export/Collector/UploadCollector.php +++ b/app/Export/Collector/UploadCollector.php @@ -14,7 +14,6 @@ declare(strict_types = 1); namespace FireflyIII\Export\Collector; use Crypt; -use FireflyIII\Models\ExportJob; use Illuminate\Contracts\Encryption\DecryptException; use Log; use Storage; @@ -35,22 +34,12 @@ class UploadCollector extends BasicCollector implements CollectorInterface /** * AttachmentCollector constructor. - * - * @param ExportJob $job */ - public function __construct(ExportJob $job) + public function __construct() { - parent::__construct($job); - - Log::debug('Going to collect attachments', ['key' => $job->key]); - - // make storage: + parent::__construct(); $this->uploadDisk = Storage::disk('upload'); $this->exportDisk = Storage::disk('export'); - - // file names associated with the old import routine. - $this->vintageFormat = sprintf('csv-upload-%d-', auth()->user()->id); - } /** @@ -60,6 +49,11 @@ class UploadCollector extends BasicCollector implements CollectorInterface */ public function run(): bool { + Log::debug('Going to collect attachments', ['key' => $this->job->key]); + + // file names associated with the old import routine. + $this->vintageFormat = sprintf('csv-upload-%d-', $this->job->user->id); + // collect old upload files (names beginning with "csv-upload". $this->collectVintageUploads(); diff --git a/app/Export/Entry/Entry.php b/app/Export/Entry/Entry.php index 0afc40ada4..2fb30850d0 100644 --- a/app/Export/Entry/Entry.php +++ b/app/Export/Entry/Entry.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Export\Entry; use Crypt; +use Steam; /** * To extend the exported object, in case of new features in Firefly III for example, @@ -73,15 +74,15 @@ final class Entry { $entry = new self; $entry->journal_id = $object->transaction_journal_id; - $entry->description = self::decrypt(intval($object->journal_encrypted), $object->journal_description); + $entry->description = Steam::decrypt(intval($object->journal_encrypted), $object->journal_description); $entry->amount = $object->amount; $entry->date = $object->date; $entry->transaction_type = $object->transaction_type; $entry->currency_code = $object->transaction_currency_code; $entry->source_account_id = $object->account_id; - $entry->source_account_name = self::decrypt(intval($object->account_name_encrypted), $object->account_name); + $entry->source_account_name = Steam::decrypt(intval($object->account_name_encrypted), $object->account_name); $entry->destination_account_id = $object->opposing_account_id; - $entry->destination_account_name = self::decrypt(intval($object->opposing_account_encrypted), $object->opposing_account_name); + $entry->destination_account_name = Steam::decrypt(intval($object->opposing_account_encrypted), $object->opposing_account_name); $entry->category_id = $object->category_id ?? ''; $entry->category_name = $object->category_name ?? ''; $entry->budget_id = $object->budget_id ?? ''; @@ -95,19 +96,5 @@ final class Entry return $entry; } - /** - * @param int $isEncrypted - * @param $value - * - * @return string - */ - protected static function decrypt(int $isEncrypted, $value) - { - if ($isEncrypted === 1) { - return Crypt::decrypt($value); - } - - return $value; - } } diff --git a/app/Export/Exporter/BasicExporter.php b/app/Export/Exporter/BasicExporter.php index b16b19776a..256fa3b544 100644 --- a/app/Export/Exporter/BasicExporter.php +++ b/app/Export/Exporter/BasicExporter.php @@ -26,17 +26,15 @@ class BasicExporter { /** @var ExportJob */ protected $job; - private $entries; + /** @var Collection */ + private $entries; /** * BasicExporter constructor. - * - * @param ExportJob $job */ - public function __construct(ExportJob $job) + public function __construct() { $this->entries = new Collection; - $this->job = $job; } /** @@ -55,5 +53,13 @@ class BasicExporter $this->entries = $entries; } + /** + * @param ExportJob $job + */ + public function setJob(ExportJob $job) + { + $this->job = $job; + } + } diff --git a/app/Export/Exporter/CsvExporter.php b/app/Export/Exporter/CsvExporter.php index b1f12f4e30..200bf8116d 100644 --- a/app/Export/Exporter/CsvExporter.php +++ b/app/Export/Exporter/CsvExporter.php @@ -14,7 +14,6 @@ declare(strict_types = 1); namespace FireflyIII\Export\Exporter; use FireflyIII\Export\Entry\Entry; -use FireflyIII\Models\ExportJob; use League\Csv\Writer; use SplFileObject; @@ -30,13 +29,10 @@ class CsvExporter extends BasicExporter implements ExporterInterface /** * CsvExporter constructor. - * - * @param ExportJob $job */ - public function __construct(ExportJob $job) + public function __construct() { - parent::__construct($job); - + parent::__construct(); } /** diff --git a/app/Export/Exporter/ExporterInterface.php b/app/Export/Exporter/ExporterInterface.php index 3559d89cec..9e267b4812 100644 --- a/app/Export/Exporter/ExporterInterface.php +++ b/app/Export/Exporter/ExporterInterface.php @@ -13,6 +13,7 @@ declare(strict_types = 1); namespace FireflyIII\Export\Exporter; +use FireflyIII\Models\ExportJob; use Illuminate\Support\Collection; /** @@ -45,4 +46,9 @@ interface ExporterInterface */ public function setEntries(Collection $entries); + /** + * @param ExportJob $job + */ + public function setJob(ExportJob $job); + } diff --git a/app/Export/Processor.php b/app/Export/Processor.php index 0d0421a460..cbbdd2736b 100644 --- a/app/Export/Processor.php +++ b/app/Export/Processor.php @@ -19,7 +19,6 @@ use FireflyIII\Export\Collector\JournalExportCollector; use FireflyIII\Export\Collector\UploadCollector; use FireflyIII\Export\Entry\Entry; use FireflyIII\Models\ExportJob; -use Illuminate\Filesystem\FilesystemAdapter; use Illuminate\Support\Collection; use Log; use Storage; @@ -54,21 +53,12 @@ class Processor implements ProcessorInterface /** * Processor constructor. - * - * @param array $settings */ - public function __construct(array $settings) + public function __construct() { - // save settings - $this->settings = $settings; - $this->accounts = $settings['accounts']; - $this->exportFormat = $settings['exportFormat']; - $this->includeAttachments = $settings['includeAttachments']; - $this->includeOldUploads = $settings['includeOldUploads']; - $this->job = $settings['job']; - $this->journals = new Collection; - $this->exportEntries = new Collection; - $this->files = new Collection; + $this->journals = new Collection; + $this->exportEntries = new Collection; + $this->files = new Collection; } @@ -78,7 +68,8 @@ class Processor implements ProcessorInterface public function collectAttachments(): bool { /** @var AttachmentCollector $attachmentCollector */ - $attachmentCollector = app(AttachmentCollector::class, [$this->job]); + $attachmentCollector = app(AttachmentCollector::class); + $attachmentCollector->setJob($this->job); $attachmentCollector->setDates($this->settings['startDate'], $this->settings['endDate']); $attachmentCollector->run(); $this->files = $this->files->merge($attachmentCollector->getEntries()); @@ -92,7 +83,8 @@ class Processor implements ProcessorInterface public function collectJournals(): bool { /** @var JournalExportCollector $collector */ - $collector = app(JournalExportCollector::class, [$this->job]); + $collector = app(JournalExportCollector::class); + $collector->setJob($this->job); $collector->setDates($this->settings['startDate'], $this->settings['endDate']); $collector->setAccounts($this->settings['accounts']); $collector->run(); @@ -108,7 +100,8 @@ class Processor implements ProcessorInterface public function collectOldUploads(): bool { /** @var UploadCollector $uploadCollector */ - $uploadCollector = app(UploadCollector::class, [$this->job]); + $uploadCollector = app(UploadCollector::class); + $uploadCollector->setJob($this->job); $uploadCollector->run(); $this->files = $this->files->merge($uploadCollector->getEntries()); @@ -166,7 +159,8 @@ class Processor implements ProcessorInterface public function exportJournals(): bool { $exporterClass = config('firefly.export_formats.' . $this->exportFormat); - $exporter = app($exporterClass, [$this->job]); + $exporter = app($exporterClass); + $exporter->setJob($this->job); $exporter->setEntries($this->exportEntries); $exporter->run(); $this->files->push($exporter->getFileName()); @@ -182,6 +176,20 @@ class Processor implements ProcessorInterface return $this->files; } + /** + * @param array $settings + */ + public function setSettings(array $settings) + { + // save settings + $this->settings = $settings; + $this->accounts = $settings['accounts']; + $this->exportFormat = $settings['exportFormat']; + $this->includeAttachments = $settings['includeAttachments']; + $this->includeOldUploads = $settings['includeOldUploads']; + $this->job = $settings['job']; + } + /** * */ diff --git a/app/Export/ProcessorInterface.php b/app/Export/ProcessorInterface.php index 614d748304..540dbcaf37 100644 --- a/app/Export/ProcessorInterface.php +++ b/app/Export/ProcessorInterface.php @@ -25,11 +25,8 @@ interface ProcessorInterface /** * Processor constructor. - * - * @param array $settings - * */ - public function __construct(array $settings); + public function __construct(); /** * @return bool @@ -65,4 +62,9 @@ interface ProcessorInterface * @return Collection */ public function getFiles(): Collection; + + /** + * @param array $settings + */ + public function setSettings(array $settings); } diff --git a/app/Generator/Chart/Basic/ChartJsGenerator.php b/app/Generator/Chart/Basic/ChartJsGenerator.php index 85cff4d4f6..b7588d2da2 100644 --- a/app/Generator/Chart/Basic/ChartJsGenerator.php +++ b/app/Generator/Chart/Basic/ChartJsGenerator.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Generator\Chart\Basic; use FireflyIII\Support\ChartColour; +use Steam; /** * Class ChartJsGenerator @@ -108,11 +109,7 @@ class ChartJsGenerator implements GeneratorInterface foreach ($data as $key => $value) { // make larger than 0 - if (bccomp($value, '0') === -1) { - $value = bcmul($value, '-1'); - } - - $chartData['datasets'][0]['data'][] = $value; + $chartData['datasets'][0]['data'][] = floatval(Steam::positive($value)); $chartData['datasets'][0]['backgroundColor'][] = ChartColour::getColour($index); $chartData['labels'][] = $key; $index++; diff --git a/app/Generator/Report/Audit/MonthReportGenerator.php b/app/Generator/Report/Audit/MonthReportGenerator.php index 9c21b1a0ba..25f255f3a7 100644 --- a/app/Generator/Report/Audit/MonthReportGenerator.php +++ b/app/Generator/Report/Audit/MonthReportGenerator.php @@ -129,6 +129,16 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface + { + return $this; + } + /** * @param Account $account * @param Carbon $date @@ -139,7 +149,7 @@ class MonthReportGenerator implements ReportGeneratorInterface { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts(new Collection([$account]))->setRange($this->start, $this->end); $journals = $collector->getJournals(); $journals = $journals->reverse(); diff --git a/app/Generator/Report/Budget/MonthReportGenerator.php b/app/Generator/Report/Budget/MonthReportGenerator.php index 38a53aad79..87557c8682 100644 --- a/app/Generator/Report/Budget/MonthReportGenerator.php +++ b/app/Generator/Report/Budget/MonthReportGenerator.php @@ -131,6 +131,16 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $this; } + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $collection * @param int $sortFlag @@ -185,7 +195,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface } /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) ->setTypes([TransactionType::WITHDRAWAL]) ->setBudgets($this->budgets)->withOpposingAccount()->disableFilter(); diff --git a/app/Generator/Report/Category/MonthReportGenerator.php b/app/Generator/Report/Category/MonthReportGenerator.php index 5517d7be13..0a3c60be3a 100644 --- a/app/Generator/Report/Category/MonthReportGenerator.php +++ b/app/Generator/Report/Category/MonthReportGenerator.php @@ -141,6 +141,16 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface return $this; } + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface + { + return $this; + } + /** * @param Collection $collection * @param int $sortFlag @@ -195,7 +205,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface } /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) ->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) ->setCategories($this->categories)->withOpposingAccount()->disableFilter(); @@ -218,7 +228,7 @@ class MonthReportGenerator extends Support implements ReportGeneratorInterface } /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($this->accounts)->setRange($this->start, $this->end) ->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) ->setCategories($this->categories)->withOpposingAccount(); diff --git a/app/Generator/Report/ReportGeneratorInterface.php b/app/Generator/Report/ReportGeneratorInterface.php index 593d318f10..12942190f4 100644 --- a/app/Generator/Report/ReportGeneratorInterface.php +++ b/app/Generator/Report/ReportGeneratorInterface.php @@ -64,4 +64,11 @@ interface ReportGeneratorInterface */ public function setStartDate(Carbon $date): ReportGeneratorInterface; + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface; + } diff --git a/app/Generator/Report/Standard/MonthReportGenerator.php b/app/Generator/Report/Standard/MonthReportGenerator.php index 113b777c91..bf4d1889ca 100644 --- a/app/Generator/Report/Standard/MonthReportGenerator.php +++ b/app/Generator/Report/Standard/MonthReportGenerator.php @@ -106,4 +106,14 @@ class MonthReportGenerator implements ReportGeneratorInterface return $this; } + + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface + { + return $this; + } } diff --git a/app/Generator/Report/Standard/MultiYearReportGenerator.php b/app/Generator/Report/Standard/MultiYearReportGenerator.php index 5dab371d6b..a5b1702a95 100644 --- a/app/Generator/Report/Standard/MultiYearReportGenerator.php +++ b/app/Generator/Report/Standard/MultiYearReportGenerator.php @@ -103,4 +103,14 @@ class MultiYearReportGenerator implements ReportGeneratorInterface return $this; } + + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface + { + return $this; + } } diff --git a/app/Generator/Report/Standard/YearReportGenerator.php b/app/Generator/Report/Standard/YearReportGenerator.php index f3297e35df..e755b45057 100644 --- a/app/Generator/Report/Standard/YearReportGenerator.php +++ b/app/Generator/Report/Standard/YearReportGenerator.php @@ -103,4 +103,14 @@ class YearReportGenerator implements ReportGeneratorInterface return $this; } + + /** + * @param Collection $tags + * + * @return ReportGeneratorInterface + */ + public function setTags(Collection $tags): ReportGeneratorInterface + { + return $this; + } } diff --git a/app/Handlers/Events/UserEventHandler.php b/app/Handlers/Events/UserEventHandler.php index 5144843bf7..836f7b11b5 100644 --- a/app/Handlers/Events/UserEventHandler.php +++ b/app/Handlers/Events/UserEventHandler.php @@ -19,7 +19,6 @@ use FireflyIII\Repositories\User\UserRepositoryInterface; use Illuminate\Mail\Message; use Log; use Mail; -use Session; use Swift_TransportException; /** @@ -54,20 +53,6 @@ class UserEventHandler return true; } - /** - * Handle user logout events. - * - * @return bool - */ - public function logoutUser(): bool - { - // dump stuff from the session: - Session::forget('twofactor-authenticated'); - Session::forget('twofactor-authenticated-date'); - - return true; - } - /** * @param RequestedNewPassword $event * diff --git a/app/Helpers/Attachments/AttachmentHelper.php b/app/Helpers/Attachments/AttachmentHelper.php index c7f7902109..74b189469b 100644 --- a/app/Helpers/Attachments/AttachmentHelper.php +++ b/app/Helpers/Attachments/AttachmentHelper.php @@ -45,7 +45,7 @@ class AttachmentHelper implements AttachmentHelperInterface public function __construct() { $this->maxUploadSize = intval(config('firefly.maxUploadSize')); - $this->allowedMimes = (array) config('firefly.allowedMimes'); + $this->allowedMimes = (array)config('firefly.allowedMimes'); $this->errors = new MessageBag; $this->messages = new MessageBag; $this->uploadDisk = Storage::disk('upload'); diff --git a/app/Helpers/Chart/MetaPieChart.php b/app/Helpers/Chart/MetaPieChart.php index fbeb70cc25..6c340b5389 100644 --- a/app/Helpers/Chart/MetaPieChart.php +++ b/app/Helpers/Chart/MetaPieChart.php @@ -21,6 +21,7 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\User; use Illuminate\Support\Collection; +use Steam; /** * Class MetaPieChart @@ -85,7 +86,8 @@ class MetaPieChart implements MetaPieChartInterface // also collect all other transactions if ($this->collectOtherObjects && $direction === 'expense') { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)->setTypes([TransactionType::WITHDRAWAL]); $journals = $collector->getJournals(); $sum = strval($journals->sum('transaction_amount')); @@ -96,7 +98,7 @@ class MetaPieChart implements MetaPieChartInterface if ($this->collectOtherObjects && $direction === 'income') { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($this->accounts)->setRange($this->start, $this->end)->setTypes([TransactionType::DEPOSIT]); $journals = $collector->getJournals(); $sum = strval($journals->sum('transaction_amount')); @@ -201,7 +203,7 @@ class MetaPieChart implements MetaPieChartInterface $modifier = 1; } /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($this->accounts); $collector->setRange($this->start, $this->end); $collector->setTypes($types); @@ -258,16 +260,13 @@ class MetaPieChart implements MetaPieChartInterface { $chartData = []; $names = []; - $repository = app($this->repositories[$type], [$this->user]); + $repository = app($this->repositories[$type]); foreach ($array as $objectId => $amount) { if (!isset($names[$objectId])) { $object = $repository->find(intval($objectId)); $names[$objectId] = $object->name; } - if (bccomp($amount, '0') === -1) { - $amount = bcmul($amount, '-1'); - } - + $amount = Steam::positive($amount); $this->total = bcadd($this->total, $amount); $chartData[$names[$objectId]] = $amount; } @@ -275,4 +274,4 @@ class MetaPieChart implements MetaPieChartInterface return $chartData; } -} \ No newline at end of file +} diff --git a/app/Helpers/Chart/MetaPieChartInterface.php b/app/Helpers/Chart/MetaPieChartInterface.php index a466db8a38..006300d308 100644 --- a/app/Helpers/Chart/MetaPieChartInterface.php +++ b/app/Helpers/Chart/MetaPieChartInterface.php @@ -79,4 +79,4 @@ interface MetaPieChartInterface */ public function setUser(User $user): MetaPieChartInterface; -} \ No newline at end of file +} diff --git a/app/Helpers/Collection/Budget.php b/app/Helpers/Collection/Budget.php deleted file mode 100644 index f590cb6216..0000000000 --- a/app/Helpers/Collection/Budget.php +++ /dev/null @@ -1,193 +0,0 @@ -budgetLines = new Collection; - } - - /** - * @param BudgetLine $budgetLine - * - * @return Budget - */ - public function addBudgetLine(BudgetLine $budgetLine): Budget - { - $this->budgetLines->push($budgetLine); - - return $this; - } - - /** - * @param string $add - * - * @return Budget - */ - public function addBudgeted(string $add): Budget - { - $this->budgeted = bcadd($this->budgeted, $add); - - return $this; - } - - /** - * @param string $add - * - * @return Budget - */ - public function addLeft(string $add): Budget - { - $this->left = bcadd($this->left, $add); - - return $this; - } - - /** - * @param string $add - * - * @return Budget - */ - public function addOverspent(string $add): Budget - { - $this->overspent = bcadd($this->overspent, $add); - - return $this; - } - - /** - * @param string $add - * - * @return Budget - */ - public function addSpent(string $add): Budget - { - $this->spent = bcadd($this->spent, $add); - - return $this; - } - - /** - * @return \Illuminate\Support\Collection - */ - public function getBudgetLines(): Collection - { - return $this->budgetLines; - } - - /** - * @return string - */ - public function getBudgeted(): string - { - return $this->budgeted; - } - - /** - * @param string $budgeted - * - * @return Budget - */ - public function setBudgeted(string $budgeted): Budget - { - $this->budgeted = $budgeted; - - return $this; - } - - /** - * @return string - */ - public function getLeft(): string - { - return $this->left; - } - - /** - * @param string $left - * - * @return Budget - */ - public function setLeft(string $left): Budget - { - $this->left = $left; - - return $this; - } - - /** - * @return string - */ - public function getOverspent(): string - { - return $this->overspent; - } - - /** - * @param string $overspent - * - * @return Budget - */ - public function setOverspent(string $overspent): Budget - { - $this->overspent = $overspent; - - return $this; - } - - /** - * @return string - */ - public function getSpent(): string - { - return $this->spent; - } - - /** - * @param string $spent - * - * @return Budget - */ - public function setSpent(string $spent): Budget - { - $this->spent = $spent; - - return $this; - } - - -} diff --git a/app/Helpers/Collection/BudgetLine.php b/app/Helpers/Collection/BudgetLine.php deleted file mode 100644 index 03bf59f8ff..0000000000 --- a/app/Helpers/Collection/BudgetLine.php +++ /dev/null @@ -1,161 +0,0 @@ -budget ?? new BudgetModel; - } - - /** - * @param BudgetModel $budget - * - * @return BudgetLine - */ - public function setBudget(BudgetModel $budget): BudgetLine - { - $this->budget = $budget; - - return $this; - } - - /** - * @return BudgetLimit - */ - public function getBudgetLimit(): BudgetLimit - { - return $this->budgetLimit ?? new BudgetLimit; - } - - /** - * @param BudgetLimit $budgetLimit - * - * @return BudgetLimit - */ - public function setBudgetLimit(BudgetLimit $budgetLimit): BudgetLine - { - $this->budgetLimit = $budgetLimit; - - return $this; - } - - /** - * @return string - */ - public function getBudgeted(): string - { - return $this->budgeted; - } - - /** - * @param string $budgeted - * - * @return BudgetLine - */ - public function setBudgeted(string $budgeted): BudgetLine - { - $this->budgeted = $budgeted; - - return $this; - } - - /** - * @return string - */ - public function getLeft(): string - { - return $this->left; - } - - /** - * @param string $left - * - * @return BudgetLine - */ - public function setLeft(string $left): BudgetLine - { - $this->left = $left; - - return $this; - } - - /** - * @return string - */ - public function getOverspent(): string - { - return $this->overspent; - } - - /** - * @param string $overspent - * - * @return BudgetLine - */ - public function setOverspent(string $overspent): BudgetLine - { - $this->overspent = $overspent; - - return $this; - } - - /** - * @return string - */ - public function getSpent(): string - { - return $this->spent; - } - - /** - * @param string $spent - * - * @return BudgetLine - */ - public function setSpent(string $spent): BudgetLine - { - $this->spent = $spent; - - return $this; - } - - -} diff --git a/app/Helpers/Collector/JournalCollector.php b/app/Helpers/Collector/JournalCollector.php index c198da7764..1603b61256 100644 --- a/app/Helpers/Collector/JournalCollector.php +++ b/app/Helpers/Collector/JournalCollector.php @@ -32,6 +32,7 @@ use Illuminate\Database\Query\JoinClause; use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use Log; +use Steam; /** * Maybe this is a good idea after all... @@ -54,9 +55,7 @@ class JournalCollector implements JournalCollectorInterface 'transaction_journals.description', 'transaction_journals.date', 'transaction_journals.encrypted', - //'transaction_journals.transaction_currency_id', 'transaction_currencies.code as transaction_currency_code', - //'transaction_currencies.symbol as transaction_currency_symbol', 'transaction_types.type as transaction_type_type', 'transaction_journals.bill_id', 'bills.name as bill_name', @@ -96,17 +95,6 @@ class JournalCollector implements JournalCollectorInterface /** @var User */ private $user; - /** - * JournalCollector constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - $this->query = $this->startQuery(); - } - /** * @return int * @throws FireflyException @@ -168,7 +156,7 @@ class JournalCollector implements JournalCollectorInterface { $this->run = true; /** @var Collection $set */ - $set = $this->query->get(array_values($this->fields)); + $set = $this->query->get(array_values($this->fields)); Log::debug(sprintf('Count of set is %d', $set->count())); $set = $this->filterTransfers($set); Log::debug(sprintf('Count of set after filterTransfers() is %d', $set->count())); @@ -182,10 +170,10 @@ class JournalCollector implements JournalCollectorInterface $set->each( function (Transaction $transaction) { $transaction->date = new Carbon($transaction->date); - $transaction->description = $transaction->encrypted ? Crypt::decrypt($transaction->description) : $transaction->description; + $transaction->description = Steam::decrypt(intval($transaction->encrypted), $transaction->description); if (!is_null($transaction->bill_name)) { - $transaction->bill_name = $transaction->bill_name_encrypted ? Crypt::decrypt($transaction->bill_name) : $transaction->bill_name; + $transaction->bill_name = Steam::decrypt(intval($transaction->bill_name_encrypted), $transaction->bill_name); } try { @@ -244,8 +232,9 @@ class JournalCollector implements JournalCollectorInterface public function setAllAssetAccounts(): JournalCollectorInterface { /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); - $accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); + $accounts = $repository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]); if ($accounts->count() > 0) { $accountIds = $accounts->pluck('id')->toArray(); $this->query->whereIn('transactions.account_id', $accountIds); @@ -456,6 +445,37 @@ class JournalCollector implements JournalCollectorInterface return $this; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + + /** + * + */ + public function startQuery() + { + /** @var EloquentBuilder $query */ + $query = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') + ->leftJoin('transaction_currencies', 'transaction_currencies.id', 'transaction_journals.transaction_currency_id') + ->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id') + ->leftJoin('bills', 'bills.id', 'transaction_journals.bill_id') + ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') + ->leftJoin('account_types', 'accounts.account_type_id', 'account_types.id') + ->whereNull('transactions.deleted_at') + ->whereNull('transaction_journals.deleted_at') + ->where('transaction_journals.user_id', $this->user->id) + ->orderBy('transaction_journals.date', 'DESC') + ->orderBy('transaction_journals.order', 'ASC') + ->orderBy('transaction_journals.id', 'DESC'); + + $this->query = $query; + + } + /** * @return JournalCollectorInterface */ @@ -484,36 +504,6 @@ class JournalCollector implements JournalCollectorInterface { $this->joinOpposingTables(); - $accountIds = $this->accountIds; - $this->query->where( - function (EloquentBuilder $q1) use ($accountIds) { - // set 1: - // where source is in the set of $accounts - // but destination is not. - $q1->where( - function (EloquentBuilder $q2) use ($accountIds) { - // transactions.account_id in set - $q2->whereIn('transactions.account_id', $accountIds); - // opposing.account_id not in set - $q2->whereNotIn('opposing.account_id', $accountIds); - - } - ); - // set 1: - // where source is not in the set of $accounts - // but destination is. - $q1->orWhere( - function (EloquentBuilder $q3) use ($accountIds) { - // transactions.account_id not in set - $q3->whereNotIn('transactions.account_id', $accountIds); - // B in set - // opposing.account_id not in set - $q3->whereIn('opposing.account_id', $accountIds); - } - ); - } - ); - return $this; } @@ -597,7 +587,7 @@ class JournalCollector implements JournalCollectorInterface * account, chances are the set include double entries: transfers get selected * on both the source, and then again on the destination account. * - * This method filters them out. + * This method filters them out by removing transfers that have been selected twice. * * @param Collection $set * @@ -606,36 +596,29 @@ class JournalCollector implements JournalCollectorInterface private function filterTransfers(Collection $set): Collection { if ($this->filterTransfers) { - $set = $set->filter( - function (Transaction $transaction) { - if (!($transaction->transaction_type_type === TransactionType::TRANSFER && bccomp($transaction->transaction_amount, '0') === -1)) { - - Log::debug( - sprintf( - 'Included journal #%d (transaction #%d) because its a %s with amount %f', - $transaction->transaction_journal_id, - $transaction->id, - $transaction->transaction_type_type, - $transaction->transaction_amount - ) - ); - - return $transaction; - } - - Log::debug( - sprintf( - 'Removed journal #%d (transaction #%d) because its a %s with amount %f', - $transaction->transaction_journal_id, - $transaction->id, - $transaction->transaction_type_type, - $transaction->transaction_amount - ) - ); - - return false; + $count = []; + $new = new Collection; + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + if ($transaction->transaction_type_type !== TransactionType::TRANSFER) { + $new->push($transaction); + continue; } - ); + // make property string: + $journalId = $transaction->transaction_journal_id; + $amount = Steam::positive($transaction->transaction_amount); + $accountIds = [intval($transaction->account_id), intval($transaction->opposing_account_id)]; + sort($accountIds); + $key = $journalId . '-' . join(',', $accountIds) . '-' . $amount; + Log::debug(sprintf('Key is %s', $key)); + if (!isset($count[$key])) { + // not yet counted? add to new set and count it: + $new->push($transaction); + $count[$key] = 1; + } + } + + return $new; } return $set; @@ -729,27 +712,4 @@ class JournalCollector implements JournalCollectorInterface $this->query->leftJoin('tag_transaction_journal', 'tag_transaction_journal.transaction_journal_id', '=', 'transaction_journals.id'); } } - - /** - * @return EloquentBuilder - */ - private function startQuery(): EloquentBuilder - { - /** @var EloquentBuilder $query */ - $query = Transaction::leftJoin('transaction_journals', 'transaction_journals.id', '=', 'transactions.transaction_journal_id') - ->leftJoin('transaction_currencies', 'transaction_currencies.id', 'transaction_journals.transaction_currency_id') - ->leftJoin('transaction_types', 'transaction_types.id', 'transaction_journals.transaction_type_id') - ->leftJoin('bills', 'bills.id', 'transaction_journals.bill_id') - ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') - ->leftJoin('account_types', 'accounts.account_type_id', 'account_types.id') - ->whereNull('transactions.deleted_at') - ->whereNull('transaction_journals.deleted_at') - ->where('transaction_journals.user_id', $this->user->id) - ->orderBy('transaction_journals.date', 'DESC') - ->orderBy('transaction_journals.order', 'ASC') - ->orderBy('transaction_journals.id', 'DESC'); - - return $query; - - } } diff --git a/app/Helpers/Collector/JournalCollectorInterface.php b/app/Helpers/Collector/JournalCollectorInterface.php index b3307ebac0..80e41eb781 100644 --- a/app/Helpers/Collector/JournalCollectorInterface.php +++ b/app/Helpers/Collector/JournalCollectorInterface.php @@ -17,6 +17,7 @@ use Carbon\Carbon; use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\Tag; +use FireflyIII\User; use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; @@ -27,7 +28,6 @@ use Illuminate\Support\Collection; */ interface JournalCollectorInterface { - /** * @return int */ @@ -84,7 +84,6 @@ interface JournalCollectorInterface */ public function setBudget(Budget $budget): JournalCollectorInterface; - /** * @param Collection $budgets * @@ -149,6 +148,13 @@ interface JournalCollectorInterface */ public function setTypes(array $types): JournalCollectorInterface; + public function setUser(User $user); + + /** + * + */ + public function startQuery(); + /** * @return JournalCollectorInterface */ diff --git a/app/Helpers/Report/BalanceReportHelper.php b/app/Helpers/Report/BalanceReportHelper.php index ca0667cf66..2c6dae78a8 100644 --- a/app/Helpers/Report/BalanceReportHelper.php +++ b/app/Helpers/Report/BalanceReportHelper.php @@ -158,7 +158,9 @@ class BalanceReportHelper implements BalanceReportHelperInterface foreach ($accounts as $account) { $balanceEntry = new BalanceEntry; $balanceEntry->setAccount($account); - $spent = $this->budgetRepository->spentInPeriod(new Collection([$budgetLimit->budget]), new Collection([$account]), $budgetLimit->start_date, $budgetLimit->end_date); + $spent = $this->budgetRepository->spentInPeriod( + new Collection([$budgetLimit->budget]), new Collection([$account]), $budgetLimit->start_date, $budgetLimit->end_date + ); $balanceEntry->setSpent($spent); $line->addBalanceEntry($balanceEntry); } diff --git a/app/Helpers/Report/BudgetReportHelper.php b/app/Helpers/Report/BudgetReportHelper.php index dff9d99d74..8025b0a159 100644 --- a/app/Helpers/Report/BudgetReportHelper.php +++ b/app/Helpers/Report/BudgetReportHelper.php @@ -15,8 +15,6 @@ namespace FireflyIII\Helpers\Report; use Carbon\Carbon; -use FireflyIII\Helpers\Collection\Budget as BudgetCollection; -use FireflyIII\Helpers\Collection\BudgetLine; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; @@ -48,44 +46,63 @@ class BudgetReportHelper implements BudgetReportHelperInterface * @param Carbon $end * @param Collection $accounts * - * @return BudgetCollection + * @return array */ - public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): BudgetCollection + public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): array { - $object = new BudgetCollection; - $set = $this->repository->getBudgets(); + $set = $this->repository->getBudgets(); + $array = []; /** @var Budget $budget */ foreach ($set as $budget) { $budgetLimits = $this->repository->getBudgetLimits($budget, $start, $end); if ($budgetLimits->count() == 0) { // no budget limit(s) for this budget + $spent = $this->repository->spentInPeriod(new Collection([$budget]), $accounts, $start, $end);// spent for budget in time range - if ($spent > 0) { - $budgetLine = new BudgetLine; - $budgetLine->setBudget($budget)->setOverspent($spent); - $object->addOverspent($spent)->addBudgetLine($budgetLine); + if (bccomp($spent, '0') === -1) { + $line = [ + 'type' => 'budget', + 'id' => $budget->id, + 'name' => $budget->name, + 'budgeted' => '0', + 'spent' => $spent, + 'left' => '0', + 'overspent' => '0', + ]; + $array[] = $line; } continue; } /** @var BudgetLimit $budgetLimit */ foreach ($budgetLimits as $budgetLimit) { // one or more repetitions for budget - $data = $this->calculateExpenses($budget, $budgetLimit, $accounts); - $budgetLine = new BudgetLine; - $budgetLine->setBudget($budget)->setBudgetLimit($budgetLimit) - ->setLeft($data['left'])->setSpent($data['expenses'])->setOverspent($data['overspent']) - ->setBudgeted(strval($budgetLimit->amount)); - - $object->addBudgeted(strval($budgetLimit->amount))->addSpent($data['spent']) - ->addLeft($data['left'])->addOverspent($data['overspent'])->addBudgetLine($budgetLine); + $data = $this->calculateExpenses($budget, $budgetLimit, $accounts); + $line = [ + 'type' => 'budget-line', + 'start' => $budgetLimit->start_date, + 'end' => $budgetLimit->end_date, + 'limit' => $budgetLimit->id, + 'id' => $budget->id, + 'name' => $budget->name, + 'budgeted' => strval($budgetLimit->amount), + 'spent' => $data['expenses'], + 'left' => $data['left'], + 'overspent' => $data['overspent'], + ]; + $array[] = $line; } } - $noBudget = $this->repository->spentInPeriodWoBudget($accounts, $start, $end); // stuff outside of budgets - $budgetLine = new BudgetLine; - $budgetLine->setOverspent($noBudget)->setSpent($noBudget); - $object->addOverspent($noBudget)->addBudgetLine($budgetLine); + $noBudget = $this->repository->spentInPeriodWoBudget($accounts, $start, $end); // stuff outside of budgets + $line = [ + 'type' => 'no-budget', + 'budgeted' => '0', + 'spent' => $noBudget, + 'left' => '0', + 'overspent' => '0', + ]; + $array[] = $line; - return $object; + return $array; } /** diff --git a/app/Helpers/Report/BudgetReportHelperInterface.php b/app/Helpers/Report/BudgetReportHelperInterface.php index 07234f9694..a64d47d39f 100644 --- a/app/Helpers/Report/BudgetReportHelperInterface.php +++ b/app/Helpers/Report/BudgetReportHelperInterface.php @@ -15,7 +15,6 @@ namespace FireflyIII\Helpers\Report; use Carbon\Carbon; -use FireflyIII\Helpers\Collection\Budget as BudgetCollection; use Illuminate\Support\Collection; /** @@ -31,9 +30,9 @@ interface BudgetReportHelperInterface * @param Carbon $end * @param Collection $accounts * - * @return BudgetCollection + * @return array */ - public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): BudgetCollection; + public function getBudgetReport(Carbon $start, Carbon $end, Collection $accounts): array; /** * @param Carbon $start diff --git a/app/Helpers/Report/ReportHelper.php b/app/Helpers/Report/ReportHelper.php index 40b7b68eaf..20a008e87a 100644 --- a/app/Helpers/Report/ReportHelper.php +++ b/app/Helpers/Report/ReportHelper.php @@ -16,15 +16,12 @@ namespace FireflyIII\Helpers\Report; use Carbon\Carbon; use FireflyIII\Helpers\Collection\Bill as BillCollection; use FireflyIII\Helpers\Collection\BillLine; -use FireflyIII\Helpers\Collection\Category as CategoryCollection; use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Helpers\FiscalHelperInterface; use FireflyIII\Models\Bill; -use FireflyIII\Models\Category; use FireflyIII\Models\Transaction; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; -use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use Illuminate\Support\Collection; /** @@ -68,7 +65,7 @@ class ReportHelper implements ReportHelperInterface /** @var BillRepositoryInterface $repository */ $repository = app(BillRepositoryInterface::class); $bills = $repository->getBillsForAccounts($accounts); - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($accounts)->setRange($start, $end)->setBills($bills); $journals = $collector->getJournals(); $collection = new BillCollection; diff --git a/app/Helpers/Report/ReportHelperInterface.php b/app/Helpers/Report/ReportHelperInterface.php index 9124821593..fb14625126 100644 --- a/app/Helpers/Report/ReportHelperInterface.php +++ b/app/Helpers/Report/ReportHelperInterface.php @@ -15,7 +15,6 @@ namespace FireflyIII\Helpers\Report; use Carbon\Carbon; use FireflyIII\Helpers\Collection\Bill as BillCollection; -use FireflyIII\Helpers\Collection\Category as CategoryCollection; use FireflyIII\Helpers\Collection\Expense; use FireflyIII\Helpers\Collection\Income; use Illuminate\Support\Collection; diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index b3b007cb9e..2c12693bcd 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -23,7 +23,6 @@ use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\Transaction; use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Account\AccountTaskerInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Support\CacheProperties; @@ -32,9 +31,7 @@ use Illuminate\Support\Collection; use Log; use Navigation; use Preferences; -use Session; use Steam; -use URL; use View; /** @@ -63,11 +60,12 @@ class AccountController extends Controller } /** - * @param string $what + * @param Request $request + * @param string $what * - * @return \Illuminate\View\View|\Illuminate\Contracts\View\Factory|View + * @return View */ - public function create(string $what = 'asset') + public function create(Request $request, string $what = 'asset') { /** @var CurrencyRepositoryInterface $repository */ $repository = app(CurrencyRepositoryInterface::class); @@ -82,27 +80,28 @@ class AccountController extends Controller // pre fill some data - Session::flash('preFilled', ['currency_id' => $defaultCurrency->id,]); + $request->session()->flash('preFilled', ['currency_id' => $defaultCurrency->id,]); // put previous url in session if not redirect from store (not "create another"). if (session('accounts.create.fromStore') !== true) { - Session::put('accounts.create.url', URL::previous()); + $this->rememberPreviousUri('accounts.create.uri'); } - Session::forget('accounts.create.fromStore'); - Session::flash('gaEventCategory', 'accounts'); - Session::flash('gaEventAction', 'create-' . $what); + $request->session()->forget('accounts.create.fromStore'); + $request->session()->flash('gaEventCategory', 'accounts'); + $request->session()->flash('gaEventAction', 'create-' . $what); return view('accounts.create', compact('subTitleIcon', 'what', 'subTitle', 'currencies', 'roles')); } /** - * @param ARI $repository - * @param Account $account + * @param Request $request + * @param AccountRepositoryInterface $repository + * @param Account $account * * @return View */ - public function delete(ARI $repository, Account $account) + public function delete(Request $request, AccountRepositoryInterface $repository, Account $account) { $typeName = config('firefly.shortNamesByFullName.' . $account->accountType->type); $subTitle = trans('firefly.delete_' . $typeName . '_account', ['name' => $account->name]); @@ -110,48 +109,42 @@ class AccountController extends Controller unset($accountList[$account->id]); // put previous url in session - Session::put('accounts.delete.url', URL::previous()); - Session::flash('gaEventCategory', 'accounts'); - Session::flash('gaEventAction', 'delete-' . $typeName); + $this->rememberPreviousUri('accounts.delete.uri'); + $request->session()->flash('gaEventCategory', 'accounts'); + $request->session()->flash('gaEventAction', 'delete-' . $typeName); return view('accounts.delete', compact('account', 'subTitle', 'accountList')); } /** - * @param Request $request - * @param ARI $repository - * @param Account $account + * @param Request $request + * @param AccountRepositoryInterface $repository + * @param Account $account * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function destroy(Request $request, ARI $repository, Account $account) + public function destroy(Request $request, AccountRepositoryInterface $repository, Account $account) { - $type = $account->accountType->type; - $typeName = config('firefly.shortNamesByFullName.' . $type); - $name = $account->name; - $accountId = $account->id; - $moveTo = $repository->find(intval($request->get('move_account_before_delete'))); + $type = $account->accountType->type; + $typeName = config('firefly.shortNamesByFullName.' . $type); + $name = $account->name; + $moveTo = $repository->find(intval($request->get('move_account_before_delete'))); $repository->destroy($account, $moveTo); - Session::flash('success', strval(trans('firefly.' . $typeName . '_deleted', ['name' => $name]))); + $request->session()->flash('success', strval(trans('firefly.' . $typeName . '_deleted', ['name' => $name]))); Preferences::mark(); - $uri = session('accounts.delete.url'); - if (!(strpos($uri, sprintf('accounts/show/%s', $accountId)) === false)) { - // uri would point back to account - $uri = route('accounts.index', [$typeName]); - } - - return redirect($uri); + return redirect($this->getPreviousUri('accounts.delete.uri')); } /** + * @param Request $request * @param Account $account * * @return View */ - public function edit(Account $account) + public function edit(Request $request, Account $account) { $what = config('firefly.shortNamesByFullName')[$account->accountType->type]; @@ -168,9 +161,9 @@ class AccountController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('accounts.edit.fromUpdate') !== true) { - Session::put('accounts.edit.url', URL::previous()); + $this->rememberPreviousUri('accounts.edit.uri'); } - Session::forget('accounts.edit.fromUpdate'); + $request->session()->forget('accounts.edit.fromUpdate'); // pre fill some useful values. @@ -191,20 +184,20 @@ class AccountController extends Controller 'virtualBalance' => $account->virtual_balance, 'currency_id' => $account->getMeta('currency_id'), ]; - Session::flash('preFilled', $preFilled); - Session::flash('gaEventCategory', 'accounts'); - Session::flash('gaEventAction', 'edit-' . $what); + $request->session()->flash('preFilled', $preFilled); + $request->session()->flash('gaEventCategory', 'accounts'); + $request->session()->flash('gaEventAction', 'edit-' . $what); return view('accounts.edit', compact('currencies', 'account', 'subTitle', 'subTitleIcon', 'openingBalance', 'what', 'roles')); } /** - * @param ARI $repository - * @param string $what + * @param AccountRepositoryInterface $repository + * @param string $what * * @return View */ - public function index(ARI $repository, string $what) + public function index(AccountRepositoryInterface $repository, string $what) { $what = $what ?? 'asset'; $subTitle = trans('firefly.' . $what . '_accounts'); @@ -269,9 +262,9 @@ class AccountController extends Controller } /** - * @param Request $request - * @param ARI $repository - * @param Account $account + * @param Request $request + * @param AccountRepositoryInterface $repository + * @param Account $account * * @return View */ @@ -284,7 +277,8 @@ class AccountController extends Controller // replace with journal collector: /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser(auth()->user()); $collector->setAccounts(new Collection([$account]))->setLimit($pageSize)->setPage($page); $journals = $collector->getPaginatedJournals(); $journals->setPath('accounts/show/' . $account->id . '/all'); @@ -318,7 +312,7 @@ class AccountController extends Controller // replace with journal collector: /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts(new Collection([$account]))->setRange($start, $end)->setLimit($pageSize)->setPage($page); $journals = $collector->getPaginatedJournals(); $journals->setPath('accounts/show/' . $account->id . '/' . $date); @@ -331,18 +325,18 @@ class AccountController extends Controller } /** - * @param AccountFormRequest $request - * @param ARI $repository + * @param AccountFormRequest $request + * @param AccountRepositoryInterface $repository * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector * */ - public function store(AccountFormRequest $request, ARI $repository) + public function store(AccountFormRequest $request, AccountRepositoryInterface $repository) { $data = $request->getAccountData(); $account = $repository->store($data); - Session::flash('success', strval(trans('firefly.stored_new_account', ['name' => $account->name]))); + $request->session()->flash('success', strval(trans('firefly.stored_new_account', ['name' => $account->name]))); Preferences::mark(); // update preferences if necessary: @@ -354,39 +348,39 @@ class AccountController extends Controller if (intval($request->get('create_another')) === 1) { // set value so create routine will not overwrite URL: - Session::put('accounts.create.fromStore', true); + $request->session()->put('accounts.create.fromStore', true); return redirect(route('accounts.create', [$request->input('what')]))->withInput(); } // redirect to previous URL. - return redirect(session('accounts.create.url')); + return redirect($this->getPreviousUri('accounts.create.uri')); } /** - * @param AccountFormRequest $request - * @param ARI $repository - * @param Account $account + * @param AccountFormRequest $request + * @param AccountRepositoryInterface $repository + * @param Account $account * * @return $this|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function update(AccountFormRequest $request, ARI $repository, Account $account) + public function update(AccountFormRequest $request, AccountRepositoryInterface $repository, Account $account) { $data = $request->getAccountData(); $repository->update($account, $data); - Session::flash('success', strval(trans('firefly.updated_account', ['name' => $account->name]))); + $request->session()->flash('success', strval(trans('firefly.updated_account', ['name' => $account->name]))); Preferences::mark(); if (intval($request->get('return_to_edit')) === 1) { // set value so edit routine will not overwrite URL: - Session::put('accounts.edit.fromUpdate', true); + $request->session()->put('accounts.edit.fromUpdate', true); return redirect(route('accounts.edit', [$account->id]))->withInput(['return_to_edit' => 1]); } // redirect to previous URL. - return redirect(session('accounts.edit.url')); + return redirect($this->getPreviousUri('accounts.edit.uri')); } @@ -417,8 +411,8 @@ class AccountController extends Controller */ private function periodEntries(Account $account): Collection { - /** @var ARI $repository */ - $repository = app(ARI::class); + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepositoryInterface::class); /** @var AccountTaskerInterface $tasker */ $tasker = app(AccountTaskerInterface::class); diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 9fcb8b9a99..818c12c2f6 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -20,7 +20,6 @@ use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\User; use Preferences; use Session; -use URL; use View; /** @@ -57,7 +56,7 @@ class UserController extends Controller { // put previous url in session if not redirect from store (not "return_to_edit"). if (session('users.edit.fromUpdate') !== true) { - Session::put('users.edit.url', URL::previous()); + $this->rememberPreviousUri('users.edit.uri'); } Session::forget('users.edit.fromUpdate'); @@ -156,7 +155,7 @@ class UserController extends Controller } // redirect to previous URL. - return redirect(session('users.edit.url')); + return redirect($this->getPreviousUri('users.edit.uri')); } diff --git a/app/Http/Controllers/AttachmentController.php b/app/Http/Controllers/AttachmentController.php index 2b154defea..51b24e4d93 100644 --- a/app/Http/Controllers/AttachmentController.php +++ b/app/Http/Controllers/AttachmentController.php @@ -18,11 +18,10 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Requests\AttachmentFormRequest; use FireflyIII\Models\Attachment; use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; +use Illuminate\Http\Request; use Illuminate\Http\Response as LaravelResponse; use Preferences; use Response; -use Session; -use URL; use View; /** @@ -54,38 +53,40 @@ class AttachmentController extends Controller } /** + * @param Request $request * @param Attachment $attachment * * @return View */ - public function delete(Attachment $attachment) + public function delete(Request $request, Attachment $attachment) { $subTitle = trans('firefly.delete_attachment', ['name' => $attachment->filename]); // put previous url in session - Session::put('attachments.delete.url', URL::previous()); - Session::flash('gaEventCategory', 'attachments'); - Session::flash('gaEventAction', 'delete-attachment'); + $this->rememberPreviousUri('attachments.delete.uri'); + $request->session()->flash('gaEventCategory', 'attachments'); + $request->session()->flash('gaEventAction', 'delete-attachment'); return view('attachments.delete', compact('attachment', 'subTitle')); } /** + * @param Request $request * @param AttachmentRepositoryInterface $repository * @param Attachment $attachment * - * @return \Illuminate\Http\RedirectResponse + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function destroy(AttachmentRepositoryInterface $repository, Attachment $attachment) + public function destroy(Request $request, AttachmentRepositoryInterface $repository, Attachment $attachment) { $name = $attachment->filename; $repository->destroy($attachment); - Session::flash('success', strval(trans('firefly.attachment_deleted', ['name' => $name]))); + $request->session()->flash('success', strval(trans('firefly.attachment_deleted', ['name' => $name]))); Preferences::mark(); - return redirect(session('attachments.delete.url')); + return redirect($this->getPreviousUri('attachments.delete.uri')); } /** @@ -120,20 +121,21 @@ class AttachmentController extends Controller } /** + * @param Request $request * @param Attachment $attachment * * @return View */ - public function edit(Attachment $attachment) + public function edit(Request $request, Attachment $attachment) { $subTitleIcon = 'fa-pencil'; $subTitle = trans('firefly.edit_attachment', ['name' => $attachment->filename]); // put previous url in session if not redirect from store (not "return_to_edit"). if (session('attachments.edit.fromUpdate') !== true) { - Session::put('attachments.edit.url', URL::previous()); + $this->rememberPreviousUri('attachments.edit.uri'); } - Session::forget('attachments.edit.fromUpdate'); + $request->session()->forget('attachments.edit.fromUpdate'); return view('attachments.edit', compact('attachment', 'subTitleIcon', 'subTitle')); } @@ -170,18 +172,18 @@ class AttachmentController extends Controller $data = $request->getAttachmentData(); $repository->update($attachment, $data); - Session::flash('success', strval(trans('firefly.attachment_updated', ['name' => $attachment->filename]))); + $request->session()->flash('success', strval(trans('firefly.attachment_updated', ['name' => $attachment->filename]))); Preferences::mark(); if (intval($request->get('return_to_edit')) === 1) { // set value so edit routine will not overwrite URL: - Session::put('attachments.edit.fromUpdate', true); + $request->session()->put('attachments.edit.fromUpdate', true); return redirect(route('attachments.edit', [$attachment->id]))->withInput(['return_to_edit' => 1]); } // redirect to previous URL. - return redirect(session('attachments.edit.url')); + return redirect($this->getPreviousUri('attachments.edit.uri')); } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index c6389159b8..0072229023 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -16,6 +16,7 @@ use Config; use FireflyConfig; use FireflyIII\Http\Controllers\Controller; use FireflyIII\User; +use Illuminate\Cookie\CookieJar; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; use Lang; @@ -30,13 +31,6 @@ class LoginController extends Controller use AuthenticatesUsers; - /** - * Where to redirect users after login / registration. - * - * @var string - */ - protected $redirectTo = '/'; - /** * Create a new controller instance. * @@ -80,6 +74,37 @@ class LoginController extends Controller return $this->sendFailedLoginResponse($request, $errorMessage); } + /** + * @param Request $request + * @param CookieJar $cookieJar + * + * @return $this + */ + public function logout(Request $request, CookieJar $cookieJar) + { + if (intval(getenv('SANDSTORM')) === 1) { + return view('error')->with('message', strval(trans('firefly.sandstorm_not_available'))); + } + + $cookie = $cookieJar->forever('twoFactorAuthenticated', 'false'); + + $this->guard()->logout(); + + $request->session()->flush(); + + $request->session()->regenerate(); + + return redirect('/')->withCookie($cookie); + } + + /** + * @return string + */ + public function redirectTo(): string + { + return route('index'); + } + /** * Show the application login form. * diff --git a/app/Http/Controllers/Auth/TwoFactorController.php b/app/Http/Controllers/Auth/TwoFactorController.php index d48f5906f2..9b74cad644 100644 --- a/app/Http/Controllers/Auth/TwoFactorController.php +++ b/app/Http/Controllers/Auth/TwoFactorController.php @@ -13,13 +13,13 @@ declare(strict_types = 1); namespace FireflyIII\Http\Controllers\Auth; -use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\TokenFormRequest; +use Illuminate\Cookie\CookieJar; +use Illuminate\Http\Request; use Log; use Preferences; -use Session; /** * Class TwoFactorController @@ -30,11 +30,14 @@ class TwoFactorController extends Controller { /** - * @return mixed + * @param Request $request + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View * @throws FireflyException */ - public function index() + public function index(Request $request) { + $user = auth()->user(); // to make sure the validator in the next step gets the secret, we push it in session @@ -50,7 +53,7 @@ class TwoFactorController extends Controller if (strlen(strval($secret)) === 0) { throw new FireflyException('Your two factor authentication secret is empty, which it cannot be at this point. Please check the log files.'); } - Session::flash('two-factor-secret', $secret); + $request->session()->flash('two-factor-secret', $secret); return view('auth.two-factor', compact('user', 'title')); } @@ -80,12 +83,12 @@ class TwoFactorController extends Controller * * @return mixed */ - public function postIndex(TokenFormRequest $request) + public function postIndex(TokenFormRequest $request, CookieJar $cookieJar) { - Session::put('twofactor-authenticated', true); - Session::put('twofactor-authenticated-date', new Carbon); + // set cookie! + $cookie = $cookieJar->forever('twoFactorAuthenticated', 'true'); - return redirect(route('home')); + return redirect(route('home'))->withCookie($cookie); } } diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php index 0642dd260b..b05ede6e52 100644 --- a/app/Http/Controllers/BillController.php +++ b/app/Http/Controllers/BillController.php @@ -22,7 +22,6 @@ use FireflyIII\Repositories\Bill\BillRepositoryInterface; use Illuminate\Http\Request; use Illuminate\Support\Collection; use Preferences; -use Session; use URL; use View; @@ -53,9 +52,11 @@ class BillController extends Controller } /** + * @param Request $request + * * @return View */ - public function create() + public function create(Request $request) { $periods = []; foreach (config('firefly.bill_periods') as $current) { @@ -66,61 +67,57 @@ class BillController extends Controller // put previous url in session if not redirect from store (not "create another"). if (session('bills.create.fromStore') !== true) { - Session::put('bills.create.url', URL::previous()); + $this->rememberPreviousUri('bills.create.uri'); } - Session::forget('bills.create.fromStore'); - Session::flash('gaEventCategory', 'bills'); - Session::flash('gaEventAction', 'create'); + $request->session()->forget('bills.create.fromStore'); + $request->session()->flash('gaEventCategory', 'bills'); + $request->session()->flash('gaEventAction', 'create'); return view('bills.create', compact('periods', 'subTitle')); } /** - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return View */ - public function delete(Bill $bill) + public function delete(Request $request, Bill $bill) { // put previous url in session - Session::put('bills.delete.url', URL::previous()); - Session::flash('gaEventCategory', 'bills'); - Session::flash('gaEventAction', 'delete'); + $this->rememberPreviousUri('bills.delete.uri'); + $request->session()->flash('gaEventCategory', 'bills'); + $request->session()->flash('gaEventAction', 'delete'); $subTitle = trans('firefly.delete_bill', ['name' => $bill->name]); return view('bills.delete', compact('bill', 'subTitle')); } /** + * @param Request $request * @param BillRepositoryInterface $repository * @param Bill $bill * - * @return \Illuminate\Http\RedirectResponse + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function destroy(BillRepositoryInterface $repository, Bill $bill) + public function destroy(Request $request, BillRepositoryInterface $repository, Bill $bill) { - $name = $bill->name; - $billId = $bill->id; + $name = $bill->name; $repository->destroy($bill); - Session::flash('success', strval(trans('firefly.deleted_bill', ['name' => $name]))); + $request->session()->flash('success', strval(trans('firefly.deleted_bill', ['name' => $name]))); Preferences::mark(); - $uri = session('bills.delete.url'); - if (!(strpos($uri, sprintf('bills/show/%s', $billId)) === false)) { - // uri would point back to bill - $uri = route('bills.index'); - } - - return redirect($uri); + return redirect($this->getPreviousUri('bills.delete.uri')); } /** - * @param Bill $bill + * @param Request $request + * @param Bill $bill * * @return View */ - public function edit(Bill $bill) + public function edit(Request $request, Bill $bill) { $periods = []; foreach (config('firefly.bill_periods') as $current) { @@ -130,11 +127,11 @@ class BillController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('bills.edit.fromUpdate') !== true) { - Session::put('bills.edit.url', URL::previous()); + $this->rememberPreviousUri('bills.edit.uri'); } - Session::forget('bills.edit.fromUpdate'); - Session::flash('gaEventCategory', 'bills'); - Session::flash('gaEventAction', 'edit'); + $request->session()->forget('bills.edit.fromUpdate'); + $request->session()->flash('gaEventCategory', 'bills'); + $request->session()->flash('gaEventAction', 'edit'); return view('bills.edit', compact('subTitle', 'periods', 'bill')); } @@ -170,15 +167,16 @@ class BillController extends Controller } /** + * @param Request $request * @param BillRepositoryInterface $repository * @param Bill $bill * - * @return \Illuminate\Http\RedirectResponse + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function rescan(BillRepositoryInterface $repository, Bill $bill) + public function rescan(Request $request, BillRepositoryInterface $repository, Bill $bill) { if (intval($bill->active) == 0) { - Session::flash('warning', strval(trans('firefly.cannot_scan_inactive_bill'))); + $request->session()->flash('warning', strval(trans('firefly.cannot_scan_inactive_bill'))); return redirect(URL::previous()); } @@ -190,7 +188,7 @@ class BillController extends Controller } - Session::flash('success', strval(trans('firefly.rescanned_bill'))); + $request->session()->flash('success', strval(trans('firefly.rescanned_bill'))); Preferences::mark(); return redirect(URL::previous()); @@ -215,7 +213,7 @@ class BillController extends Controller // use collector: /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAllAssetAccounts()->setBills(new Collection([$bill]))->setLimit($pageSize)->setPage($page)->withBudgetInformation() ->withCategoryInformation(); $journals = $collector->getPaginatedJournals(); @@ -238,18 +236,18 @@ class BillController extends Controller { $billData = $request->getBillData(); $bill = $repository->store($billData); - Session::flash('success', strval(trans('firefly.stored_new_bill', ['name' => e($bill->name)]))); + $request->session()->flash('success', strval(trans('firefly.stored_new_bill', ['name' => e($bill->name)]))); Preferences::mark(); if (intval($request->get('create_another')) === 1) { // set value so create routine will not overwrite URL: - Session::put('bills.create.fromStore', true); + $request->session()->put('bills.create.fromStore', true); return redirect(route('bills.create'))->withInput(); } // redirect to previous URL. - return redirect(session('bills.create.url')); + return redirect($this->getPreviousUri('bills.create.uri')); } @@ -265,18 +263,17 @@ class BillController extends Controller $billData = $request->getBillData(); $bill = $repository->update($bill, $billData); - Session::flash('success', strval(trans('firefly.updated_bill', ['name' => e($bill->name)]))); + $request->session()->flash('success', strval(trans('firefly.updated_bill', ['name' => e($bill->name)]))); Preferences::mark(); if (intval($request->get('return_to_edit')) === 1) { // set value so edit routine will not overwrite URL: - Session::put('bills.edit.fromUpdate', true); + $request->session()->put('bills.edit.fromUpdate', true); return redirect(route('bills.edit', [$bill->id]))->withInput(['return_to_edit' => 1]); } - // redirect to previous URL. - return redirect(session('bills.edit.url')); + return redirect($this->getPreviousUri('bills.edit.uri')); } diff --git a/app/Http/Controllers/BudgetController.php b/app/Http/Controllers/BudgetController.php index 0d8ce65937..c7c73030f7 100644 --- a/app/Http/Controllers/BudgetController.php +++ b/app/Http/Controllers/BudgetController.php @@ -29,8 +29,6 @@ use Illuminate\Http\Request; use Illuminate\Support\Collection; use Preferences; use Response; -use Session; -use URL; use View; /** @@ -88,17 +86,19 @@ class BudgetController extends Controller } /** + * @param Request $request + * * @return View */ - public function create() + public function create(Request $request) { // put previous url in session if not redirect from store (not "create another"). if (session('budgets.create.fromStore') !== true) { - Session::put('budgets.create.url', URL::previous()); + $this->rememberPreviousUri('budgets.create.uri'); } - Session::forget('budgets.create.fromStore'); - Session::flash('gaEventCategory', 'budgets'); - Session::flash('gaEventAction', 'create'); + $request->session()->forget('budgets.create.fromStore'); + $request->session()->flash('gaEventCategory', 'budgets'); + $request->session()->flash('gaEventAction', 'create'); $subTitle = (string)trans('firefly.create_new_budget'); return view('budgets.create', compact('subTitle')); @@ -109,59 +109,52 @@ class BudgetController extends Controller * * @return View */ - public function delete(Budget $budget) + public function delete(Request $request, Budget $budget) { $subTitle = trans('firefly.delete_budget', ['name' => $budget->name]); // put previous url in session - Session::put('budgets.delete.url', URL::previous()); - Session::flash('gaEventCategory', 'budgets'); - Session::flash('gaEventAction', 'delete'); + $this->rememberPreviousUri('budgets.delete.uri'); + $request->session()->flash('gaEventCategory', 'budgets'); + $request->session()->flash('gaEventAction', 'delete'); return view('budgets.delete', compact('budget', 'subTitle')); } /** - * @param Budget $budget + * @param Request $request + * @param Budget $budget * - * @return \Illuminate\Http\RedirectResponse + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function destroy(Budget $budget) + public function destroy(Request $request, Budget $budget) { - $name = $budget->name; - $budgetId = $budget->id; + $name = $budget->name; $this->repository->destroy($budget); - - - Session::flash('success', strval(trans('firefly.deleted_budget', ['name' => e($name)]))); + $request->session()->flash('success', strval(trans('firefly.deleted_budget', ['name' => e($name)]))); Preferences::mark(); - $uri = session('budgets.delete.url'); - if (!(strpos($uri, sprintf('budgets/show/%s', $budgetId)) === false)) { - // uri would point back to budget - $uri = route('budgets.index'); - } - - return redirect($uri); + return redirect($this->getPreviousUri('budgets.delete.uri')); } /** - * @param Budget $budget + * @param Request $request + * @param Budget $budget * * @return View */ - public function edit(Budget $budget) + public function edit(Request $request, Budget $budget) { $subTitle = trans('firefly.edit_budget', ['name' => $budget->name]); // put previous url in session if not redirect from store (not "return_to_edit"). if (session('budgets.edit.fromUpdate') !== true) { - Session::put('budgets.edit.url', URL::previous()); + $this->rememberPreviousUri('budgets.edit.uri'); } - Session::forget('budgets.edit.fromUpdate'); - Session::flash('gaEventCategory', 'budgets'); - Session::flash('gaEventAction', 'edit'); + $request->session()->forget('budgets.edit.fromUpdate'); + $request->session()->flash('gaEventCategory', 'budgets'); + $request->session()->flash('gaEventAction', 'edit'); return view('budgets.edit', compact('budget', 'subTitle')); @@ -212,7 +205,7 @@ class BudgetController extends Controller // collector /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAllAssetAccounts()->setRange($start, $end)->setLimit($pageSize)->setPage($page)->withoutBudget(); $journals = $collector->getPaginatedJournals(); $journals->setPath('/budgets/list/noBudget'); @@ -253,7 +246,7 @@ class BudgetController extends Controller $repetition = null; // collector: /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAllAssetAccounts()->setRange($start, $end)->setBudget($budget)->setLimit($pageSize)->setPage($page)->withCategoryInformation(); $journals = $collector->getPaginatedJournals(); $journals->setPath('/budgets/show/' . $budget->id); @@ -278,9 +271,9 @@ class BudgetController extends Controller throw new FireflyException('This budget limit is not part of this budget.'); } - $page = intval($request->get('page')) == 0 ? 1 : intval($request->get('page')); - $pageSize = intval(Preferences::get('transactionPageSize', 50)->data); - $subTitle = trans( + $page = intval($request->get('page')) == 0 ? 1 : intval($request->get('page')); + $pageSize = intval(Preferences::get('transactionPageSize', 50)->data); + $subTitle = trans( 'firefly.budget_in_period', [ 'name' => $budget->name, 'start' => $budgetLimit->start_date->formatLocalized($this->monthAndDayFormat), @@ -290,7 +283,7 @@ class BudgetController extends Controller // collector: /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAllAssetAccounts()->setRange($budgetLimit->start_date, $budgetLimit->end_date) ->setBudget($budget)->setLimit($pageSize)->setPage($page)->withCategoryInformation(); $journals = $collector->getPaginatedJournals(); @@ -315,19 +308,17 @@ class BudgetController extends Controller $data = $request->getBudgetData(); $budget = $this->repository->store($data); - Session::flash('success', strval(trans('firefly.stored_new_budget', ['name' => e($budget->name)]))); + $request->session()->flash('success', strval(trans('firefly.stored_new_budget', ['name' => e($budget->name)]))); Preferences::mark(); if (intval($request->get('create_another')) === 1) { // set value so create routine will not overwrite URL: - Session::put('budgets.create.fromStore', true); + $request->session()->put('budgets.create.fromStore', true); return redirect(route('budgets.create'))->withInput(); } - // redirect to previous URL. - return redirect(session('budgets.create.url')); - + return redirect($this->getPreviousUri('budgets.create.uri')); } /** @@ -341,19 +332,17 @@ class BudgetController extends Controller $data = $request->getBudgetData(); $this->repository->update($budget, $data); - Session::flash('success', strval(trans('firefly.updated_budget', ['name' => e($budget->name)]))); + $request->session()->flash('success', strval(trans('firefly.updated_budget', ['name' => e($budget->name)]))); Preferences::mark(); if (intval($request->get('return_to_edit')) === 1) { // set value so edit routine will not overwrite URL: - Session::put('budgets.edit.fromUpdate', true); + $request->session()->put('budgets.edit.fromUpdate', true); return redirect(route('budgets.edit', [$budget->id]))->withInput(['return_to_edit' => 1]); } - // redirect to previous URL. - return redirect(session('budgets.edit.url')); - + return redirect($this->getPreviousUri('budgets.edit.uri')); } /** diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 2a52505818..24a391ec4b 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -25,8 +25,6 @@ use Illuminate\Http\Request; use Illuminate\Support\Collection; use Navigation; use Preferences; -use Session; -use URL; use View; /** @@ -56,80 +54,78 @@ class CategoryController extends Controller } /** + * @param Request $request + * * @return View */ - public function create() + public function create(Request $request) { if (session('categories.create.fromStore') !== true) { - Session::put('categories.create.url', URL::previous()); + $this->rememberPreviousUri('categories.create.uri'); } - Session::forget('categories.create.fromStore'); - Session::flash('gaEventCategory', 'categories'); - Session::flash('gaEventAction', 'create'); + $request->session()->forget('categories.create.fromStore'); + $request->session()->flash('gaEventCategory', 'categories'); + $request->session()->flash('gaEventAction', 'create'); $subTitle = trans('firefly.create_new_category'); return view('categories.create', compact('subTitle')); } /** + * @param Request $request * @param Category $category * * @return View */ - public function delete(Category $category) + public function delete(Request $request, Category $category) { $subTitle = trans('firefly.delete_category', ['name' => $category->name]); // put previous url in session - Session::put('categories.delete.url', URL::previous()); - Session::flash('gaEventCategory', 'categories'); - Session::flash('gaEventAction', 'delete'); + $this->rememberPreviousUri('categories.delete.uri'); + $request->session()->flash('gaEventCategory', 'categories'); + $request->session()->flash('gaEventAction', 'delete'); return view('categories.delete', compact('category', 'subTitle')); } /** + * @param Request $request * @param CategoryRepositoryInterface $repository * @param Category $category * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function destroy(CategoryRepositoryInterface $repository, Category $category) + public function destroy(Request $request, CategoryRepositoryInterface $repository, Category $category) { - $name = $category->name; - $categoryId = $category->id; + $name = $category->name; $repository->destroy($category); - Session::flash('success', strval(trans('firefly.deleted_category', ['name' => e($name)]))); + $request->session()->flash('success', strval(trans('firefly.deleted_category', ['name' => e($name)]))); Preferences::mark(); - $uri = session('categories.delete.url'); - if (!(strpos($uri, sprintf('categories/show/%s', $categoryId)) === false)) { - // uri would point back to category - $uri = route('categories.index'); - } - - return redirect($uri); + return redirect($this->getPreviousUri('categories.delete.uri')); } /** + * @param Request $request * @param Category $category * * @return View */ - public function edit(Category $category) + public function edit(Request $request, Category $category) { $subTitle = trans('firefly.edit_category', ['name' => $category->name]); // put previous url in session if not redirect from store (not "return_to_edit"). if (session('categories.edit.fromUpdate') !== true) { - Session::put('categories.edit.url', URL::previous()); + $this->rememberPreviousUri('categories.edit.uri'); } - Session::forget('categories.edit.fromUpdate'); - Session::flash('gaEventCategory', 'categories'); - Session::flash('gaEventAction', 'edit'); + $request->session()->forget('categories.edit.fromUpdate'); + $request->session()->flash('gaEventCategory', 'categories'); + $request->session()->flash('gaEventAction', 'edit'); return view('categories.edit', compact('category', 'subTitle')); @@ -165,7 +161,7 @@ class CategoryController extends Controller // new collector: /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAllAssetAccounts()->setRange($start, $end)->withoutCategory();//->groupJournals(); $journals = $collector->getJournals(); $subTitle = trans( @@ -277,11 +273,11 @@ class CategoryController extends Controller $data = $request->getCategoryData(); $category = $repository->store($data); - Session::flash('success', strval(trans('firefly.stored_category', ['name' => e($category->name)]))); + $request->session()->flash('success', strval(trans('firefly.stored_category', ['name' => e($category->name)]))); Preferences::mark(); if (intval($request->get('create_another')) === 1) { - Session::put('categories.create.fromStore', true); + $request->session()->put('categories.create.fromStore', true); return redirect(route('categories.create'))->withInput(); } @@ -302,18 +298,16 @@ class CategoryController extends Controller $data = $request->getCategoryData(); $repository->update($category, $data); - Session::flash('success', strval(trans('firefly.updated_category', ['name' => e($category->name)]))); + $request->session()->flash('success', strval(trans('firefly.updated_category', ['name' => e($category->name)]))); Preferences::mark(); if (intval($request->get('return_to_edit')) === 1) { - Session::put('categories.edit.fromUpdate', true); + $request->session()->put('categories.edit.fromUpdate', true); return redirect(route('categories.edit', [$category->id])); } - // redirect to previous URL. - return redirect(session('categories.edit.url')); - + return redirect($this->getPreviousUri('categories.edit.uri')); } /** diff --git a/app/Http/Controllers/Chart/BudgetController.php b/app/Http/Controllers/Chart/BudgetController.php index 0a8fe543cf..cf99421aee 100644 --- a/app/Http/Controllers/Chart/BudgetController.php +++ b/app/Http/Controllers/Chart/BudgetController.php @@ -416,7 +416,7 @@ class BudgetController extends Controller { // collector /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $types = [TransactionType::WITHDRAWAL]; $collector->setAllAssetAccounts()->setTypes($types)->setRange($start, $end)->withoutBudget(); $journals = $collector->getJournals(); diff --git a/app/Http/Controllers/Chart/BudgetReportController.php b/app/Http/Controllers/Chart/BudgetReportController.php index d131f8a661..d570eae6b8 100644 --- a/app/Http/Controllers/Chart/BudgetReportController.php +++ b/app/Http/Controllers/Chart/BudgetReportController.php @@ -80,7 +80,6 @@ class BudgetReportController extends Controller $helper = app(MetaPieChartInterface::class); $helper->setAccounts($accounts); $helper->setBudgets($budgets); - $helper->setUser(auth()->user()); $helper->setStart($start); $helper->setEnd($end); $helper->setCollectOtherObjects(intval($others) === 1); @@ -106,7 +105,6 @@ class BudgetReportController extends Controller $helper = app(MetaPieChartInterface::class); $helper->setAccounts($accounts); $helper->setBudgets($budgets); - $helper->setUser(auth()->user()); $helper->setStart($start); $helper->setEnd($end); $helper->setCollectOtherObjects(intval($others) === 1); @@ -239,7 +237,7 @@ class BudgetReportController extends Controller private function getExpenses(Collection $accounts, Collection $budgets, Carbon $start, Carbon $end): Collection { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) ->setBudgets($budgets)->withOpposingAccount()->disableFilter(); $accountIds = $accounts->pluck('id')->toArray(); diff --git a/app/Http/Controllers/Chart/CategoryReportController.php b/app/Http/Controllers/Chart/CategoryReportController.php index e156becd7e..94f6cfb370 100644 --- a/app/Http/Controllers/Chart/CategoryReportController.php +++ b/app/Http/Controllers/Chart/CategoryReportController.php @@ -80,7 +80,6 @@ class CategoryReportController extends Controller $helper = app(MetaPieChartInterface::class); $helper->setAccounts($accounts); $helper->setCategories($categories); - $helper->setUser(auth()->user()); $helper->setStart($start); $helper->setEnd($end); $helper->setCollectOtherObjects(intval($others) === 1); @@ -105,7 +104,6 @@ class CategoryReportController extends Controller $helper = app(MetaPieChartInterface::class); $helper->setAccounts($accounts); $helper->setCategories($categories); - $helper->setUser(auth()->user()); $helper->setStart($start); $helper->setEnd($end); $helper->setCollectOtherObjects(intval($others) === 1); @@ -130,7 +128,6 @@ class CategoryReportController extends Controller $helper = app(MetaPieChartInterface::class); $helper->setAccounts($accounts); $helper->setCategories($categories); - $helper->setUser(auth()->user()); $helper->setStart($start); $helper->setEnd($end); $helper->setCollectOtherObjects(intval($others) === 1); @@ -156,7 +153,6 @@ class CategoryReportController extends Controller $helper = app(MetaPieChartInterface::class); $helper->setAccounts($accounts); $helper->setCategories($categories); - $helper->setUser(auth()->user()); $helper->setStart($start); $helper->setEnd($end); $helper->setCollectOtherObjects(intval($others) === 1); @@ -284,7 +280,7 @@ class CategoryReportController extends Controller private function getExpenses(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): Collection { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL, TransactionType::TRANSFER]) ->setCategories($categories)->withOpposingAccount()->disableFilter(); $accountIds = $accounts->pluck('id')->toArray(); @@ -305,7 +301,7 @@ class CategoryReportController extends Controller private function getIncome(Collection $accounts, Collection $categories, Carbon $start, Carbon $end): Collection { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($accounts)->setRange($start, $end)->setTypes([TransactionType::DEPOSIT, TransactionType::TRANSFER]) ->setCategories($categories)->withOpposingAccount(); $accountIds = $accounts->pluck('id')->toArray(); diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 0904e4bbbc..bbf6cb51d5 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -23,6 +23,7 @@ use Illuminate\Foundation\Bus\DispatchesJobs; use Illuminate\Foundation\Validation\ValidatesRequests; use Illuminate\Routing\Controller as BaseController; use Session; +use URL; use View; /** @@ -56,7 +57,6 @@ class Controller extends BaseController View::share('DEMO_PASSWORD', env('DEMO_PASSWORD', '')); // translations: - $this->middleware( function ($request, $next) { $this->monthFormat = (string)trans('config.month'); @@ -69,6 +69,29 @@ class Controller extends BaseController } + /** + * Functionality: + * + * - If the $identifier contains the word "delete" then a remembered uri with the text "/show/" in it will not be returned but instead the index (/) + * will be returned. + * - If the remembered uri contains "javascript/" the remembered uri will not be returned but instead the index (/) will be returned. + * + * @param string $identifier + * + * @return string + */ + protected function getPreviousUri(string $identifier): string + { + $uri = strval(session($identifier)); + if (!(strpos($identifier, 'delete') === false) && !(strpos($uri, '/show/') === false)) { + $uri = route('index'); + } + if (!(strpos($uri, 'javascript') === false)) { + $uri = route('index'); + } + + return $uri; + } /** * @param TransactionJournal $journal @@ -102,4 +125,12 @@ class Controller extends BaseController return redirect(route('index')); } + /** + * @param string $identifier + */ + protected function rememberPreviousUri(string $identifier) + { + Session::put($identifier, URL::previous()); + } + } diff --git a/app/Http/Controllers/CurrencyController.php b/app/Http/Controllers/CurrencyController.php index 2b01c3043c..d38e964c62 100644 --- a/app/Http/Controllers/CurrencyController.php +++ b/app/Http/Controllers/CurrencyController.php @@ -17,10 +17,9 @@ use Cache; use FireflyIII\Http\Requests\CurrencyFormRequest; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; +use Illuminate\Http\Request; use Log; use Preferences; -use Session; -use URL; use View; /** @@ -53,34 +52,35 @@ class CurrencyController extends Controller /** * @return View */ - public function create() + public function create(Request $request) { $subTitleIcon = 'fa-plus'; $subTitle = trans('firefly.create_currency'); // put previous url in session if not redirect from store (not "create another"). if (session('currencies.create.fromStore') !== true) { - Session::put('currencies.create.url', URL::previous()); + $this->rememberPreviousUri('currencies.create.uri'); } - Session::forget('currencies.create.fromStore'); - Session::flash('gaEventCategory', 'currency'); - Session::flash('gaEventAction', 'create'); + $request->session()->forget('currencies.create.fromStore'); + $request->session()->flash('gaEventCategory', 'currency'); + $request->session()->flash('gaEventAction', 'create'); return view('currencies.create', compact('subTitleIcon', 'subTitle')); } /** + * @param Request $request * @param TransactionCurrency $currency * - * @return \Illuminate\Http\RedirectResponse + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function defaultCurrency(TransactionCurrency $currency) + public function defaultCurrency(Request $request, TransactionCurrency $currency) { Preferences::set('currencyPreference', $currency->code); Preferences::mark(); - Session::flash('success', trans('firefly.new_default_currency', ['name' => $currency->name])); + $request->session()->flash('success', trans('firefly.new_default_currency', ['name' => $currency->name])); Cache::forget('FFCURRENCYSYMBOL'); Cache::forget('FFCURRENCYCODE'); @@ -95,19 +95,19 @@ class CurrencyController extends Controller * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|View */ - public function delete(CurrencyRepositoryInterface $repository, TransactionCurrency $currency) + public function delete(Request $request, CurrencyRepositoryInterface $repository, TransactionCurrency $currency) { if (!$repository->canDeleteCurrency($currency)) { - Session::flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name])); + $request->session()->flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name])); return redirect(route('currencies.index')); } // put previous url in session - Session::put('currencies.delete.url', URL::previous()); - Session::flash('gaEventCategory', 'currency'); - Session::flash('gaEventAction', 'delete'); + $this->rememberPreviousUri('currencies.delete.uri'); + $request->session()->flash('gaEventCategory', 'currency'); + $request->session()->flash('gaEventAction', 'delete'); $subTitle = trans('form.delete_currency', ['name' => $currency->name]); @@ -120,26 +120,27 @@ class CurrencyController extends Controller * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function destroy(CurrencyRepositoryInterface $repository, TransactionCurrency $currency) + public function destroy(Request $request, CurrencyRepositoryInterface $repository, TransactionCurrency $currency) { if (!$repository->canDeleteCurrency($currency)) { - Session::flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name])); + $request->session()->flash('error', trans('firefly.cannot_delete_currency', ['name' => $currency->name])); return redirect(route('currencies.index')); } $repository->destroy($currency); - Session::flash('success', trans('firefly.deleted_currency', ['name' => $currency->name])); + $request->session()->flash('success', trans('firefly.deleted_currency', ['name' => $currency->name])); - return redirect(session('currencies.delete.url')); + return redirect($this->getPreviousUri('currencies.delete.uri')); } /** + * @param Request $request * @param TransactionCurrency $currency * * @return View */ - public function edit(TransactionCurrency $currency) + public function edit(Request $request, TransactionCurrency $currency) { $subTitleIcon = 'fa-pencil'; $subTitle = trans('breadcrumbs.edit_currency', ['name' => $currency->name]); @@ -147,29 +148,30 @@ class CurrencyController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('currencies.edit.fromUpdate') !== true) { - Session::put('currencies.edit.url', URL::previous()); + $this->rememberPreviousUri('currencies.edit.uri'); } - Session::forget('currencies.edit.fromUpdate'); - Session::flash('gaEventCategory', 'currency'); - Session::flash('gaEventAction', 'edit'); + $request->session()->forget('currencies.edit.fromUpdate'); + $request->session()->flash('gaEventCategory', 'currency'); + $request->session()->flash('gaEventAction', 'edit'); return view('currencies.edit', compact('currency', 'subTitle', 'subTitleIcon')); } /** + * @param Request $request * @param CurrencyRepositoryInterface $repository * * @return View */ - public function index(CurrencyRepositoryInterface $repository) + public function index(Request $request, CurrencyRepositoryInterface $repository) { $currencies = $repository->get(); $defaultCurrency = $repository->getCurrencyByPreference(Preferences::get('currencyPreference', config('firefly.default_currency', 'EUR'))); if (!auth()->user()->hasRole('owner')) { - Session::flash('info', trans('firefly.ask_site_owner', ['owner' => env('SITE_OWNER')])); + $request->session()->flash('info', trans('firefly.ask_site_owner', ['owner' => env('SITE_OWNER')])); } @@ -188,23 +190,20 @@ class CurrencyController extends Controller if (!auth()->user()->hasRole('owner')) { Log::error('User ' . auth()->user()->id . ' is not admin, but tried to store a currency.'); - return redirect(session('currencies.create.url')); + return redirect($this->getPreviousUri('currencies.create.uri')); } $data = $request->getCurrencyData(); $currency = $repository->store($data); - Session::flash('success', trans('firefly.created_currency', ['name' => $currency->name])); + $request->session()->flash('success', trans('firefly.created_currency', ['name' => $currency->name])); if (intval($request->get('create_another')) === 1) { - Session::put('currencies.create.fromStore', true); + $request->session()->put('currencies.create.fromStore', true); return redirect(route('currencies.create'))->withInput(); } - // redirect to previous URL. - return redirect(session('currencies.create.url')); - - + return redirect($this->getPreviousUri('currencies.create.uri')); } /** @@ -220,18 +219,16 @@ class CurrencyController extends Controller if (auth()->user()->hasRole('owner')) { $currency = $repository->update($currency, $data); } - Session::flash('success', trans('firefly.updated_currency', ['name' => $currency->name])); + $request->session()->flash('success', trans('firefly.updated_currency', ['name' => $currency->name])); Preferences::mark(); if (intval($request->get('return_to_edit')) === 1) { - Session::put('currencies.edit.fromUpdate', true); + $request->session()->put('currencies.edit.fromUpdate', true); return redirect(route('currencies.edit', [$currency->id])); } - // redirect to previous URL. - return redirect(session('currencies.edit.url')); - + return redirect($this->getPreviousUri('currencies.edit.uri')); } } diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index 1ace8118c1..823c82e928 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -150,7 +150,8 @@ class ExportController extends Controller $jobs->changeStatus($job, 'export_status_make_exporter'); /** @var ProcessorInterface $processor */ - $processor = app(ProcessorInterface::class, [$settings]); + $processor = app(ProcessorInterface::class); + $processor->setSettings($settings); /* * Collect journals: diff --git a/app/Http/Controllers/HelpController.php b/app/Http/Controllers/HelpController.php index 24d2d75254..82846210cf 100644 --- a/app/Http/Controllers/HelpController.php +++ b/app/Http/Controllers/HelpController.php @@ -58,7 +58,8 @@ class HelpController extends Controller return Response::json($content); } - $content = $help->getFromGithub($language, $route); + $content = $help->getFromGithub($language, $route); + $notYourLanguage = '

' . strval(trans('firefly.help_may_not_be_your_language')) . '

'; // get backup language content (try English): if (strlen($content) === 0) { @@ -68,12 +69,11 @@ class HelpController extends Controller $content = $help->getFromCache($route, $language); } if (!$help->inCache($route, $language)) { - $content = $help->getFromGithub($language, $route); - $content = '

' . strval(trans('firefly.help_may_not_be_your_language')) . '

' . $content; + $content = trim($notYourLanguage . $help->getFromGithub($language, $route)); } } - if (strlen($content) === 0) { + if ($content === $notYourLanguage) { $content = '

' . strval(trans('firefly.route_has_no_help')) . '

'; } diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index 9263a25937..460a3e98cd 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -17,15 +17,12 @@ use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Models\AccountType; -use FireflyIII\Models\Tag; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Bill\BillRepositoryInterface; -use FireflyIII\Repositories\Tag\TagRepositoryInterface; use Illuminate\Http\Request; use Illuminate\Support\Collection; use Log; use Preferences; -use Route; use Session; use View; @@ -86,30 +83,14 @@ class HomeController extends Controller } /** - * @param TagRepositoryInterface $repository + * @param Request $request * * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ - public function flush(TagRepositoryInterface $repository) + public function flush(Request $request) { - Preferences::mark(); - - // get all tags. - // update all counts: - $tags = $repository->get(); - - /** @var Tag $tag */ - foreach ($tags as $tag) { - foreach ($tag->transactionJournals()->get() as $journal) { - $count = $journal->tags()->count(); - $journal->tag_count = $count; - $journal->save(); - } - } - Session::forget(['start', 'end', 'viewRange', 'range', 'is_custom_range']); - - Session::clear(); + $request->session()->forget(['start', 'end', '_previous', 'viewRange', 'range', 'is_custom_range']); Artisan::call('cache:clear'); return redirect(route('index')); @@ -159,74 +140,6 @@ class HomeController extends Controller ); } - /** - * Display a list of named routes. Excludes some that cannot be "shown". This method - * is used to generate help files (down the road). - */ - public function routes() - { - // these routes are not relevant for the help pages: - $ignore = [ - // login and two-factor routes: - 'login', - 'registe', - 'password.rese', - 'logout', - 'two-fac', - 'lost-two', - // test troutes - 'test-flash', - 'all-routes', - // json routes - 'json.', - // routes that point to modals or that redirect immediately. - 'piggy-banks.add', - 'piggy-banks.remove', - 'rules.rule.up', - 'attachments.download', - 'bills.rescan', - 'rules.rule.down', - 'rules.rule-group.up', - 'rules.rule-group.down', - 'popup.', - 'error', - 'flush', - //'preferences.', - 'admin.users.domains.block-', - 'help.', - // ajax routes: - 'import.json', - // charts: - 'chart.', - // report data: - 'report-data.', - - // others: - 'debugbar', - 'attachments.preview', - 'budgets.income', - 'currencies.default', - - - ]; - $routes = Route::getRoutes(); - $return = '
';
-
-        /** @var \Illuminate\Routing\Route $route */
-        foreach ($routes as $route) {
-            $name    = $route->getName();
-            $methods = $route->getMethods();
-
-            if (!is_null($name) && strlen($name) > 0 && in_array('GET', $methods) && !$this->startsWithAny($ignore, $name)) {
-                $return .= sprintf('touch %s.md', $name) . "\n";
-
-            }
-        }
-        $return .= '

'; - - return $return; - } - /** * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector */ @@ -240,21 +153,4 @@ class HomeController extends Controller return redirect(route('home')); } - /** - * @param array $array - * @param string $needle - * - * @return bool - */ - private function startsWithAny(array $array, string $needle): bool - { - foreach ($array as $entry) { - if ((substr($needle, 0, strlen($entry)) === $entry)) { - return true; - } - } - - return false; - } - } diff --git a/app/Http/Controllers/JavascriptController.php b/app/Http/Controllers/JavascriptController.php index 67c3d268d7..6e63e57a43 100644 --- a/app/Http/Controllers/JavascriptController.php +++ b/app/Http/Controllers/JavascriptController.php @@ -13,6 +13,7 @@ namespace FireflyIII\Http\Controllers; use Amount; use FireflyIII\Exceptions\FireflyException; +use Illuminate\Http\Request; use Navigation; use Preferences; use Session; @@ -28,7 +29,7 @@ class JavascriptController extends Controller /** * */ - public function variables() + public function variables(Request $request) { $picker = $this->getDateRangePicker(); $start = Session::get('start'); @@ -52,6 +53,7 @@ class JavascriptController extends Controller 'localeconv' => $localeconv, 'language' => $lang, ]; + $request->session()->keep(['two-factor-secret']); return response() ->view('javascript.variables', $data, 200) @@ -129,4 +131,4 @@ class JavascriptController extends Controller ]; } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php index 47357c5bc0..b74905c682 100644 --- a/app/Http/Controllers/PiggyBankController.php +++ b/app/Http/Controllers/PiggyBankController.php @@ -27,7 +27,6 @@ use Preferences; use Response; use Session; use Steam; -use URL; use View; /** @@ -116,7 +115,7 @@ class PiggyBankController extends Controller // put previous url in session if not redirect from store (not "create another"). if (session('piggy-banks.create.fromStore') !== true) { - Session::put('piggy-banks.create.url', URL::previous()); + $this->rememberPreviousUri('piggy-banks.create.uri'); } Session::forget('piggy-banks.create.fromStore'); Session::flash('gaEventCategory', 'piggy-banks'); @@ -135,7 +134,7 @@ class PiggyBankController extends Controller $subTitle = trans('firefly.delete_piggy_bank', ['name' => $piggyBank->name]); // put previous url in session - Session::put('piggy-banks.delete.url', URL::previous()); + $this->rememberPreviousUri('piggy-banks.delete.uri'); Session::flash('gaEventCategory', 'piggy-banks'); Session::flash('gaEventAction', 'delete'); @@ -152,16 +151,9 @@ class PiggyBankController extends Controller { Session::flash('success', strval(trans('firefly.deleted_piggy_bank', ['name' => e($piggyBank->name)]))); Preferences::mark(); - $piggyBankId = $piggyBank->id; $repository->destroy($piggyBank); - $uri = session('piggy-banks.delete.url'); - if (!(strpos($uri, sprintf('piggy-banks/show/%s', $piggyBankId)) === false)) { - // uri would point back to piggy bank - $uri = route('piggy-banks.index'); - } - - return redirect($uri); + return redirect($this->getPreviousUri('piggy-banks.delete.uri')); } /** @@ -197,7 +189,7 @@ class PiggyBankController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('piggy-banks.edit.fromUpdate') !== true) { - Session::put('piggy-banks.edit.url', URL::previous()); + $this->rememberPreviousUri('piggy-banks.edit.uri'); } Session::forget('piggy-banks.edit.fromUpdate'); @@ -404,9 +396,7 @@ class PiggyBankController extends Controller return redirect(route('piggy-banks.create'))->withInput(); } - - // redirect to previous URL. - return redirect(session('piggy-banks.create.url')); + return redirect($this->getPreviousUri('piggy-banks.edit.uri')); } /** @@ -430,12 +420,6 @@ class PiggyBankController extends Controller return redirect(route('piggy-banks.edit', [$piggyBank->id])); } - - // redirect to previous URL. - return redirect(session('piggy-banks.edit.url')); - - + return redirect($this->getPreviousUri('piggy-banks.edit.uri')); } - - } diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php index 0f436dc962..a2f3505923 100644 --- a/app/Http/Controllers/Popup/ReportController.php +++ b/app/Http/Controllers/Popup/ReportController.php @@ -103,7 +103,7 @@ class ReportController extends Controller switch (true) { case ($role === BalanceLine::ROLE_DEFAULTROLE && !is_null($budget->id)): /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector ->setAccounts(new Collection([$account])) ->setRange($attributes['startDate'], $attributes['endDate']) @@ -114,7 +114,7 @@ class ReportController extends Controller case ($role === BalanceLine::ROLE_DEFAULTROLE && is_null($budget->id)): $budget->name = strval(trans('firefly.no_budget')); /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector ->setAccounts(new Collection([$account])) ->setTypes($types) @@ -124,7 +124,7 @@ class ReportController extends Controller break; case ($role === BalanceLine::ROLE_DIFFROLE): /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector ->setAccounts(new Collection([$account])) ->setTypes($types) @@ -169,7 +169,7 @@ class ReportController extends Controller $repository = app(BudgetRepositoryInterface::class); $budget = $repository->find(intval($attributes['budgetId'])); /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector ->setAccounts($attributes['accounts']) @@ -203,7 +203,7 @@ class ReportController extends Controller $category = $repository->find(intval($attributes['categoryId'])); $types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER]; /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts($attributes['accounts'])->setTypes($types) ->setRange($attributes['startDate'], $attributes['endDate']) ->setCategory($category); @@ -230,7 +230,7 @@ class ReportController extends Controller $account = $repository->find(intval($attributes['accountId'])); $types = [TransactionType::WITHDRAWAL, TransactionType::TRANSFER]; /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts(new Collection([$account]))->setRange($attributes['startDate'], $attributes['endDate'])->setTypes($types); $journals = $collector->getJournals(); $report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report @@ -266,7 +266,7 @@ class ReportController extends Controller $account = $repository->find(intval($attributes['accountId'])); $types = [TransactionType::DEPOSIT, TransactionType::TRANSFER]; /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); $collector->setAccounts(new Collection([$account]))->setRange($attributes['startDate'], $attributes['endDate'])->setTypes($types); $journals = $collector->getJournals(); $report = $attributes['accounts']->pluck('id')->toArray(); // accounts used in this report diff --git a/app/Http/Controllers/PreferencesController.php b/app/Http/Controllers/PreferencesController.php index f4bd94c4b5..4373d61204 100644 --- a/app/Http/Controllers/PreferencesController.php +++ b/app/Http/Controllers/PreferencesController.php @@ -56,9 +56,9 @@ class PreferencesController extends Controller { $domain = $this->getDomain(); /** @noinspection PhpMethodParametersCountMismatchInspection */ - $secret = $google2fa->generateSecretKey(16, auth()->user()->id); + $secret = $google2fa->generateSecretKey(32, auth()->user()->id); Session::flash('two-factor-secret', $secret); - $image = $google2fa->getQRCodeInline('Firefly III at ' . $domain, null, $secret, 150); + $image = $google2fa->getQRCodeInline('Firefly III at ' . $domain, auth()->user()->email, $secret, 150); return view('preferences.code', compact('image')); diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index aebec981cb..e2f7516dd8 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -52,6 +52,10 @@ class ProfileController extends Controller */ public function changePassword() { + if (intval(getenv('SANDSTORM')) === 1) { + return view('error')->with('message', strval(trans('firefly.sandstorm_not_available'))); + } + if (auth()->user()->hasRole('demo')) { Session::flash('info', strval(trans('firefly.cannot_change_demo'))); @@ -70,6 +74,10 @@ class ProfileController extends Controller */ public function deleteAccount() { + if (intval(getenv('SANDSTORM')) === 1) { + return view('error')->with('message', strval(trans('firefly.sandstorm_not_available'))); + } + if (auth()->user()->hasRole('demo')) { Session::flash('info', strval(trans('firefly.cannot_delete_demo'))); @@ -103,6 +111,10 @@ class ProfileController extends Controller */ public function postChangePassword(ProfileFormRequest $request, UserRepositoryInterface $repository) { + if (intval(getenv('SANDSTORM')) === 1) { + return view('error')->with('message', strval(trans('firefly.sandstorm_not_available'))); + } + if (auth()->user()->hasRole('demo')) { Session::flash('info', strval(trans('firefly.cannot_change_demo'))); @@ -139,6 +151,10 @@ class ProfileController extends Controller */ public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request) { + if (intval(getenv('SANDSTORM')) === 1) { + return view('error')->with('message', strval(trans('firefly.sandstorm_not_available'))); + } + if (auth()->user()->hasRole('demo')) { Session::flash('info', strval(trans('firefly.cannot_delete_demo'))); diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index e2348dc6d8..a3ac8ab74a 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -19,9 +19,11 @@ use FireflyIII\Generator\Report\ReportGeneratorFactory; use FireflyIII\Helpers\Report\ReportHelperInterface; use FireflyIII\Http\Requests\ReportFormRequest; use FireflyIII\Models\AccountType; +use FireflyIII\Models\Tag; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; +use FireflyIII\Repositories\Tag\TagRepositoryInterface; use Illuminate\Http\RedirectResponse; use Illuminate\Support\Collection; use Preferences; @@ -238,6 +240,9 @@ class ReportController extends Controller case 'budget': $result = $this->budgetReportOptions(); break; + case 'tag': + $result = $this->tagReportOptions(); + break; } return Response::json(['html' => $result]); @@ -258,6 +263,7 @@ class ReportController extends Controller $accounts = join(',', $request->getAccountList()->pluck('id')->toArray()); $categories = join(',', $request->getCategoryList()->pluck('id')->toArray()); $budgets = join(',', $request->getBudgetList()->pluck('id')->toArray()); + $tags = join(',', $request->getTagList()->pluck('tag')->toArray()); if ($request->getAccountList()->count() === 0) { Session::flash('error', trans('firefly.select_more_than_one_account')); @@ -277,6 +283,12 @@ class ReportController extends Controller return redirect(route('reports.index')); } + if ($request->getTagList()->count() === 0 && $reportType === 'tag') { + Session::flash('error', trans('firefly.select_more_than_one_tag')); + + return redirect(route('reports.index')); + } + if ($end < $start) { return view('error')->with('message', trans('firefly.end_after_start_date')); } @@ -301,11 +313,50 @@ class ReportController extends Controller case 'budget': $uri = route('reports.report.budget', [$accounts, $budgets, $start, $end]); break; + case 'tag': + $uri = route('reports.report.tag', [$accounts, $tags, $start, $end]); + break; } return redirect($uri); } + /** + * @param Collection $accounts + * @param Collection $tags + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function tagReport(Collection $accounts, Collection $tags, Carbon $start, Carbon $end) + { + if ($end < $start) { + return view('error')->with('message', trans('firefly.end_after_start_date')); + } + if ($start < session('first')) { + $start = session('first'); + } + + View::share( + 'subTitle', trans( + 'firefly.report_tag', + [ + 'start' => $start->formatLocalized($this->monthFormat), + 'end' => $end->formatLocalized($this->monthFormat), + ] + ) + ); + + $generator = ReportGeneratorFactory::reportGenerator('Tag', $start, $end); + $generator->setAccounts($accounts); + $generator->setTags($tags); + $result = $generator->generate(); + + return $result; + + } + /** * @return string */ @@ -341,4 +392,22 @@ class ReportController extends Controller { return view('reports.options.no-options')->render(); } + + /** + * @return string + */ + private function tagReportOptions(): string + { + /** @var TagRepositoryInterface $repository */ + $repository = app(TagRepositoryInterface::class); + $tags = $repository->get()->sortBy( + function (Tag $tag) { + return $tag->tag; + } + ); + $result = view('reports.options.tag', compact('tags'))->render(); + + return $result; + + } } diff --git a/app/Http/Controllers/RuleController.php b/app/Http/Controllers/RuleController.php index 8e0e466933..e20830a819 100644 --- a/app/Http/Controllers/RuleController.php +++ b/app/Http/Controllers/RuleController.php @@ -26,7 +26,6 @@ use Illuminate\Http\Request; use Preferences; use Response; use Session; -use URL; use View; /** @@ -88,7 +87,7 @@ class RuleController extends Controller // put previous url in session if not redirect from store (not "create another"). if (session('rules.create.fromStore') !== true) { - Session::put('rules.create.url', URL::previous()); + $this->rememberPreviousUri('rules.create.uri'); } Session::forget('rules.create.fromStore'); Session::flash('gaEventCategory', 'rules'); @@ -111,7 +110,7 @@ class RuleController extends Controller $subTitle = trans('firefly.delete_rule', ['title' => $rule->title]); // put previous url in session - Session::put('rules.delete.url', URL::previous()); + $this->rememberPreviousUri('rules.delete.uri'); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'delete-rule'); @@ -135,8 +134,7 @@ class RuleController extends Controller Session::flash('success', trans('firefly.deleted_rule', ['title' => $title])); Preferences::mark(); - - return redirect(session('rules.delete.url')); + return redirect($this->getPreviousUri('rules.delete.uri')); } /** @@ -181,7 +179,7 @@ class RuleController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('rules.edit.fromUpdate') !== true) { - Session::put('rules.edit.url', URL::previous()); + $this->rememberPreviousUri('rules.edit.uri'); } Session::forget('rules.edit.fromUpdate'); Session::flash('gaEventCategory', 'rules'); @@ -263,9 +261,7 @@ class RuleController extends Controller return redirect(route('rules.create', [$ruleGroup]))->withInput(); } - // redirect to previous URL. - return redirect(session('rules.create.url')); - + return redirect($this->getPreviousUri('rules.create.uri')); } /** @@ -293,7 +289,7 @@ class RuleController extends Controller $range = config('firefly.test-triggers.range'); /** @var TransactionMatcher $matcher */ - $matcher = app('FireflyIII\Rules\TransactionMatcher'); + $matcher = app(TransactionMatcher::class); $matcher->setLimit($limit); $matcher->setRange($range); $matcher->setTriggers($triggers); @@ -350,14 +346,13 @@ class RuleController extends Controller return redirect(route('rules.edit', [$rule->id]))->withInput(['return_to_edit' => 1]); } - // redirect to previous URL. - return redirect(session('rules.edit.url')); + return redirect($this->getPreviousUri('rules.edit.uri')); } private function createDefaultRule() { /** @var RuleRepositoryInterface $repository */ - $repository = app('FireflyIII\Repositories\Rule\RuleRepositoryInterface'); + $repository = app(RuleRepositoryInterface::class); if ($repository->count() === 0) { $data = [ diff --git a/app/Http/Controllers/RuleGroupController.php b/app/Http/Controllers/RuleGroupController.php index ee0cb84c26..e0bc8b7476 100644 --- a/app/Http/Controllers/RuleGroupController.php +++ b/app/Http/Controllers/RuleGroupController.php @@ -25,7 +25,6 @@ use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; use Illuminate\Http\Request; use Preferences; use Session; -use URL; use View; /** @@ -63,7 +62,7 @@ class RuleGroupController extends Controller // put previous url in session if not redirect from store (not "create another"). if (session('rule-groups.create.fromStore') !== true) { - Session::put('rule-groups.create.url', URL::previous()); + $this->rememberPreviousUri('rule-groups.create.uri'); } Session::forget('rule-groups.create.fromStore'); Session::flash('gaEventCategory', 'rules'); @@ -86,7 +85,7 @@ class RuleGroupController extends Controller unset($ruleGroupList[$ruleGroup->id]); // put previous url in session - Session::put('rule-groups.delete.url', URL::previous()); + $this->rememberPreviousUri('rule-groups.delete.uri'); Session::flash('gaEventCategory', 'rules'); Session::flash('gaEventAction', 'delete-rule-group'); @@ -112,8 +111,7 @@ class RuleGroupController extends Controller Session::flash('success', strval(trans('firefly.deleted_rule_group', ['title' => $title]))); Preferences::mark(); - - return redirect(session('rule-groups.delete.url')); + return redirect($this->getPreviousUri('rule-groups.delete.uri')); } /** @@ -141,7 +139,7 @@ class RuleGroupController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('rule-groups.edit.fromUpdate') !== true) { - Session::put('rule-groups.edit.url', URL::previous()); + $this->rememberPreviousUri('rule-groups.edit.uri'); } Session::forget('rule-groups.edit.fromUpdate'); Session::flash('gaEventCategory', 'rules'); @@ -225,8 +223,7 @@ class RuleGroupController extends Controller return redirect(route('rule-groups.create'))->withInput(); } - // redirect to previous URL. - return redirect(session('rule-groups.create.url')); + return redirect($this->getPreviousUri('rule-groups.create.uri')); } /** @@ -271,7 +268,7 @@ class RuleGroupController extends Controller } // redirect to previous URL. - return redirect(session('rule-groups.edit.url')); + return redirect($this->getPreviousUri('rule-groups.edit.uri')); } } diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 4b47777c62..17e868a2fb 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -15,6 +15,8 @@ namespace FireflyIII\Http\Controllers; use FireflyIII\Support\Search\SearchInterface; use Illuminate\Http\Request; +use Illuminate\Support\Collection; +use View; /** * Class SearchController @@ -30,44 +32,66 @@ class SearchController extends Controller { parent::__construct(); + $this->middleware( + function ($request, $next) { + View::share('mainTitleIcon', 'fa-search'); + View::share('title', trans('firefly.search')); + + return $next($request); + } + ); + } /** - * Results always come in the form of an array [results, count, fullCount] - * * @param Request $request * @param SearchInterface $searcher * - * @return $this + * @return View */ public function index(Request $request, SearchInterface $searcher) { - $minSearchLen = 1; - $subTitle = null; - $query = null; - $result = []; - $title = trans('firefly.search'); - $limit = 20; - $mainTitleIcon = 'fa-search'; + // yes, hard coded values: + $minSearchLen = 1; + $limit = 20; - // set limit for search: - $searcher->setLimit($limit); + // ui stuff: + $subTitle = ''; + + // query stuff + $query = null; + $result = []; + $rawQuery = $request->get('q'); + $hasModifiers = true; + $modifiers = []; if (!is_null($request->get('q')) && strlen($request->get('q')) >= $minSearchLen) { - $query = trim(strtolower($request->get('q'))); - $words = explode(' ', $query); - $subTitle = trans('firefly.search_results_for', ['query' => $query]); + // parse query, find modifiers: + // set limit for search + $searcher->setLimit($limit); + $searcher->parseQuery($request->get('q')); - $transactions = $searcher->searchTransactions($words); - $accounts = $searcher->searchAccounts($words); - $categories = $searcher->searchCategories($words); - $budgets = $searcher->searchBudgets($words); - $tags = $searcher->searchTags($words); - $result = ['transactions' => $transactions, 'accounts' => $accounts, 'categories' => $categories, 'budgets' => $budgets, 'tags' => $tags]; + $transactions = $searcher->searchTransactions(); + $accounts = new Collection; + $categories = new Collection; + $tags = new Collection; + $budgets = new Collection; + + // no special search thing? + if (!$searcher->hasModifiers()) { + $hasModifiers = false; + $accounts = $searcher->searchAccounts(); + $categories = $searcher->searchCategories(); + $budgets = $searcher->searchBudgets(); + $tags = $searcher->searchTags(); + } + $query = $searcher->getWordsAsString(); + $subTitle = trans('firefly.search_results_for', ['query' => $query]); + $result = ['transactions' => $transactions, 'accounts' => $accounts, 'categories' => $categories, 'budgets' => $budgets, 'tags' => $tags]; } - return view('search.index', compact('title', 'subTitle', 'limit', 'mainTitleIcon', 'query', 'result')); + return view('search.index', compact('rawQuery', 'hasModifiers', 'modifiers', 'subTitle', 'limit', 'query', 'result')); } } diff --git a/app/Http/Controllers/TagController.php b/app/Http/Controllers/TagController.php index 260adc97e3..bdb3160ea7 100644 --- a/app/Http/Controllers/TagController.php +++ b/app/Http/Controllers/TagController.php @@ -26,7 +26,6 @@ use Illuminate\Support\Collection; use Navigation; use Preferences; use Session; -use URL; use View; /** @@ -98,7 +97,7 @@ class TagController extends Controller } // put previous url in session if not redirect from store (not "create another"). if (session('tags.create.fromStore') !== true) { - Session::put('tags.create.url', URL::previous()); + $this->rememberPreviousUri('tags.create.uri'); } Session::forget('tags.create.fromStore'); Session::flash('gaEventCategory', 'tags'); @@ -117,7 +116,7 @@ class TagController extends Controller $subTitle = trans('breadcrumbs.delete_tag', ['tag' => e($tag->tag)]); // put previous url in session - Session::put('tags.delete.url', URL::previous()); + $this->rememberPreviousUri('tags.delete.uri'); Session::flash('gaEventCategory', 'tags'); Session::flash('gaEventAction', 'delete'); @@ -138,7 +137,7 @@ class TagController extends Controller Session::flash('success', strval(trans('firefly.deleted_tag', ['tag' => e($tagName)]))); Preferences::mark(); - return redirect(route('tags.index')); + return redirect($this->getPreviousUri('tags.delete.uri')); } /** @@ -174,7 +173,7 @@ class TagController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('tags.edit.fromUpdate') !== true) { - Session::put('tags.edit.url', URL::previous()); + $this->rememberPreviousUri('tags.edit.uri'); } Session::forget('tags.edit.fromUpdate'); Session::flash('gaEventCategory', 'tags'); @@ -289,8 +288,7 @@ class TagController extends Controller return redirect(route('tags.create'))->withInput(); } - // redirect to previous URL. - return redirect(session('tags.create.url')); + return redirect($this->getPreviousUri('tags.create.uri')); } @@ -316,7 +314,7 @@ class TagController extends Controller } // redirect to previous URL. - return redirect(session('tags.edit.url')); + return redirect($this->getPreviousUri('tags.edit.uri')); } /** diff --git a/app/Http/Controllers/Transaction/ConvertController.php b/app/Http/Controllers/Transaction/ConvertController.php index 45f5583b9a..3fb1e41de7 100644 --- a/app/Http/Controllers/Transaction/ConvertController.php +++ b/app/Http/Controllers/Transaction/ConvertController.php @@ -145,7 +145,7 @@ class ConvertController extends Controller $errors = $repository->convert($journal, $destinationType, $source, $destination); if ($errors->count() > 0) { - return redirect(route('transactions.convert', [strtolower($destinationType->type), $journal->id]))->withErrors($errors)->withInput(); + return redirect(route('transactions.convert.index', [strtolower($destinationType->type), $journal->id]))->withErrors($errors)->withInput(); } Session::flash('success', trans('firefly.converted_to_' . $destinationType->type)); diff --git a/app/Http/Controllers/Transaction/MassController.php b/app/Http/Controllers/Transaction/MassController.php index d139f0f414..5a61b060f4 100644 --- a/app/Http/Controllers/Transaction/MassController.php +++ b/app/Http/Controllers/Transaction/MassController.php @@ -25,7 +25,6 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Illuminate\Support\Collection; use Preferences; use Session; -use URL; use View; /** @@ -63,7 +62,7 @@ class MassController extends Controller $subTitle = trans('firefly.mass_delete_journals'); // put previous url in session - Session::put('transactions.mass-delete.url', URL::previous()); + $this->rememberPreviousUri('transactions.mass-delete.uri'); Session::flash('gaEventCategory', 'transactions'); Session::flash('gaEventAction', 'mass-delete'); @@ -104,7 +103,7 @@ class MassController extends Controller Session::flash('success', trans('firefly.mass_deleted_transactions_success', ['amount' => $count])); // redirect to previous URL: - return redirect(session('transactions.mass-delete.url')); + return redirect($this->getPreviousUri('transactions.mass-delete.uri')); } @@ -150,7 +149,7 @@ class MassController extends Controller } // put previous url in session - Session::put('transactions.mass-edit.url', URL::previous()); + $this->rememberPreviousUri('transactions.mass-edit.uri'); Session::flash('gaEventCategory', 'transactions'); Session::flash('gaEventAction', 'mass-edit'); @@ -236,7 +235,7 @@ class MassController extends Controller Session::flash('success', trans('firefly.mass_edited_transactions_success', ['amount' => $count])); // redirect to previous URL: - return redirect(session('transactions.mass-edit.url')); + return redirect($this->getPreviousUri('transactions.mass-edit.uri')); } } diff --git a/app/Http/Controllers/Transaction/SingleController.php b/app/Http/Controllers/Transaction/SingleController.php index 9c006617bd..830c32eb78 100644 --- a/app/Http/Controllers/Transaction/SingleController.php +++ b/app/Http/Controllers/Transaction/SingleController.php @@ -31,7 +31,6 @@ use Log; use Preferences; use Session; use Steam; -use URL; use View; /** @@ -140,8 +139,7 @@ class SingleController extends Controller // put previous url in session if not redirect from store (not "create another"). if (session('transactions.create.fromStore') !== true) { - $url = URL::previous(); - Session::put('transactions.create.url', $url); + $this->rememberPreviousUri('transactions.create.uri'); } Session::forget('transactions.create.fromStore'); Session::flash('gaEventCategory', 'transactions'); @@ -172,7 +170,7 @@ class SingleController extends Controller $subTitle = trans('firefly.delete_' . $what, ['description' => $journal->description]); // put previous url in session - Session::put('transactions.delete.url', URL::previous()); + $this->rememberPreviousUri('transactions.delete.uri'); Session::flash('gaEventCategory', 'transactions'); Session::flash('gaEventAction', 'delete-' . $what); @@ -192,21 +190,14 @@ class SingleController extends Controller if ($this->isOpeningBalance($transactionJournal)) { return $this->redirectToAccount($transactionJournal); } - $journalId = $transactionJournal->id; - $type = TransactionJournal::transactionTypeStr($transactionJournal); + $type = TransactionJournal::transactionTypeStr($transactionJournal); Session::flash('success', strval(trans('firefly.deleted_' . strtolower($type), ['description' => e($transactionJournal->description)]))); $repository->delete($transactionJournal); Preferences::mark(); - $uri = session('transactions.delete.url'); - if (!(strpos($uri, sprintf('transactions/show/%s', $journalId)) === false)) { - // uri would point back to transaction - $uri = route('transactions.index', [strtolower($type)]); - } - - return redirect($uri); + return redirect($this->getPreviousUri('transactions.delete.uri')); } /** @@ -275,7 +266,7 @@ class SingleController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('transactions.edit.fromUpdate') !== true) { - Session::put('transactions.edit.url', URL::previous()); + $this->rememberPreviousUri('transactions.edit.uri'); } Session::forget('transactions.edit.fromUpdate'); @@ -336,7 +327,7 @@ class SingleController extends Controller // redirect to previous URL. - return redirect(session('transactions.create.url')); + return redirect($this->getPreviousUri('transactions.create.uri')); } @@ -386,7 +377,6 @@ class SingleController extends Controller } // redirect to previous URL. - return redirect(session('transactions.edit.url')); - + return redirect($this->getPreviousUri('transactions.edit.uri')); } } diff --git a/app/Http/Controllers/Transaction/SplitController.php b/app/Http/Controllers/Transaction/SplitController.php index 91b35ddfce..e667cb5f1b 100644 --- a/app/Http/Controllers/Transaction/SplitController.php +++ b/app/Http/Controllers/Transaction/SplitController.php @@ -30,7 +30,6 @@ use Log; use Preferences; use Session; use Steam; -use URL; use View; /** @@ -107,7 +106,7 @@ class SplitController extends Controller // put previous url in session if not redirect from store (not "return_to_edit"). if (session('transactions.edit-split.fromUpdate') !== true) { - Session::put('transactions.edit-split.url', URL::previous()); + $this->rememberPreviousUri('transactions.edit-split.uri'); } Session::forget('transactions.edit-split.fromUpdate'); @@ -139,7 +138,7 @@ class SplitController extends Controller $data = $this->arrayFromInput($request); $journal = $repository->updateSplitJournal($journal, $data); /** @var array $files */ - $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; // save attachments: $this->attachments->saveAttachmentsForModel($journal, $files); @@ -163,8 +162,7 @@ class SplitController extends Controller } // redirect to previous URL. - return redirect(session('transactions.edit-split.url')); - + return redirect($this->getPreviousUri('transactions.edit-split.uri')); } /** diff --git a/app/Http/Controllers/TransactionController.php b/app/Http/Controllers/TransactionController.php index 2ec3e8ce5c..b0ef6013ab 100644 --- a/app/Http/Controllers/TransactionController.php +++ b/app/Http/Controllers/TransactionController.php @@ -72,16 +72,11 @@ class TransactionController extends Controller $end = session('end', Navigation::endOfPeriod(new Carbon, $range)); /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); - $collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts(); - $collector->setRange($start, $end)->withBudgetInformation()->withCategoryInformation(); - - // do not filter transfers if $what = transfer. - if (!in_array($what, ['transfer', 'transfers'])) { - Log::debug('Also get opposing account info.'); - $collector->withOpposingAccount(); - } - + $collector = app(JournalCollectorInterface::class); + $collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts()->setRange($start, $end)->withBudgetInformation() + ->withCategoryInformation(); + $collector->withOpposingAccount(); + $collector->disableInternalFilter(); $journals = $collector->getPaginatedJournals(); $journals->setPath('transactions/' . $what); @@ -122,14 +117,11 @@ class TransactionController extends Controller $subTitle = sprintf('%s (%s)', trans('firefly.title_' . $what), strtolower(trans('firefly.everything'))); $page = intval($request->get('page')) === 0 ? 1 : intval($request->get('page')); - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); $collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts()->withBudgetInformation()->withCategoryInformation(); - - // do not filter transfers if $what = transfer. - if (!in_array($what, ['transfer', 'transfers'])) { - Log::debug('Also get opposing account info.'); - $collector->withOpposingAccount(); - } + $collector->withOpposingAccount(); + $collector->disableInternalFilter(); $journals = $collector->getPaginatedJournals(); $journals->setPath('transactions/' . $what . '/all'); @@ -161,16 +153,12 @@ class TransactionController extends Controller Log::debug(sprintf('Transaction index by date will show between %s and %s', $start->format('Y-m-d'), $end->format('Y-m-d'))); /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser(auth()->user()); $collector->setTypes($types)->setLimit($pageSize)->setPage($page)->setAllAssetAccounts(); $collector->setRange($start, $end)->withBudgetInformation()->withCategoryInformation(); - - // do not filter transfers if $what = transfer. - if (!in_array($what, ['transfer', 'transfers'])) { - Log::debug('Also get opposing account info.'); - $collector->withOpposingAccount(); - } - + $collector->withOpposingAccount(); + $collector->disableInternalFilter(); $journals = $collector->getPaginatedJournals(); $journals->setPath('transactions/' . $what . '/' . $date); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index e8dc229028..289a6924d1 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -20,6 +20,8 @@ use FireflyIII\Http\Middleware\IsAdmin; use FireflyIII\Http\Middleware\Range; use FireflyIII\Http\Middleware\RedirectIfAuthenticated; use FireflyIII\Http\Middleware\RedirectIfTwoFactorAuthenticated; +use FireflyIII\Http\Middleware\Sandstorm; +use FireflyIII\Http\Middleware\StartFireflySession; use FireflyIII\Http\Middleware\VerifyCsrfToken; use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; use Illuminate\Auth\Middleware\Authorize; @@ -28,7 +30,6 @@ use Illuminate\Foundation\Http\Kernel as HttpKernel; use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode; use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Routing\Middleware\ThrottleRequests; -use Illuminate\Session\Middleware\StartSession; use Illuminate\View\Middleware\ShareErrorsFromSession; /** @@ -48,9 +49,8 @@ class Kernel extends HttpKernel */ protected $bootstrappers = [ - 'Illuminate\Foundation\Bootstrap\DetectEnvironment', + 'Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables', 'Illuminate\Foundation\Bootstrap\LoadConfiguration', - 'FireflyIII\Bootstrap\ConfigureLogging', 'Illuminate\Foundation\Bootstrap\HandleExceptions', 'Illuminate\Foundation\Bootstrap\RegisterFacades', 'Illuminate\Foundation\Bootstrap\RegisterProviders', @@ -79,19 +79,23 @@ class Kernel extends HttpKernel // does not check login // does not check 2fa // does not check activation - 'web' => [ + 'web' => [ + Sandstorm::class, EncryptCookies::class, AddQueuedCookiesToResponse::class, - StartSession::class, + StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, ], + + // MUST NOT be logged in. Does not care about 2FA or confirmation. - 'user-not-logged-in' => [ + 'user-not-logged-in' => [ + Sandstorm::class, EncryptCookies::class, AddQueuedCookiesToResponse::class, - StartSession::class, + StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, @@ -100,37 +104,26 @@ class Kernel extends HttpKernel // MUST be logged in. // MUST NOT have 2FA // don't care about confirmation: - 'user-logged-in-no-2fa' => [ + 'user-logged-in-no-2fa' => [ + Sandstorm::class, EncryptCookies::class, AddQueuedCookiesToResponse::class, - StartSession::class, + StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, Authenticate::class, RedirectIfTwoFactorAuthenticated::class, ], - // MUST be logged in - // MUST have 2FA - // MUST NOT have confirmation. - 'user-logged-in-2fa-no-activation' => [ - EncryptCookies::class, - AddQueuedCookiesToResponse::class, - StartSession::class, - ShareErrorsFromSession::class, - VerifyCsrfToken::class, - SubstituteBindings::class, - Authenticate::class, - AuthenticateTwoFactor::class, - ], // MUST be logged in // don't care about 2fa // don't care about confirmation. - 'user-simple-auth' => [ + 'user-simple-auth' => [ + Sandstorm::class, EncryptCookies::class, AddQueuedCookiesToResponse::class, - StartSession::class, + StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, @@ -141,10 +134,11 @@ class Kernel extends HttpKernel // MUST have 2fa // MUST be confirmed. // (this group includes the other Firefly middleware) - 'user-full-auth' => [ + 'user-full-auth' => [ + Sandstorm::class, EncryptCookies::class, AddQueuedCookiesToResponse::class, - StartSession::class, + StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, @@ -158,10 +152,11 @@ class Kernel extends HttpKernel // MUST be confirmed. // MUST have owner role // (this group includes the other Firefly middleware) - 'admin' => [ + 'admin' => [ + Sandstorm::class, EncryptCookies::class, AddQueuedCookiesToResponse::class, - StartSession::class, + StartFireflySession::class, ShareErrorsFromSession::class, VerifyCsrfToken::class, SubstituteBindings::class, diff --git a/app/Http/Middleware/AuthenticateTwoFactor.php b/app/Http/Middleware/AuthenticateTwoFactor.php index 4f9f1f5542..5325150bcc 100644 --- a/app/Http/Middleware/AuthenticateTwoFactor.php +++ b/app/Http/Middleware/AuthenticateTwoFactor.php @@ -14,8 +14,10 @@ declare(strict_types = 1); namespace FireflyIII\Http\Middleware; use Closure; +use Cookie; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; +use Log; use Preferences; use Session; @@ -55,8 +57,13 @@ class AuthenticateTwoFactor } $is2faEnabled = Preferences::get('twoFactorAuthEnabled', false)->data; $has2faSecret = !is_null(Preferences::get('twoFactorAuthSecret')); - $is2faAuthed = Session::get('twofactor-authenticated'); + + // grab 2auth information from cookie, not from session. + $is2faAuthed = Cookie::get('twoFactorAuthenticated') === 'true'; + if ($is2faEnabled && $has2faSecret && !$is2faAuthed) { + Log::debug('Does not seem to be 2 factor authed, redirect.'); + return redirect(route('two-factor.index')); } diff --git a/app/Http/Middleware/Range.php b/app/Http/Middleware/Range.php index fdf5322a4d..7bc60818c9 100644 --- a/app/Http/Middleware/Range.php +++ b/app/Http/Middleware/Range.php @@ -17,7 +17,6 @@ use Amount; use App; use Carbon\Carbon; use Closure; -use FireflyIII\Exceptions\FireflyException; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use Illuminate\Contracts\Auth\Guard; use Illuminate\Http\Request; diff --git a/app/Http/Middleware/RedirectIfTwoFactorAuthenticated.php b/app/Http/Middleware/RedirectIfTwoFactorAuthenticated.php index 43cc865dc7..53dcaa619e 100644 --- a/app/Http/Middleware/RedirectIfTwoFactorAuthenticated.php +++ b/app/Http/Middleware/RedirectIfTwoFactorAuthenticated.php @@ -17,7 +17,8 @@ use Closure; use Illuminate\Support\Facades\Auth; use Preferences; use Session; - +use Log; +use Cookie; /** * Class RedirectIfTwoFactorAuthenticated * @@ -40,7 +41,10 @@ class RedirectIfTwoFactorAuthenticated $is2faEnabled = Preferences::get('twoFactorAuthEnabled', false)->data; $has2faSecret = !is_null(Preferences::get('twoFactorAuthSecret')); - $is2faAuthed = Session::get('twofactor-authenticated'); + + // grab 2auth information from cookie + $is2faAuthed = Cookie::get('twoFactorAuthenticated') === 'true'; + if ($is2faEnabled && $has2faSecret && $is2faAuthed) { return redirect('/'); } diff --git a/app/Http/Middleware/Sandstorm.php b/app/Http/Middleware/Sandstorm.php new file mode 100644 index 0000000000..92225ceef5 --- /dev/null +++ b/app/Http/Middleware/Sandstorm.php @@ -0,0 +1,75 @@ +guest()) { + $userId = strval($request->header('X-Sandstorm-User-Id')); + if (strlen($userId) > 0) { + // find user? + $email = $userId . '@firefly'; + $user = User::whereEmail($email)->first(); + if (is_null($user)) { + $user = User::create( + [ + 'email' => $email, + 'password' => str_random(16), + ] + ); + + } + + + // login user: + Auth::guard($guard)->login($user); + } else { + echo 'user id no length, guest?'; + exit; + } + + } + + return $next($request); + } +} diff --git a/app/Http/Middleware/StartFireflySession.php b/app/Http/Middleware/StartFireflySession.php new file mode 100644 index 0000000000..f72e13aed3 --- /dev/null +++ b/app/Http/Middleware/StartFireflySession.php @@ -0,0 +1,54 @@ +fullUrl(); + if ($request->method() === 'GET' && $request->route() && !$request->ajax()) { + if (strpos($fullUrl, '/javascript/') === false) { + $session->setPreviousUrl($fullUrl); + } + } + } + +} diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index 11ec0455c9..0c7c3ed591 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -12,9 +12,10 @@ declare(strict_types = 1); namespace FireflyIII\Http\Middleware; +use Carbon\Carbon; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier; use Symfony\Component\HttpFoundation\Cookie; -use Carbon\Carbon; + /** * Class VerifyCsrfToken * @@ -35,8 +36,9 @@ class VerifyCsrfToken extends BaseVerifier /** * Add the CSRF token to the response cookies. * - * @param \Illuminate\Http\Request $request - * @param \Symfony\Component\HttpFoundation\Response $response + * @param \Illuminate\Http\Request $request + * @param \Symfony\Component\HttpFoundation\Response $response + * * @return \Symfony\Component\HttpFoundation\Response */ protected function addCookieToResponse($request, $response) diff --git a/app/Http/Requests/AccountFormRequest.php b/app/Http/Requests/AccountFormRequest.php index cbd07f46ee..cadf22b600 100644 --- a/app/Http/Requests/AccountFormRequest.php +++ b/app/Http/Requests/AccountFormRequest.php @@ -77,11 +77,11 @@ class AccountFormRequest extends Request return [ 'id' => $idRule, 'name' => $nameRule, - 'openingBalance' => 'numeric', + 'openingBalance' => 'numeric|required_with:openingBalanceDate', + 'openingBalanceDate' => 'date|required_with:openingBalance', 'iban' => 'iban', 'BIC' => 'bic', 'virtualBalance' => 'numeric', - 'openingBalanceDate' => 'date', 'currency_id' => 'exists:transaction_currencies,id', 'accountNumber' => 'between:1,255|uniqueAccountNumberForUser', 'accountRole' => 'in:' . $accountRoles, diff --git a/app/Http/Requests/ReportFormRequest.php b/app/Http/Requests/ReportFormRequest.php index 763af9dd6a..02a5f5c8e5 100644 --- a/app/Http/Requests/ReportFormRequest.php +++ b/app/Http/Requests/ReportFormRequest.php @@ -19,6 +19,7 @@ use FireflyIII\Exceptions\FireflyException; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; +use FireflyIII\Repositories\Tag\TagRepositoryInterface; use Illuminate\Support\Collection; /** @@ -141,13 +142,34 @@ class ReportFormRequest extends Request return $date; } + /** + * @return Collection + */ + public function getTagList(): Collection + { + /** @var TagRepositoryInterface $repository */ + $repository = app(TagRepositoryInterface::class); + $set = $this->get('tag'); + $collection = new Collection; + if (is_array($set)) { + foreach ($set as $tagTag) { + $tag = $repository->findByTag($tagTag); + if (!is_null($tag->id)) { + $collection->push($tag); + } + } + } + + return $collection; + } + /** * @return array */ public function rules(): array { return [ - 'report_type' => 'in:audit,default,category,budget', + 'report_type' => 'in:audit,default,category,budget,tag', ]; } diff --git a/app/Http/Requests/Request.php b/app/Http/Requests/Request.php index e73b17ac60..cf8bbae71e 100644 --- a/app/Http/Requests/Request.php +++ b/app/Http/Requests/Request.php @@ -87,7 +87,7 @@ class Request extends FormRequest */ protected function string(string $field): string { - $string = $this->get($field) ?? ''; + $string = $this->get($field) ?? ''; $search = [ "\u{0001}", // start of heading "\u{0002}", // start of text diff --git a/app/Http/Requests/RuleGroupFormRequest.php b/app/Http/Requests/RuleGroupFormRequest.php index fcf92d0105..7d2250882f 100644 --- a/app/Http/Requests/RuleGroupFormRequest.php +++ b/app/Http/Requests/RuleGroupFormRequest.php @@ -49,7 +49,7 @@ class RuleGroupFormRequest extends Request public function rules() { /** @var RuleGroupRepositoryInterface $repository */ - $repository = app(RuleGroupRepositoryInterface::class, [auth()->user()]); + $repository = app(RuleGroupRepositoryInterface::class); $titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title'; if (!is_null($repository->find(intval($this->get('id')))->id)) { $titleRule = 'required|between:1,100|uniqueObjectForUser:rule_groups,title,' . intval($this->get('id')); diff --git a/app/Http/Requests/SplitJournalFormRequest.php b/app/Http/Requests/SplitJournalFormRequest.php index 5efba69243..3d82027c6b 100644 --- a/app/Http/Requests/SplitJournalFormRequest.php +++ b/app/Http/Requests/SplitJournalFormRequest.php @@ -13,6 +13,7 @@ declare(strict_types = 1); namespace FireflyIII\Http\Requests; +use Steam; /** * Class SplitJournalFormRequest @@ -101,7 +102,7 @@ class SplitJournalFormRequest extends Request $category = $categories[$index] ?? ''; $transaction = [ 'description' => $description, - 'amount' => $amounts[$index], + 'amount' => Steam::positive($amounts[$index]), 'budget_id' => $budgets[$index] ?? 0, 'category' => $category, 'source_account_id' => $srcAccountIds[$index] ?? $this->get('journal_source_account_id'), diff --git a/app/Http/Requests/TagFormRequest.php b/app/Http/Requests/TagFormRequest.php index 544b53c0b0..ce85aaa94f 100644 --- a/app/Http/Requests/TagFormRequest.php +++ b/app/Http/Requests/TagFormRequest.php @@ -12,7 +12,6 @@ declare(strict_types = 1); namespace FireflyIII\Http\Requests; -use Carbon\Carbon; use FireflyIII\Repositories\Tag\TagRepositoryInterface; /** diff --git a/app/Http/breadcrumbs.php b/app/Http/breadcrumbs.php index b7a64a5c07..05bf0acb56 100644 --- a/app/Http/breadcrumbs.php +++ b/app/Http/breadcrumbs.php @@ -772,7 +772,7 @@ Breadcrumbs::register( $breadcrumbs->parent('transactions.show', $journal); $breadcrumbs->push( trans('firefly.convert_to_' . $destinationType->type, ['description' => $journal->description]), - route('transactions.convert', [strtolower($destinationType->type), $journal->id]) + route('transactions.convert.index', [strtolower($destinationType->type), $journal->id]) ); } ); diff --git a/app/Import/Converter/AccountId.php b/app/Import/Converter/AccountId.php index 5b39999f2e..4c07790fa5 100644 --- a/app/Import/Converter/AccountId.php +++ b/app/Import/Converter/AccountId.php @@ -40,7 +40,8 @@ class AccountId extends BasicConverter implements ConverterInterface return new Account; } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/AssetAccountIban.php b/app/Import/Converter/AssetAccountIban.php index 9ed749a781..d2336c282d 100644 --- a/app/Import/Converter/AssetAccountIban.php +++ b/app/Import/Converter/AssetAccountIban.php @@ -43,7 +43,8 @@ class AssetAccountIban extends BasicConverter implements ConverterInterface } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { diff --git a/app/Import/Converter/AssetAccountName.php b/app/Import/Converter/AssetAccountName.php index 4785ae16d2..8618d52f2d 100644 --- a/app/Import/Converter/AssetAccountName.php +++ b/app/Import/Converter/AssetAccountName.php @@ -43,7 +43,8 @@ class AssetAccountName extends BasicConverter implements ConverterInterface } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { diff --git a/app/Import/Converter/AssetAccountNumber.php b/app/Import/Converter/AssetAccountNumber.php index 5c71bf57f1..d389492c91 100644 --- a/app/Import/Converter/AssetAccountNumber.php +++ b/app/Import/Converter/AssetAccountNumber.php @@ -41,7 +41,8 @@ class AssetAccountNumber extends BasicConverter implements ConverterInterface } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { diff --git a/app/Import/Converter/BillId.php b/app/Import/Converter/BillId.php index 06713afaf4..cb20e4c7c9 100644 --- a/app/Import/Converter/BillId.php +++ b/app/Import/Converter/BillId.php @@ -42,7 +42,8 @@ class BillId extends BasicConverter implements ConverterInterface } /** @var BillRepositoryInterface $repository */ - $repository = app(BillRepositoryInterface::class, [$this->user]); + $repository = app(BillRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found bill in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/BillName.php b/app/Import/Converter/BillName.php index 6c4aa2fc17..3d2dbe9a71 100644 --- a/app/Import/Converter/BillName.php +++ b/app/Import/Converter/BillName.php @@ -44,7 +44,8 @@ class BillName extends BasicConverter implements ConverterInterface } /** @var BillRepositoryInterface $repository */ - $repository = app(BillRepositoryInterface::class, [$this->user]); + $repository = app(BillRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found bill in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/BudgetId.php b/app/Import/Converter/BudgetId.php index 0fe769f70e..cf709c0beb 100644 --- a/app/Import/Converter/BudgetId.php +++ b/app/Import/Converter/BudgetId.php @@ -42,7 +42,8 @@ class BudgetId extends BasicConverter implements ConverterInterface } /** @var BudgetRepositoryInterface $repository */ - $repository = app(BudgetRepositoryInterface::class, [$this->user]); + $repository = app(BudgetRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found budget in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/BudgetName.php b/app/Import/Converter/BudgetName.php index fc5d5416fc..7ecd85530c 100644 --- a/app/Import/Converter/BudgetName.php +++ b/app/Import/Converter/BudgetName.php @@ -42,7 +42,8 @@ class BudgetName extends BasicConverter implements ConverterInterface } /** @var BudgetRepositoryInterface $repository */ - $repository = app(BudgetRepositoryInterface::class, [$this->user]); + $repository = app(BudgetRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found budget in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/CategoryId.php b/app/Import/Converter/CategoryId.php index 5d538f4b90..2544a61597 100644 --- a/app/Import/Converter/CategoryId.php +++ b/app/Import/Converter/CategoryId.php @@ -42,7 +42,8 @@ class CategoryId extends BasicConverter implements ConverterInterface } /** @var CategoryRepositoryInterface $repository */ - $repository = app(CategoryRepositoryInterface::class, [$this->user]); + $repository = app(CategoryRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found category in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/CategoryName.php b/app/Import/Converter/CategoryName.php index 28e7650c1f..f8af2414b1 100644 --- a/app/Import/Converter/CategoryName.php +++ b/app/Import/Converter/CategoryName.php @@ -42,7 +42,8 @@ class CategoryName extends BasicConverter implements ConverterInterface } /** @var CategoryRepositoryInterface $repository */ - $repository = app(CategoryRepositoryInterface::class, [$this->user]); + $repository = app(CategoryRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found category in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/CurrencyCode.php b/app/Import/Converter/CurrencyCode.php index 48901cceaa..f78433ddf3 100644 --- a/app/Import/Converter/CurrencyCode.php +++ b/app/Import/Converter/CurrencyCode.php @@ -36,6 +36,7 @@ class CurrencyCode extends BasicConverter implements ConverterInterface /** @var CurrencyRepositoryInterface $repository */ $repository = app(CurrencyRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/CurrencyId.php b/app/Import/Converter/CurrencyId.php index 6622899264..299cde1bf3 100644 --- a/app/Import/Converter/CurrencyId.php +++ b/app/Import/Converter/CurrencyId.php @@ -42,7 +42,8 @@ class CurrencyId extends BasicConverter implements ConverterInterface } /** @var CurrencyRepositoryInterface $repository */ - $repository = app(CurrencyRepositoryInterface::class, [$this->user]); + $repository = app(CurrencyRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/CurrencyName.php b/app/Import/Converter/CurrencyName.php index ad28107f4b..71af377582 100644 --- a/app/Import/Converter/CurrencyName.php +++ b/app/Import/Converter/CurrencyName.php @@ -42,7 +42,8 @@ class CurrencyName extends BasicConverter implements ConverterInterface } /** @var CurrencyRepositoryInterface $repository */ - $repository = app(CurrencyRepositoryInterface::class, [$this->user]); + $repository = app(CurrencyRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/CurrencySymbol.php b/app/Import/Converter/CurrencySymbol.php index 307d409cd0..27ed50dd48 100644 --- a/app/Import/Converter/CurrencySymbol.php +++ b/app/Import/Converter/CurrencySymbol.php @@ -42,7 +42,8 @@ class CurrencySymbol extends BasicConverter implements ConverterInterface } /** @var CurrencyRepositoryInterface $repository */ - $repository = app(CurrencyRepositoryInterface::class, [$this->user]); + $repository = app(CurrencyRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]); diff --git a/app/Import/Converter/OpposingAccountIban.php b/app/Import/Converter/OpposingAccountIban.php index c3dacbd712..ee8b40747c 100644 --- a/app/Import/Converter/OpposingAccountIban.php +++ b/app/Import/Converter/OpposingAccountIban.php @@ -43,7 +43,8 @@ class OpposingAccountIban extends BasicConverter implements ConverterInterface } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { diff --git a/app/Import/Converter/OpposingAccountName.php b/app/Import/Converter/OpposingAccountName.php index 4516873a25..fa51245fd6 100644 --- a/app/Import/Converter/OpposingAccountName.php +++ b/app/Import/Converter/OpposingAccountName.php @@ -42,7 +42,8 @@ class OpposingAccountName extends BasicConverter implements ConverterInterface } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { diff --git a/app/Import/Converter/OpposingAccountNumber.php b/app/Import/Converter/OpposingAccountNumber.php index 86df680223..d513a88ae0 100644 --- a/app/Import/Converter/OpposingAccountNumber.php +++ b/app/Import/Converter/OpposingAccountNumber.php @@ -43,7 +43,8 @@ class OpposingAccountNumber extends BasicConverter implements ConverterInterface } /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); if (isset($this->mapping[$value])) { diff --git a/app/Import/Converter/TagSplit.php b/app/Import/Converter/TagSplit.php index cc99561663..d93074b7d0 100644 --- a/app/Import/Converter/TagSplit.php +++ b/app/Import/Converter/TagSplit.php @@ -39,7 +39,8 @@ class TagSplit Log::debug('Exploded parts.', $parts); /** @var TagRepositoryInterface $repository */ - $repository = app(TagRepositoryInterface::class, [$user]); + $repository = app(TagRepositoryInterface::class); + $repository->setUser($user); /** @var string $part */ diff --git a/app/Import/ImportProcedure.php b/app/Import/ImportProcedure.php index c535d47fae..991c5addcd 100644 --- a/app/Import/ImportProcedure.php +++ b/app/Import/ImportProcedure.php @@ -58,7 +58,8 @@ class ImportProcedure implements ImportProcedureInterface if ($job->configuration['import-account'] != 0) { /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$job->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($job->user); $validator->setDefaultImportAccount($repository->find($job->configuration['import-account'])); } diff --git a/app/Import/ImportProcedureInterface.php b/app/Import/ImportProcedureInterface.php index 72765aa4ce..22a519aa95 100644 --- a/app/Import/ImportProcedureInterface.php +++ b/app/Import/ImportProcedureInterface.php @@ -30,4 +30,4 @@ interface ImportProcedureInterface */ public function runImport(ImportJob $job): Collection; -} \ No newline at end of file +} diff --git a/app/Import/ImportStorage.php b/app/Import/ImportStorage.php index 4edf17d5f8..89b5e76ded 100644 --- a/app/Import/ImportStorage.php +++ b/app/Import/ImportStorage.php @@ -27,6 +27,7 @@ use FireflyIII\Rules\Processor; use FireflyIII\User; use Illuminate\Support\Collection; use Log; +use Steam; /** * Class ImportStorage @@ -159,8 +160,9 @@ class ImportStorage private function createImportTag(): Tag { /** @var TagRepositoryInterface $repository */ - $repository = app(TagRepositoryInterface::class, [$this->user]); - $data = [ + $repository = app(TagRepositoryInterface::class); + $repository->setUser($this->user); + $data = [ 'tag' => trans('firefly.import_with_key', ['key' => $this->job->key]), 'date' => new Carbon, 'description' => null, @@ -169,7 +171,7 @@ class ImportStorage 'zoomLevel' => null, 'tagMode' => 'nothing', ]; - $tag = $repository->store($data); + $tag = $repository->store($data); return $tag; } @@ -196,21 +198,6 @@ class ImportStorage } - /** - * @param float $amount - * - * @return string - */ - private function makePositive(float $amount): string - { - $amount = strval($amount); - if (bccomp($amount, '0', 4) === -1) { // left is larger than right - $amount = bcmul($amount, '-1'); - } - - return $amount; - } - /** * @param $entry * @@ -369,7 +356,7 @@ class ImportStorage $journal = $this->storeJournal($entry); - $amount = $this->makePositive($entry->fields['amount']); + $amount = Steam::positive($entry->fields['amount']); $accounts = $this->storeAccounts($entry); // create new transactions. This is something that needs a rewrite for multiple/split transactions. diff --git a/app/Import/ImportValidator.php b/app/Import/ImportValidator.php index d6d15d3ed2..9a5a254151 100644 --- a/app/Import/ImportValidator.php +++ b/app/Import/ImportValidator.php @@ -177,7 +177,8 @@ class ImportValidator // find it first by new type: /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); $result = $repository->findByName($account->name, [$type]); if (is_null($result->id)) { @@ -214,7 +215,8 @@ class ImportValidator { /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); $name = 'Unknown expense account'; $result = $repository->findByName($name, [AccountType::EXPENSE]); @@ -235,7 +237,8 @@ class ImportValidator { /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [$this->user]); + $repository = app(AccountRepositoryInterface::class); + $repository->setUser($this->user); $name = 'Unknown revenue account'; $result = $repository->findByName($name, [AccountType::REVENUE]); @@ -382,7 +385,8 @@ class ImportValidator { if (is_null($entry->fields['currency'])) { /** @var CurrencyRepositoryInterface $repository */ - $repository = app(CurrencyRepositoryInterface::class, [$this->user]); + $repository = app(CurrencyRepositoryInterface::class); + $repository->setUser($this->user); // is the default currency for the user or the system $defaultCode = Preferences::getForUser($this->user, 'currencyPreference', config('firefly.default_currency', 'EUR'))->data; diff --git a/app/Import/Setup/CsvSetup.php b/app/Import/Setup/CsvSetup.php index 20c938bda3..01fcdc756a 100644 --- a/app/Import/Setup/CsvSetup.php +++ b/app/Import/Setup/CsvSetup.php @@ -181,10 +181,9 @@ class CsvSetup implements SetupInterface public function saveImportConfiguration(array $data, FileBag $files): bool { /** @var AccountRepositoryInterface $repository */ - $repository = app(AccountRepositoryInterface::class, [auth()->user()]); - - $importId = $data['csv_import_account'] ?? 0; - $account = $repository->find(intval($importId)); + $repository = app(AccountRepositoryInterface::class); + $importId = $data['csv_import_account'] ?? 0; + $account = $repository->find(intval($importId)); $hasHeaders = isset($data['has_headers']) && intval($data['has_headers']) === 1 ? true : false; $config = $this->job->configuration; @@ -438,8 +437,9 @@ class CsvSetup implements SetupInterface Log::debug('Now in getDataForColumnRoles()'); $config = $this->job->configuration; $data = [ - 'columns' => [], - 'columnCount' => 0, + 'columns' => [], + 'columnCount' => 0, + 'columnHeaders' => [], ]; // show user column role configuration. @@ -448,8 +448,13 @@ class CsvSetup implements SetupInterface // create CSV reader. $reader = Reader::createFromString($content); $reader->setDelimiter($config['delimiter']); - $start = $config['has-headers'] ? 1 : 0; - $end = $start + config('csv.example_rows'); + $start = $config['has-headers'] ? 1 : 0; + $end = $start + config('csv.example_rows'); + $header = []; + if ($config['has-headers']) { + $header = $reader->fetchOne(0); + } + // collect example data in $data['columns'] Log::debug(sprintf('While %s is smaller than %d', $start, $end)); @@ -467,7 +472,8 @@ class CsvSetup implements SetupInterface } foreach ($row as $index => $value) { - $value = trim($value); + $value = trim($value); + $data['columnHeaders'][$index] = $header[$index] ?? ''; if (strlen($value) > 0) { $data['columns'][$index][] = $value; } diff --git a/app/Jobs/ExecuteRuleGroupOnExistingTransactions.php b/app/Jobs/ExecuteRuleGroupOnExistingTransactions.php index 1678cb2bcc..0ac899ffcb 100644 --- a/app/Jobs/ExecuteRuleGroupOnExistingTransactions.php +++ b/app/Jobs/ExecuteRuleGroupOnExistingTransactions.php @@ -156,7 +156,8 @@ class ExecuteRuleGroupOnExistingTransactions extends Job implements ShouldQueue protected function collectJournals() { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setAccounts($this->accounts)->setRange($this->startDate, $this->endDate); return $collector->getJournals(); diff --git a/app/Models/Budget.php b/app/Models/Budget.php index 504802e05a..84ef039aa0 100644 --- a/app/Models/Budget.php +++ b/app/Models/Budget.php @@ -44,7 +44,7 @@ class Budget extends Model 'encrypted' => 'boolean', ]; /** @var array */ - protected $dates = ['created_at', 'updated_at', 'deleted_at']; + protected $dates = ['created_at', 'updated_at', 'deleted_at']; protected $fillable = ['user_id', 'name', 'active']; protected $hidden = ['encrypted']; protected $rules = ['name' => 'required|between:1,200',]; diff --git a/app/Providers/AccountServiceProvider.php b/app/Providers/AccountServiceProvider.php index 0ce5a90329..3035731adb 100644 --- a/app/Providers/AccountServiceProvider.php +++ b/app/Providers/AccountServiceProvider.php @@ -14,7 +14,10 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Account\AccountRepository; +use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Repositories\Account\AccountTasker; +use FireflyIII\Repositories\Account\AccountTaskerInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -44,8 +47,6 @@ class AccountServiceProvider extends ServiceProvider { $this->registerRepository(); $this->registerTasker(); - - } /** @@ -54,16 +55,16 @@ class AccountServiceProvider extends ServiceProvider private function registerRepository() { $this->app->bind( - 'FireflyIII\Repositories\Account\AccountRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Account\AccountRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + AccountRepositoryInterface::class, + function (Application $app) { + /** @var AccountRepositoryInterface $repository */ + $repository = app(AccountRepository::class); + + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Account\AccountRepository', $arguments); + return $repository; } ); } @@ -74,16 +75,16 @@ class AccountServiceProvider extends ServiceProvider private function registerTasker() { $this->app->bind( - 'FireflyIII\Repositories\Account\AccountTaskerInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Account\AccountTasker', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + AccountTaskerInterface::class, + function (Application $app) { + /** @var AccountTaskerInterface $tasker */ + $tasker = app(AccountTasker::class); + + if ($app->auth->check()) { + $tasker->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Account\AccountTasker', $arguments); + return $tasker; } ); } diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 56ff3467cf..d8dd3843f5 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -33,7 +33,7 @@ class AppServiceProvider extends ServiceProvider // force root URL. $forcedUrl = env('APP_FORCE_ROOT', ''); - if (strlen($forcedUrl) > 0) { + if (strlen(strval($forcedUrl)) > 0) { URL::forceRootUrl($forcedUrl); } diff --git a/app/Providers/AttachmentServiceProvider.php b/app/Providers/AttachmentServiceProvider.php index 77debb7354..c9f3a9d48d 100644 --- a/app/Providers/AttachmentServiceProvider.php +++ b/app/Providers/AttachmentServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Attachment\AttachmentRepository; +use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,15 @@ class AttachmentServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Attachment\AttachmentRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + AttachmentRepositoryInterface::class, + function (Application $app) { + /** @var AttachmentRepositoryInterface $repository */ + $repository = app(AttachmentRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Attachment\AttachmentRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/BillServiceProvider.php b/app/Providers/BillServiceProvider.php index 7275348a8d..a07e8e37ff 100644 --- a/app/Providers/BillServiceProvider.php +++ b/app/Providers/BillServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Bill\BillRepository; +use FireflyIII\Repositories\Bill\BillRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,16 @@ class BillServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Bill\BillRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Bill\BillRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + BillRepositoryInterface::class, + function (Application $app) { + /** @var BillRepositoryInterface $repository */ + $repository = app(BillRepository::class); + + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Bill\BillRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/BudgetServiceProvider.php b/app/Providers/BudgetServiceProvider.php index 51408c5098..df87739ea6 100644 --- a/app/Providers/BudgetServiceProvider.php +++ b/app/Providers/BudgetServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Budget\BudgetRepository; +use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,15 @@ class BudgetServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Budget\BudgetRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Budget\BudgetRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + BudgetRepositoryInterface::class, + function (Application $app) { + /** @var BudgetRepositoryInterface $repository */ + $repository = app(BudgetRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Budget\BudgetRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/CategoryServiceProvider.php b/app/Providers/CategoryServiceProvider.php index a3deb55f30..bdac9c91f1 100644 --- a/app/Providers/CategoryServiceProvider.php +++ b/app/Providers/CategoryServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Category\CategoryRepository; +use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,15 @@ class CategoryServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Category\CategoryRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Category\CategoryRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + CategoryRepositoryInterface::class, + function (Application $app) { + /** @var CategoryRepository $repository */ + $repository = app(CategoryRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Category\CategoryRepository', $arguments); + return $repository; } ); diff --git a/app/Providers/CrudServiceProvider.php b/app/Providers/CrudServiceProvider.php deleted file mode 100644 index 93acfa1412..0000000000 --- a/app/Providers/CrudServiceProvider.php +++ /dev/null @@ -1,64 +0,0 @@ -registerJournal(); - } - - private function registerJournal() - { - $this->app->bind( - 'FireflyIII\Crud\Split\JournalInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Crud\Split\Journal', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); - } - - return app('FireflyIII\Crud\Split\Journal', $arguments); - } - ); - - } -} diff --git a/app/Providers/CurrencyServiceProvider.php b/app/Providers/CurrencyServiceProvider.php index d95532e072..bfdf535c70 100644 --- a/app/Providers/CurrencyServiceProvider.php +++ b/app/Providers/CurrencyServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Currency\CurrencyRepository; +use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,15 @@ class CurrencyServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Currency\CurrencyRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Currency\CurrencyRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + CurrencyRepositoryInterface::class, + function (Application $app) { + /** @var CurrencyRepository $repository */ + $repository = app(CurrencyRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Currency\CurrencyRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index 215fc5978e..3fcdd8da06 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -56,12 +56,6 @@ class EventServiceProvider extends ServiceProvider 'FireflyIII\Handlers\Events\UpdatedJournalEventHandler@scanBills', 'FireflyIII\Handlers\Events\UpdatedJournalEventHandler@processRules', ], - - // LARAVEL EVENTS: - 'Illuminate\Auth\Events\Logout' => - [ - 'FireflyIII\Handlers\Events\UserEventHandler@logoutUser', - ], ]; /** diff --git a/app/Providers/ExportJobServiceProvider.php b/app/Providers/ExportJobServiceProvider.php index 220a678623..6850f417b5 100644 --- a/app/Providers/ExportJobServiceProvider.php +++ b/app/Providers/ExportJobServiceProvider.php @@ -14,7 +14,10 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\ExportJob\ExportJobRepository; +use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface; +use FireflyIII\Repositories\ImportJob\ImportJobRepository; +use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -33,8 +36,7 @@ class ExportJobServiceProvider extends ServiceProvider */ public function boot() { - $this->exportJob(); - $this->importJob(); + } @@ -45,7 +47,8 @@ class ExportJobServiceProvider extends ServiceProvider */ public function register() { - // + $this->exportJob(); + $this->importJob(); } /** @@ -53,18 +56,16 @@ class ExportJobServiceProvider extends ServiceProvider */ private function exportJob() { - $this->app->bind( - 'FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\ExportJob\ExportJobRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + ExportJobRepositoryInterface::class, + function (Application $app) { + /** @var ExportJobRepository $repository */ + $repository = app(ExportJobRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\ExportJob\ExportJobRepository', $arguments); + return $repository; } ); } @@ -72,16 +73,15 @@ class ExportJobServiceProvider extends ServiceProvider private function importJob() { $this->app->bind( - 'FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\ImportJob\ImportJobRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + ImportJobRepositoryInterface::class, + function (Application $app) { + /** @var ImportJobRepository $repository */ + $repository = app(ImportJobRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\ImportJob\ImportJobRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php index b798f531e0..40f456b4d0 100644 --- a/app/Providers/FireflyServiceProvider.php +++ b/app/Providers/FireflyServiceProvider.php @@ -13,6 +13,28 @@ declare(strict_types = 1); namespace FireflyIII\Providers; +use FireflyIII\Export\Processor; +use FireflyIII\Export\ProcessorInterface; +use FireflyIII\Generator\Chart\Basic\ChartJsGenerator; +use FireflyIII\Generator\Chart\Basic\GeneratorInterface; +use FireflyIII\Helpers\Attachments\AttachmentHelper; +use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; +use FireflyIII\Helpers\Chart\MetaPieChart; +use FireflyIII\Helpers\Chart\MetaPieChartInterface; +use FireflyIII\Helpers\FiscalHelper; +use FireflyIII\Helpers\FiscalHelperInterface; +use FireflyIII\Helpers\Help\Help; +use FireflyIII\Helpers\Help\HelpInterface; +use FireflyIII\Helpers\Report\BalanceReportHelper; +use FireflyIII\Helpers\Report\BalanceReportHelperInterface; +use FireflyIII\Helpers\Report\BudgetReportHelper; +use FireflyIII\Helpers\Report\BudgetReportHelperInterface; +use FireflyIII\Helpers\Report\ReportHelper; +use FireflyIII\Helpers\Report\ReportHelperInterface; +use FireflyIII\Import\ImportProcedure; +use FireflyIII\Import\ImportProcedureInterface; +use FireflyIII\Repositories\User\UserRepository; +use FireflyIII\Repositories\User\UserRepositoryInterface; use FireflyIII\Support\Amount; use FireflyIII\Support\ExpandedForm; use FireflyIII\Support\FireflyConfig; @@ -94,22 +116,22 @@ class FireflyServiceProvider extends ServiceProvider ); // chart generator: - $this->app->bind('FireflyIII\Generator\Chart\Basic\GeneratorInterface', 'FireflyIII\Generator\Chart\Basic\ChartJsGenerator'); + $this->app->bind(GeneratorInterface::class, ChartJsGenerator::class); // chart builder - $this->app->bind('FireflyIII\Helpers\Chart\MetaPieChartInterface', 'FireflyIII\Helpers\Chart\MetaPieChart'); + $this->app->bind(MetaPieChartInterface::class, MetaPieChart::class); // other generators - $this->app->bind('FireflyIII\Export\ProcessorInterface', 'FireflyIII\Export\Processor'); - $this->app->bind('FireflyIII\Import\ImportProcedureInterface', 'FireflyIII\Import\ImportProcedure'); - $this->app->bind('FireflyIII\Repositories\User\UserRepositoryInterface', 'FireflyIII\Repositories\User\UserRepository'); - $this->app->bind('FireflyIII\Helpers\Attachments\AttachmentHelperInterface', 'FireflyIII\Helpers\Attachments\AttachmentHelper'); + $this->app->bind(ProcessorInterface::class, Processor::class); + $this->app->bind(ImportProcedureInterface::class, ImportProcedure::class); + $this->app->bind(UserRepositoryInterface::class, UserRepository::class); + $this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class); - $this->app->bind('FireflyIII\Helpers\Help\HelpInterface', 'FireflyIII\Helpers\Help\Help'); - $this->app->bind('FireflyIII\Helpers\Report\ReportHelperInterface', 'FireflyIII\Helpers\Report\ReportHelper'); - $this->app->bind('FireflyIII\Helpers\FiscalHelperInterface', 'FireflyIII\Helpers\FiscalHelper'); - $this->app->bind('FireflyIII\Helpers\Report\BalanceReportHelperInterface', 'FireflyIII\Helpers\Report\BalanceReportHelper'); - $this->app->bind('FireflyIII\Helpers\Report\BudgetReportHelperInterface', 'FireflyIII\Helpers\Report\BudgetReportHelper'); + $this->app->bind(HelpInterface::class, Help::class); + $this->app->bind(ReportHelperInterface::class, ReportHelper::class); + $this->app->bind(FiscalHelperInterface::class, FiscalHelper::class); + $this->app->bind(BalanceReportHelperInterface::class, BalanceReportHelper::class); + $this->app->bind(BudgetReportHelperInterface::class, BudgetReportHelper::class); } } diff --git a/app/Providers/FireflySessionProvider.php b/app/Providers/FireflySessionProvider.php new file mode 100644 index 0000000000..47dfb1bfe7 --- /dev/null +++ b/app/Providers/FireflySessionProvider.php @@ -0,0 +1,64 @@ +registerSessionManager(); + + $this->registerSessionDriver(); + + $this->app->singleton(StartFireflySession::class); + } + + /** + * Register the session driver instance. + * + * @return void + */ + protected function registerSessionDriver() + { + $this->app->singleton( + 'session.store', function ($app) { + // First, we will create the session manager which is responsible for the + // creation of the various session drivers when they are needed by the + // application instance, and will resolve them on a lazy load basis. + return $app->make('session')->driver(); + } + ); + } + + /** + * Register the session manager instance. + * + * @return void + */ + protected function registerSessionManager() + { + $this->app->singleton( + 'session', function ($app) { + return new SessionManager($app); + } + ); + } +} diff --git a/app/Providers/JournalServiceProvider.php b/app/Providers/JournalServiceProvider.php index 2ac7f61f64..b44c11b760 100644 --- a/app/Providers/JournalServiceProvider.php +++ b/app/Providers/JournalServiceProvider.php @@ -14,7 +14,12 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Collector\JournalCollector; +use FireflyIII\Helpers\Collector\JournalCollectorInterface; +use FireflyIII\Repositories\Journal\JournalRepository; +use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\Journal\JournalTasker; +use FireflyIII\Repositories\Journal\JournalTaskerInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -50,16 +55,16 @@ class JournalServiceProvider extends ServiceProvider private function registerCollector() { $this->app->bind( - 'FireflyIII\Helpers\Collector\JournalCollectorInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Helpers\Collector\JournalCollector', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + JournalCollectorInterface::class, + function (Application $app) { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollector::class); + if ($app->auth->check()) { + $collector->setUser(auth()->user()); } + $collector->startQuery(); - return app('FireflyIII\Helpers\Collector\JournalCollector', $arguments); + return $collector; } ); } @@ -67,16 +72,16 @@ class JournalServiceProvider extends ServiceProvider private function registerRepository() { $this->app->bind( - 'FireflyIII\Repositories\Journal\JournalRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Journal\JournalRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + JournalRepositoryInterface::class, + function (Application $app) { + /** @var JournalRepositoryInterface $repository */ + $repository = app(JournalRepository::class); + if ($app->auth->check()) { + + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Journal\JournalRepository', $arguments); + return $repository; } ); } @@ -84,16 +89,16 @@ class JournalServiceProvider extends ServiceProvider private function registerTasker() { $this->app->bind( - 'FireflyIII\Repositories\Journal\JournalTaskerInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Journal\JournalTasker', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + JournalTaskerInterface::class, + function (Application $app) { + /** @var JournalTaskerInterface $tasker */ + $tasker = app(JournalTasker::class); + + if ($app->auth->check()) { + $tasker->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Journal\JournalTasker', $arguments); + return $tasker; } ); } diff --git a/app/Providers/LogServiceProvider.php b/app/Providers/LogServiceProvider.php new file mode 100644 index 0000000000..dc742d6b80 --- /dev/null +++ b/app/Providers/LogServiceProvider.php @@ -0,0 +1,53 @@ +useDailyFiles( + $this->app->storagePath() . '/logs/firefly-iii.log', $this->maxFiles(), + $this->logLevel() + ); + } + + /** + * Configure the Monolog handlers for the application. + * + * @param \Illuminate\Log\Writer $log + * + * @return void + */ + protected function configureSingleHandler(Writer $log) + { + $log->useFiles( + $this->app->storagePath() . '/logs/firefly-iii.log', + $this->logLevel() + ); + } +} diff --git a/app/Providers/PiggyBankServiceProvider.php b/app/Providers/PiggyBankServiceProvider.php index 11ba540e3c..d91f362114 100644 --- a/app/Providers/PiggyBankServiceProvider.php +++ b/app/Providers/PiggyBankServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\PiggyBank\PiggyBankRepository; +use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -44,16 +45,15 @@ class PiggyBankServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\PiggyBank\PiggyBankRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + PiggyBankRepositoryInterface::class, + function (Application $app) { + /** @var PiggyBankRepository $repository */ + $repository = app(PiggyBankRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\PiggyBank\PiggyBankRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/RuleGroupServiceProvider.php b/app/Providers/RuleGroupServiceProvider.php index bddd6a8480..0a3c8db599 100644 --- a/app/Providers/RuleGroupServiceProvider.php +++ b/app/Providers/RuleGroupServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\RuleGroup\RuleGroupRepository; +use FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -44,16 +45,15 @@ class RuleGroupServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\RuleGroup\RuleGroupRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\RuleGroup\RuleGroupRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + RuleGroupRepositoryInterface::class, + function (Application $app) { + /** @var RuleGroupRepository $repository */ + $repository = app(RuleGroupRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\RuleGroup\RuleGroupRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/RuleServiceProvider.php b/app/Providers/RuleServiceProvider.php index a395e8cda3..9d047d9e74 100644 --- a/app/Providers/RuleServiceProvider.php +++ b/app/Providers/RuleServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Rule\RuleRepository; +use FireflyIII\Repositories\Rule\RuleRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,15 @@ class RuleServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Rule\RuleRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Rule\RuleRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + RuleRepositoryInterface::class, + function (Application $app) { + /** @var RuleRepository $repository */ + $repository = app(RuleRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Rule\RuleRepository', $arguments); + return $repository; } ); } diff --git a/app/Providers/SearchServiceProvider.php b/app/Providers/SearchServiceProvider.php index a7be767e5e..18d5b48c6e 100644 --- a/app/Providers/SearchServiceProvider.php +++ b/app/Providers/SearchServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Support\Search\Search; +use FireflyIII\Support\Search\SearchInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,15 @@ class SearchServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Support\Search\SearchInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Support\Search\Search', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + SearchInterface::class, + function (Application $app) { + /** @var Search $search */ + $search = app(Search::class); + if ($app->auth->check()) { + $search->setUser(auth()->user()); } - return app('FireflyIII\Support\Search\Search', $arguments); + return $search; } ); } diff --git a/app/Providers/TagServiceProvider.php b/app/Providers/TagServiceProvider.php index 8889c9fbeb..b5daa36c6c 100644 --- a/app/Providers/TagServiceProvider.php +++ b/app/Providers/TagServiceProvider.php @@ -14,7 +14,8 @@ declare(strict_types = 1); namespace FireflyIII\Providers; -use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Repositories\Tag\TagRepository; +use FireflyIII\Repositories\Tag\TagRepositoryInterface; use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; @@ -43,16 +44,16 @@ class TagServiceProvider extends ServiceProvider public function register() { $this->app->bind( - 'FireflyIII\Repositories\Tag\TagRepositoryInterface', - function (Application $app, array $arguments) { - if (!isset($arguments[0]) && $app->auth->check()) { - return app('FireflyIII\Repositories\Tag\TagRepository', [auth()->user()]); - } - if (!isset($arguments[0]) && !$app->auth->check()) { - throw new FireflyException('There is no user present.'); + TagRepositoryInterface::class, + function (Application $app) { + /** @var TagRepository $repository */ + $repository = app(TagRepository::class); + + if ($app->auth->check()) { + $repository->setUser(auth()->user()); } - return app('FireflyIII\Repositories\Tag\TagRepository', $arguments); + return $repository; } ); } diff --git a/app/Repositories/Account/AccountRepository.php b/app/Repositories/Account/AccountRepository.php index d740291f68..26ba26b6ea 100644 --- a/app/Repositories/Account/AccountRepository.php +++ b/app/Repositories/Account/AccountRepository.php @@ -43,16 +43,6 @@ class AccountRepository implements AccountRepositoryInterface /** @var array */ private $validFields = ['accountRole', 'ccMonthlyPaymentDate', 'ccType', 'accountNumber', 'currency_id', 'BIC']; - /** - * AttachmentRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * Moved here from account CRUD * @@ -323,6 +313,14 @@ class AccountRepository implements AccountRepositoryInterface return $journal->date; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/Account/AccountRepositoryInterface.php b/app/Repositories/Account/AccountRepositoryInterface.php index 428e48144d..b0ab9b738b 100644 --- a/app/Repositories/Account/AccountRepositoryInterface.php +++ b/app/Repositories/Account/AccountRepositoryInterface.php @@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Account; use Carbon\Carbon; use FireflyIII\Models\Account; use FireflyIII\Models\TransactionJournal; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -124,6 +125,11 @@ interface AccountRepositoryInterface */ public function oldestJournalDate(Account $account): Carbon; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param array $data * diff --git a/app/Repositories/Account/AccountTasker.php b/app/Repositories/Account/AccountTasker.php index 126d084e8d..e5c81eb211 100644 --- a/app/Repositories/Account/AccountTasker.php +++ b/app/Repositories/Account/AccountTasker.php @@ -31,16 +31,6 @@ class AccountTasker implements AccountTaskerInterface /** @var User */ private $user; - /** - * AttachmentRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @see self::amountInPeriod * @@ -108,8 +98,8 @@ class AccountTasker implements AccountTaskerInterface */ public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array { - $ids = $accounts->pluck('id')->toArray(); - $yesterday = clone $start; + $ids = $accounts->pluck('id')->toArray(); + $yesterday = clone $start; $yesterday->subDay(); $startSet = Steam::balancesById($ids, $yesterday); $endSet = Steam::balancesById($ids, $end); @@ -136,13 +126,15 @@ class AccountTasker implements AccountTaskerInterface ]; // get first journal date: - $first = $repository->oldestJournal($account); + $first = $repository->oldestJournal($account); + Log::debug(sprintf('Date of first journal for %s is %s', $account->name, $first->date->format('Y-m-d'))); $entry['start_balance'] = $startSet[$account->id] ?? '0'; $entry['end_balance'] = $endSet[$account->id] ?? '0'; - if (!is_null($first->id) && $yesterday < $first->date && $end >= $first->date) { - // something about balance? + + // first journal exists, and is on start, then this is the actual opening balance: + if (!is_null($first->id) && $first->date->isSameDay($start)) { $entry['start_balance'] = $first->transactions()->where('account_id', $account->id)->first()->amount; - Log::debug(sprintf('Account was opened before %s, so opening balance is %f', $yesterday->format('Y-m-d'), $entry['start_balance'])); + Log::debug(sprintf('Account %s was opened on %s, so opening balance is %f', $account->name, $start->format('Y-m-d'), $entry['start_balance'])); } $return['start'] = bcadd($return['start'], $entry['start_balance']); $return['end'] = bcadd($return['end'], $entry['end_balance']); @@ -155,6 +147,14 @@ class AccountTasker implements AccountTaskerInterface return $return; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * Will return how much money has been going out (ie. spent) by the given account(s). * Alternatively, will return how much money has been coming in (ie. earned) by the given accounts. diff --git a/app/Repositories/Account/AccountTaskerInterface.php b/app/Repositories/Account/AccountTaskerInterface.php index 57fbebaa79..4ea5be74ef 100644 --- a/app/Repositories/Account/AccountTaskerInterface.php +++ b/app/Repositories/Account/AccountTaskerInterface.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\Account; use Carbon\Carbon; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -23,7 +24,6 @@ use Illuminate\Support\Collection; */ interface AccountTaskerInterface { - /** * @param Collection $accounts * @param Collection $excluded @@ -57,4 +57,9 @@ interface AccountTaskerInterface */ public function getAccountReport(Collection $accounts, Carbon $start, Carbon $end): array; + /** + * @param User $user + */ + public function setUser(User $user); + } diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php index 1bc9401624..79a481e4ab 100644 --- a/app/Repositories/Attachment/AttachmentRepository.php +++ b/app/Repositories/Attachment/AttachmentRepository.php @@ -14,12 +14,12 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\Attachment; use Carbon\Carbon; +use Crypt; use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Models\Attachment; use FireflyIII\User; use Illuminate\Support\Collection; use Storage; -use Crypt; /** * Class AttachmentRepository @@ -31,16 +31,6 @@ class AttachmentRepository implements AttachmentRepositoryInterface /** @var User */ private $user; - /** - * AttachmentRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param Attachment $attachment * @@ -117,6 +107,14 @@ class AttachmentRepository implements AttachmentRepositoryInterface return ''; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param Attachment $attachment * @param array $data diff --git a/app/Repositories/Attachment/AttachmentRepositoryInterface.php b/app/Repositories/Attachment/AttachmentRepositoryInterface.php index 9e12092c70..cc7cb887f8 100644 --- a/app/Repositories/Attachment/AttachmentRepositoryInterface.php +++ b/app/Repositories/Attachment/AttachmentRepositoryInterface.php @@ -15,6 +15,7 @@ namespace FireflyIII\Repositories\Attachment; use Carbon\Carbon; use FireflyIII\Models\Attachment; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -59,6 +60,11 @@ interface AttachmentRepositoryInterface */ public function getContent(Attachment $attachment): string; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param Attachment $attachment * @param array $attachmentData diff --git a/app/Repositories/Bill/BillRepository.php b/app/Repositories/Bill/BillRepository.php index d3bfa01572..545a29fb96 100644 --- a/app/Repositories/Bill/BillRepository.php +++ b/app/Repositories/Bill/BillRepository.php @@ -37,16 +37,6 @@ class BillRepository implements BillRepositoryInterface /** @var User */ private $user; - /** - * BillRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param Bill $bill * @@ -520,6 +510,14 @@ class BillRepository implements BillRepositoryInterface } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/Bill/BillRepositoryInterface.php b/app/Repositories/Bill/BillRepositoryInterface.php index c2c6cd223d..2e07d12d93 100644 --- a/app/Repositories/Bill/BillRepositoryInterface.php +++ b/app/Repositories/Bill/BillRepositoryInterface.php @@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Bill; use Carbon\Carbon; use FireflyIII\Models\Bill; use FireflyIII\Models\TransactionJournal; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -25,7 +26,6 @@ use Illuminate\Support\Collection; */ interface BillRepositoryInterface { - /** * @param Bill $bill * @@ -159,6 +159,11 @@ interface BillRepositoryInterface */ public function scan(Bill $bill, TransactionJournal $journal): bool; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param array $data * diff --git a/app/Repositories/Budget/BudgetRepository.php b/app/Repositories/Budget/BudgetRepository.php index 7c8d2f6391..9b4f985390 100644 --- a/app/Repositories/Budget/BudgetRepository.php +++ b/app/Repositories/Budget/BudgetRepository.php @@ -38,16 +38,6 @@ class BudgetRepository implements BudgetRepositoryInterface /** @var User */ private $user; - /** - * BudgetRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @return bool */ @@ -433,6 +423,14 @@ class BudgetRepository implements BudgetRepositoryInterface return true; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param Collection $budgets * @param Collection $accounts @@ -444,7 +442,8 @@ class BudgetRepository implements BudgetRepositoryInterface public function spentInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end): string { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setBudgets($budgets); if ($accounts->count() > 0) { @@ -470,7 +469,8 @@ class BudgetRepository implements BudgetRepositoryInterface public function spentInPeriodWoBudget(Collection $accounts, Carbon $start, Carbon $end): string { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutBudget(); if ($accounts->count() > 0) { diff --git a/app/Repositories/Budget/BudgetRepositoryInterface.php b/app/Repositories/Budget/BudgetRepositoryInterface.php index ee9eba1641..906a4827ae 100644 --- a/app/Repositories/Budget/BudgetRepositoryInterface.php +++ b/app/Repositories/Budget/BudgetRepositoryInterface.php @@ -17,6 +17,7 @@ use Carbon\Carbon; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\TransactionCurrency; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -26,7 +27,6 @@ use Illuminate\Support\Collection; */ interface BudgetRepositoryInterface { - /** * @return bool */ @@ -149,6 +149,11 @@ interface BudgetRepositoryInterface */ public function setAvailableBudget(TransactionCurrency $currency, Carbon $start, Carbon $end, string $amount): bool; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param Collection $budgets * @param Collection $accounts diff --git a/app/Repositories/Category/CategoryRepository.php b/app/Repositories/Category/CategoryRepository.php index 32c2eb2135..bed2d5847f 100644 --- a/app/Repositories/Category/CategoryRepository.php +++ b/app/Repositories/Category/CategoryRepository.php @@ -34,16 +34,6 @@ class CategoryRepository implements CategoryRepositoryInterface /** @var User */ private $user; - /** - * CategoryRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param Category $category * @@ -67,7 +57,8 @@ class CategoryRepository implements CategoryRepositoryInterface public function earnedInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAccounts($accounts)->setCategories($categories); $set = $collector->getJournals(); $sum = strval($set->sum('transaction_amount')); @@ -384,6 +375,14 @@ class CategoryRepository implements CategoryRepositoryInterface return $result; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param Collection $categories * @param Collection $accounts @@ -395,7 +394,8 @@ class CategoryRepository implements CategoryRepositoryInterface public function spentInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setCategories($categories); @@ -423,7 +423,8 @@ class CategoryRepository implements CategoryRepositoryInterface public function spentInPeriodWithoutCategory(Collection $accounts, Carbon $start, Carbon $end): string { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->withoutCategory(); if ($accounts->count() > 0) { diff --git a/app/Repositories/Category/CategoryRepositoryInterface.php b/app/Repositories/Category/CategoryRepositoryInterface.php index 1194fbbf74..9e89a78f50 100644 --- a/app/Repositories/Category/CategoryRepositoryInterface.php +++ b/app/Repositories/Category/CategoryRepositoryInterface.php @@ -15,6 +15,7 @@ namespace FireflyIII\Repositories\Category; use Carbon\Carbon; use FireflyIII\Models\Category; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -121,6 +122,11 @@ interface CategoryRepositoryInterface */ public function periodIncomeNoCategory(Collection $accounts, Carbon $start, Carbon $end): array; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param Collection $categories * @param Collection $accounts diff --git a/app/Repositories/Currency/CurrencyRepository.php b/app/Repositories/Currency/CurrencyRepository.php index d2eaed1c30..b053780cac 100644 --- a/app/Repositories/Currency/CurrencyRepository.php +++ b/app/Repositories/Currency/CurrencyRepository.php @@ -30,16 +30,6 @@ class CurrencyRepository implements CurrencyRepositoryInterface /** @var User */ private $user; - /** - * CategoryRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param TransactionCurrency $currency * @@ -188,6 +178,14 @@ class CurrencyRepository implements CurrencyRepositoryInterface return $preferred; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/Currency/CurrencyRepositoryInterface.php b/app/Repositories/Currency/CurrencyRepositoryInterface.php index 4ccebe40b0..63eb9bf0b5 100644 --- a/app/Repositories/Currency/CurrencyRepositoryInterface.php +++ b/app/Repositories/Currency/CurrencyRepositoryInterface.php @@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Currency; use FireflyIII\Models\Preference; use FireflyIII\Models\TransactionCurrency; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -94,6 +95,11 @@ interface CurrencyRepositoryInterface */ public function getCurrencyByPreference(Preference $preference): TransactionCurrency; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param array $data * diff --git a/app/Repositories/ExportJob/ExportJobRepository.php b/app/Repositories/ExportJob/ExportJobRepository.php index b83818284a..aa956f901e 100644 --- a/app/Repositories/ExportJob/ExportJobRepository.php +++ b/app/Repositories/ExportJob/ExportJobRepository.php @@ -29,16 +29,6 @@ class ExportJobRepository implements ExportJobRepositoryInterface /** @var User */ private $user; - /** - * ExportJobRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param ExportJob $job * @param string $status @@ -149,4 +139,12 @@ class ExportJobRepository implements ExportJobRepositoryInterface return $content; } + + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } } diff --git a/app/Repositories/ExportJob/ExportJobRepositoryInterface.php b/app/Repositories/ExportJob/ExportJobRepositoryInterface.php index 6f3c7a30b1..7e93663ea5 100644 --- a/app/Repositories/ExportJob/ExportJobRepositoryInterface.php +++ b/app/Repositories/ExportJob/ExportJobRepositoryInterface.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\ExportJob; use FireflyIII\Models\ExportJob; +use FireflyIII\User; /** * Interface ExportJobRepositoryInterface @@ -61,4 +62,9 @@ interface ExportJobRepositoryInterface */ public function getContent(ExportJob $job): string; + /** + * @param User $user + */ + public function setUser(User $user); + } diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php index d7f4ac30cf..0eec759e5b 100644 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ b/app/Repositories/ImportJob/ImportJobRepository.php @@ -28,16 +28,6 @@ class ImportJobRepository implements ImportJobRepositoryInterface /** @var User */ private $user; - /** - * ExportJobRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param string $fileType * @@ -95,4 +85,12 @@ class ImportJobRepository implements ImportJobRepositoryInterface return $result; } + + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } } diff --git a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php index a17d9ca62c..5bb2149fbe 100644 --- a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php +++ b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\ImportJob; use FireflyIII\Models\ImportJob; +use FireflyIII\User; /** * Interface ImportJobRepositoryInterface @@ -35,4 +36,9 @@ interface ImportJobRepositoryInterface * @return ImportJob */ public function findByKey(string $key): ImportJob; + + /** + * @param User $user + */ + public function setUser(User $user); } diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index 9ee336cddf..31ac868afa 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -43,16 +43,6 @@ class JournalRepository implements JournalRepositoryInterface /** @var array */ private $validMetaFields = ['interest_date', 'book_date', 'process_date', 'due_date', 'payment_date', 'invoice_date', 'internal_reference', 'notes']; - /** - * JournalRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param TransactionJournal $journal * @param TransactionType $type @@ -145,6 +135,14 @@ class JournalRepository implements JournalRepositoryInterface return TransactionType::orderBy('type', 'ASC')->get(); } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index 0b62a5729a..f1f5438ad4 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Journal; use FireflyIII\Models\Account; use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionType; +use FireflyIII\User; use Illuminate\Support\Collection; use Illuminate\Support\MessageBag; @@ -26,7 +27,6 @@ use Illuminate\Support\MessageBag; */ interface JournalRepositoryInterface { - /** * @param TransactionJournal $journal * @param TransactionType $type @@ -37,11 +37,6 @@ interface JournalRepositoryInterface */ public function convert(TransactionJournal $journal, TransactionType $type, Account $source, Account $destination): MessageBag; - /** - * @return Collection - */ - public function getTransactionTypes(): Collection; - /** * Deletes a journal. * @@ -67,6 +62,15 @@ interface JournalRepositoryInterface */ public function first(): TransactionJournal; + /** + * @return Collection + */ + public function getTransactionTypes(): Collection; + + /** + * @param User $user + */ + public function setUser(User $user); /** * @param array $data diff --git a/app/Repositories/Journal/JournalTasker.php b/app/Repositories/Journal/JournalTasker.php index eb77c77e6f..7a75d8a871 100644 --- a/app/Repositories/Journal/JournalTasker.php +++ b/app/Repositories/Journal/JournalTasker.php @@ -13,7 +13,6 @@ declare(strict_types = 1); namespace FireflyIII\Repositories\Journal; -use Crypt; use DB; use FireflyIII\Models\AccountType; use FireflyIII\Models\PiggyBankEvent; @@ -23,6 +22,7 @@ use FireflyIII\User; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; +use Steam; /** * Class JournalTasker @@ -35,15 +35,6 @@ class JournalTasker implements JournalTaskerInterface /** @var User */ private $user; - /** - * JournalRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } /** * @param TransactionJournal $journal @@ -122,7 +113,7 @@ class JournalTasker implements JournalTaskerInterface 'source_amount' => $entry->amount, 'description' => $entry->description, 'source_account_id' => $entry->account_id, - 'source_account_name' => intval($entry->account_encrypted) === 1 ? Crypt::decrypt($entry->account_name) : $entry->account_name, + 'source_account_name' => Steam::decrypt(intval($entry->account_encrypted), $entry->account_name), 'source_account_type' => $entry->account_type, 'source_account_before' => $sourceBalance, 'source_account_after' => bcadd($sourceBalance, $entry->amount), @@ -130,8 +121,7 @@ class JournalTasker implements JournalTaskerInterface 'destination_amount' => bcmul($entry->amount, '-1'), 'destination_account_id' => $entry->destination_account_id, 'destination_account_type' => $entry->destination_account_type, - 'destination_account_name' => - intval($entry->destination_account_encrypted) === 1 ? Crypt::decrypt($entry->destination_account_name) : $entry->destination_account_name, + 'destination_account_name' => Steam::decrypt(intval($entry->destination_account_encrypted), $entry->destination_account_name), 'destination_account_before' => $destinationBalance, 'destination_account_after' => bcadd($destinationBalance, bcmul($entry->amount, '-1')), 'budget_id' => is_null($budget) ? 0 : $budget->id, @@ -152,6 +142,14 @@ class JournalTasker implements JournalTaskerInterface return $transactions; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * Collect the balance of an account before the given transaction has hit. This is tricky, because * the balance does not depend on the transaction itself but the journal it's part of. And of course diff --git a/app/Repositories/Journal/JournalTaskerInterface.php b/app/Repositories/Journal/JournalTaskerInterface.php index 058bc63733..1273f69c3a 100644 --- a/app/Repositories/Journal/JournalTaskerInterface.php +++ b/app/Repositories/Journal/JournalTaskerInterface.php @@ -15,6 +15,7 @@ namespace FireflyIII\Repositories\Journal; use FireflyIII\Models\TransactionJournal; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -24,7 +25,6 @@ use Illuminate\Support\Collection; */ interface JournalTaskerInterface { - /** * @param TransactionJournal $journal * @@ -41,4 +41,9 @@ interface JournalTaskerInterface * @return array */ public function getTransactionsOverview(TransactionJournal $journal): array; + + /** + * @param User $user + */ + public function setUser(User $user); } diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index 5a9f07704c..1f14467a5b 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -32,16 +32,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface /** @var User */ private $user; - /** - * PiggyBankRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @param PiggyBank $piggyBank * @param string $amount @@ -167,6 +157,14 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface return true; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index aae01702d7..a2da326d86 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -15,6 +15,7 @@ namespace FireflyIII\Repositories\PiggyBank; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBankEvent; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -98,6 +99,10 @@ interface PiggyBankRepositoryInterface */ public function setOrder(int $piggyBankId, int $order): bool; + /** + * @param User $user + */ + public function setUser(User $user); /** * Store new piggy bank. diff --git a/app/Repositories/Rule/RuleRepository.php b/app/Repositories/Rule/RuleRepository.php index 4b7ce00433..7e0487be63 100644 --- a/app/Repositories/Rule/RuleRepository.php +++ b/app/Repositories/Rule/RuleRepository.php @@ -30,16 +30,6 @@ class RuleRepository implements RuleRepositoryInterface /** @var User */ private $user; - /** - * BillRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @return int */ @@ -218,6 +208,14 @@ class RuleRepository implements RuleRepositoryInterface } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/Rule/RuleRepositoryInterface.php b/app/Repositories/Rule/RuleRepositoryInterface.php index 518417d94a..6ca1456214 100644 --- a/app/Repositories/Rule/RuleRepositoryInterface.php +++ b/app/Repositories/Rule/RuleRepositoryInterface.php @@ -17,6 +17,7 @@ use FireflyIII\Models\Rule; use FireflyIII\Models\RuleAction; use FireflyIII\Models\RuleGroup; use FireflyIII\Models\RuleTrigger; +use FireflyIII\User; /** * Interface RuleRepositoryInterface @@ -25,7 +26,6 @@ use FireflyIII\Models\RuleTrigger; */ interface RuleRepositoryInterface { - /** * @return int */ @@ -94,6 +94,11 @@ interface RuleRepositoryInterface */ public function resetRulesInGroupOrder(RuleGroup $ruleGroup): bool; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param array $data * diff --git a/app/Repositories/RuleGroup/RuleGroupRepository.php b/app/Repositories/RuleGroup/RuleGroupRepository.php index b294e19937..404e2f9d2f 100644 --- a/app/Repositories/RuleGroup/RuleGroupRepository.php +++ b/app/Repositories/RuleGroup/RuleGroupRepository.php @@ -30,16 +30,6 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface /** @var User */ private $user; - /** - * BillRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * @return int */ @@ -230,6 +220,14 @@ class RuleGroupRepository implements RuleGroupRepositoryInterface } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + /** * @param array $data * diff --git a/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php b/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php index 985a121b92..c365fca704 100644 --- a/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php +++ b/app/Repositories/RuleGroup/RuleGroupRepositoryInterface.php @@ -26,7 +26,6 @@ use Illuminate\Support\Collection; interface RuleGroupRepositoryInterface { - /** * * @@ -92,6 +91,11 @@ interface RuleGroupRepositoryInterface */ public function resetRulesInGroupOrder(RuleGroup $ruleGroup): bool; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param array $data * diff --git a/app/Repositories/Tag/TagRepository.php b/app/Repositories/Tag/TagRepository.php index 8145be1151..57bade58b5 100644 --- a/app/Repositories/Tag/TagRepository.php +++ b/app/Repositories/Tag/TagRepository.php @@ -34,16 +34,6 @@ class TagRepository implements TagRepositoryInterface /** @var User */ private $user; - /** - * TagRepository constructor. - * - * @param User $user - */ - public function __construct(User $user) - { - $this->user = $user; - } - /** * * @param TransactionJournal $journal @@ -90,6 +80,25 @@ class TagRepository implements TagRepositoryInterface return true; } + /** + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function earnedInPeriod(Tag $tag, Carbon $start, Carbon $end): string + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); + $collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAllAssetAccounts()->setTag($tag); + $set = $collector->getJournals(); + $sum = strval($set->sum('transaction_amount')); + + return $sum; + } + /** * @param int $tagId * @@ -169,6 +178,33 @@ class TagRepository implements TagRepositoryInterface return new Carbon; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + + /** + * @param Tag $tag + * @param Carbon $start + * @param Carbon $end + * + * @return string + */ + public function spentInPeriod(Tag $tag, Carbon $start, Carbon $end): string + { + /** @var JournalCollectorInterface $collector */ + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); + $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAllAssetAccounts()->setTag($tag); + $set = $collector->getJournals(); + $sum = strval($set->sum('transaction_amount')); + + return $sum; + } + /** * @param array $data * @@ -385,40 +421,4 @@ class TagRepository implements TagRepositoryInterface return false; } - - /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end - * - * @return string - */ - public function earnedInPeriod(Tag $tag, Carbon $start, Carbon $end): string - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); - $collector->setRange($start, $end)->setTypes([TransactionType::DEPOSIT])->setAllAssetAccounts()->setTag($tag); - $set = $collector->getJournals(); - $sum = strval($set->sum('transaction_amount')); - - return $sum; - } - - /** - * @param Tag $tag - * @param Carbon $start - * @param Carbon $end - * - * @return string - */ - public function spentInPeriod(Tag $tag, Carbon $start, Carbon $end): string - { - /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); - $collector->setRange($start, $end)->setTypes([TransactionType::WITHDRAWAL])->setAllAssetAccounts()->setTag($tag); - $set = $collector->getJournals(); - $sum = strval($set->sum('transaction_amount')); - - return $sum; - } } diff --git a/app/Repositories/Tag/TagRepositoryInterface.php b/app/Repositories/Tag/TagRepositoryInterface.php index 64bf47c44e..b360e7d436 100644 --- a/app/Repositories/Tag/TagRepositoryInterface.php +++ b/app/Repositories/Tag/TagRepositoryInterface.php @@ -16,6 +16,7 @@ namespace FireflyIII\Repositories\Tag; use Carbon\Carbon; use FireflyIII\Models\Tag; use FireflyIII\Models\TransactionJournal; +use FireflyIII\User; use Illuminate\Support\Collection; @@ -89,6 +90,11 @@ interface TagRepositoryInterface */ public function lastUseDate(Tag $tag): Carbon; + /** + * @param User $user + */ + public function setUser(User $user); + /** * @param Tag $tag * @param Carbon $start diff --git a/app/Repositories/User/UserRepositoryInterface.php b/app/Repositories/User/UserRepositoryInterface.php index 93e34a7a14..9e2bb096b3 100644 --- a/app/Repositories/User/UserRepositoryInterface.php +++ b/app/Repositories/User/UserRepositoryInterface.php @@ -24,6 +24,7 @@ use Illuminate\Support\Collection; */ interface UserRepositoryInterface { + /** * Returns a collection of all users. * diff --git a/app/Rules/Actions/SetBudget.php b/app/Rules/Actions/SetBudget.php index 90d7aa6d18..7797501e2b 100644 --- a/app/Rules/Actions/SetBudget.php +++ b/app/Rules/Actions/SetBudget.php @@ -50,10 +50,11 @@ class SetBudget implements ActionInterface public function act(TransactionJournal $journal): bool { /** @var BudgetRepositoryInterface $repository */ - $repository = app(BudgetRepositoryInterface::class, [$journal->user]); - $search = $this->action->action_value; - $budgets = $repository->getActiveBudgets(); - $budget = $budgets->filter( + $repository = app(BudgetRepositoryInterface::class); + $repository->setUser($journal->user); + $search = $this->action->action_value; + $budgets = $repository->getActiveBudgets(); + $budget = $budgets->filter( function (Budget $current) use ($search) { return $current->name == $search; } diff --git a/app/Rules/Actions/SetDestinationAccount.php b/app/Rules/Actions/SetDestinationAccount.php index 829c4928c4..33ca3d27c3 100644 --- a/app/Rules/Actions/SetDestinationAccount.php +++ b/app/Rules/Actions/SetDestinationAccount.php @@ -60,8 +60,9 @@ class SetDestinationAccount implements ActionInterface public function act(TransactionJournal $journal): bool { $this->journal = $journal; - $this->repository = app(AccountRepositoryInterface::class, [$journal->user]); - $count = $journal->transactions()->count(); + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser($journal->user); + $count = $journal->transactions()->count(); if ($count > 2) { Log::error(sprintf('Cannot change destination account of journal #%d because it is a split journal.', $journal->id)); diff --git a/app/Rules/Actions/SetSourceAccount.php b/app/Rules/Actions/SetSourceAccount.php index 5e625fe886..07f0125d4a 100644 --- a/app/Rules/Actions/SetSourceAccount.php +++ b/app/Rules/Actions/SetSourceAccount.php @@ -60,8 +60,9 @@ class SetSourceAccount implements ActionInterface public function act(TransactionJournal $journal): bool { $this->journal = $journal; - $this->repository = app(AccountRepositoryInterface::class, [$journal->user]); - $count = $journal->transactions()->count(); + $this->repository = app(AccountRepositoryInterface::class); + $this->repository->setUser($journal->user); + $count = $journal->transactions()->count(); if ($count > 2) { Log::error(sprintf('Cannot change source account of journal #%d because it is a split journal.', $journal->id)); diff --git a/app/Rules/TransactionMatcher.php b/app/Rules/TransactionMatcher.php index acac7c8521..5241e4f84c 100644 --- a/app/Rules/TransactionMatcher.php +++ b/app/Rules/TransactionMatcher.php @@ -78,7 +78,8 @@ class TransactionMatcher do { // Fetch a batch of transactions from the database /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [auth()->user()]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser(auth()->user()); $collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page)->setTypes($this->transactionTypes); $set = $collector->getPaginatedJournals(); Log::debug(sprintf('Found %d journals to check. ', $set->count())); diff --git a/app/Rules/Triggers/AbstractTrigger.php b/app/Rules/Triggers/AbstractTrigger.php index 0fd9a3bfd8..d38e1dcd9f 100644 --- a/app/Rules/Triggers/AbstractTrigger.php +++ b/app/Rules/Triggers/AbstractTrigger.php @@ -75,7 +75,6 @@ class AbstractTrigger } - /** * @param RuleTrigger $trigger * @param TransactionJournal $journal diff --git a/app/Rules/Triggers/AmountExactly.php b/app/Rules/Triggers/AmountExactly.php index cef4d8315d..e7984deb02 100644 --- a/app/Rules/Triggers/AmountExactly.php +++ b/app/Rules/Triggers/AmountExactly.php @@ -60,7 +60,7 @@ final class AmountExactly extends AbstractTrigger implements TriggerInterface { $amount = $journal->destination_amount ?? TransactionJournal::amountPositive($journal); $compare = $this->triggerValue; - $result = bccomp($amount, $compare, 4); + $result = bccomp($amount, $compare); if ($result === 0) { Log::debug(sprintf('RuleTrigger AmountExactly for journal #%d: %d matches %d exactly, so return true', $journal->id, $amount, $compare)); diff --git a/app/Rules/Triggers/AmountLess.php b/app/Rules/Triggers/AmountLess.php index cbf4e61ac3..1c856c6796 100644 --- a/app/Rules/Triggers/AmountLess.php +++ b/app/Rules/Triggers/AmountLess.php @@ -60,7 +60,7 @@ final class AmountLess extends AbstractTrigger implements TriggerInterface { $amount = $journal->destination_amount ?? TransactionJournal::amountPositive($journal); $compare = $this->triggerValue; - $result = bccomp($amount, $compare, 4); + $result = bccomp($amount, $compare); if ($result === -1) { Log::debug(sprintf('RuleTrigger AmountLess for journal #%d: %d is less than %d, so return true', $journal->id, $amount, $compare)); diff --git a/app/Rules/Triggers/AmountMore.php b/app/Rules/Triggers/AmountMore.php index d44cca0071..d8a7ce1643 100644 --- a/app/Rules/Triggers/AmountMore.php +++ b/app/Rules/Triggers/AmountMore.php @@ -66,7 +66,7 @@ final class AmountMore extends AbstractTrigger implements TriggerInterface { $amount = $journal->destination_amount ?? TransactionJournal::amountPositive($journal); $compare = $this->triggerValue; - $result = bccomp($amount, $compare, 4); + $result = bccomp($amount, $compare); if ($result === 1) { Log::debug(sprintf('RuleTrigger AmountMore for journal #%d: %d is more than %d, so return true', $journal->id, $amount, $compare)); diff --git a/app/Support/Binder/TagList.php b/app/Support/Binder/TagList.php new file mode 100644 index 0000000000..b1c42bb4c8 --- /dev/null +++ b/app/Support/Binder/TagList.php @@ -0,0 +1,52 @@ +check()) { + $tags = explode(',', $value); + /** @var TagRepositoryInterface $repository */ + $repository = app(TagRepositoryInterface::class); + $allTags = $repository->get(); + $set = $allTags->filter( + function (Tag $tag) use ($tags) { + return in_array($tag->tag, $tags); + } + ); + + if ($set->count() > 0) { + return $set; + } + } + throw new NotFoundHttpException; + } +} diff --git a/app/Support/Search/Modifier.php b/app/Support/Search/Modifier.php new file mode 100644 index 0000000000..d61b64f020 --- /dev/null +++ b/app/Support/Search/Modifier.php @@ -0,0 +1,212 @@ +transaction_amount); + + $compare = bccomp($amount, $transactionAmount); + Log::debug(sprintf('%s vs %s is %d', $amount, $transactionAmount, $compare)); + + return $compare === $expected; + } + + public static function apply(array $modifier, Transaction $transaction): bool + { + switch ($modifier['type']) { + default: + throw new FireflyException(sprintf('Search modifier "%s" is not (yet) supported. Sorry!', $modifier['type'])); + break; + case 'amount': + case 'amount_is': + $res = Modifier::amountCompare($transaction, $modifier['value'], 0); + Log::debug(sprintf('Amount is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'amount_min': + case 'amount_less': + $res = Modifier::amountCompare($transaction, $modifier['value'], 1); + Log::debug(sprintf('Amount less than %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'amount_max': + case 'amount_more': + $res = Modifier::amountCompare($transaction, $modifier['value'], -1); + Log::debug(sprintf('Amount more than %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'source': + $res = Modifier::stringCompare($transaction->account_name, $modifier['value']); + Log::debug(sprintf('Source is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'destination': + $res = Modifier::stringCompare($transaction->opposing_account_name, $modifier['value']); + Log::debug(sprintf('Destination is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'category': + $res = Modifier::category($transaction, $modifier['value']); + Log::debug(sprintf('Category is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'budget': + $res = Modifier::budget($transaction, $modifier['value']); + Log::debug(sprintf('Budget is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'bill': + $res = Modifier::stringCompare(strval($transaction->bill_name), $modifier['value']); + Log::debug(sprintf('Bill is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'type': + $res = Modifier::stringCompare($transaction->transaction_type_type, $modifier['value']); + Log::debug(sprintf('Transaction type is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'date': + case 'on': + $res = Modifier::sameDate($transaction->date, $modifier['value']); + Log::debug(sprintf('Date is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'date_before': + case 'before': + $res = Modifier::dateBefore($transaction->date, $modifier['value']); + Log::debug(sprintf('Date is %s? %s', $modifier['value'], var_export($res, true))); + break; + case 'date_after': + case 'after': + $res = Modifier::dateAfter($transaction->date, $modifier['value']); + Log::debug(sprintf('Date is %s? %s', $modifier['value'], var_export($res, true))); + break; + } + + return $res; + } + + /** + * @param Carbon $date + * @param string $compare + * + * @return bool + */ + public static function dateAfter(Carbon $date, string $compare): bool + { + try { + $compareDate = new Carbon($compare); + } catch (Exception $e) { + return false; + } + + return $date->greaterThanOrEqualTo($compareDate); + } + + /** + * @param Carbon $date + * @param string $compare + * + * @return bool + */ + public static function dateBefore(Carbon $date, string $compare): bool + { + try { + $compareDate = new Carbon($compare); + } catch (Exception $e) { + return false; + } + + return $date->lessThanOrEqualTo($compareDate); + } + + /** + * @param Carbon $date + * @param string $compare + * + * @return bool + */ + public static function sameDate(Carbon $date, string $compare): bool + { + try { + $compareDate = new Carbon($compare); + } catch (Exception $e) { + return false; + } + + return $compareDate->isSameDay($date); + } + + /** + * @param string $haystack + * @param string $needle + * + * @return bool + */ + public static function stringCompare(string $haystack, string $needle): bool + { + $res = !(strpos(strtolower($haystack), strtolower($needle)) === false); + Log::debug(sprintf('"%s" is in "%s"? %s', $needle, $haystack, var_export($res, true))); + + return $res; + + } + + /** + * @param Transaction $transaction + * @param string $search + * + * @return bool + */ + private static function budget(Transaction $transaction, string $search): bool + { + $journalBudget = ''; + if (!is_null($transaction->transaction_journal_budget_name)) { + $journalBudget = Steam::decrypt(intval($transaction->transaction_journal_budget_encrypted), $transaction->transaction_journal_budget_name); + } + $transactionBudget = ''; + if (!is_null($transaction->transaction_budget_name)) { + $journalBudget = Steam::decrypt(intval($transaction->transaction_budget_encrypted), $transaction->transaction_budget_name); + } + + return self::stringCompare($journalBudget, $search) || self::stringCompare($transactionBudget, $search); + } + + /** + * @param Transaction $transaction + * @param string $search + * + * @return bool + */ + private static function category(Transaction $transaction, string $search): bool + { + $journalCategory = ''; + if (!is_null($transaction->transaction_journal_category_name)) { + $journalCategory = Steam::decrypt(intval($transaction->transaction_journal_category_encrypted), $transaction->transaction_journal_category_name); + } + $transactionCategory = ''; + if (!is_null($transaction->transaction_category_name)) { + $journalCategory = Steam::decrypt(intval($transaction->transaction_category_encrypted), $transaction->transaction_category_name); + } + + return self::stringCompare($journalCategory, $search) || self::stringCompare($transactionCategory, $search); + } +} \ No newline at end of file diff --git a/app/Support/Search/Search.php b/app/Support/Search/Search.php index c71e1e2985..cc6bd5e9f3 100644 --- a/app/Support/Search/Search.php +++ b/app/Support/Search/Search.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Support\Search; +use FireflyIII\Exceptions\FireflyException; use FireflyIII\Helpers\Collector\JournalCollectorInterface; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; @@ -34,29 +35,66 @@ class Search implements SearchInterface { /** @var int */ private $limit = 100; + /** @var Collection */ + private $modifiers; /** @var User */ private $user; + /** @var array */ + private $validModifiers = []; + /** @var array */ + private $words = []; /** - * AttachmentRepository constructor. - * - * @param User $user + * Search constructor. */ - public function __construct(User $user) + public function __construct() { - $this->user = $user; + $this->modifiers = new Collection; + $this->validModifiers = config('firefly.search_modifiers'); + } + + /** + * @return string + */ + public function getWordsAsString(): string + { + return join(' ', $this->words); + } + + /** + * @return bool + */ + public function hasModifiers(): bool + { + return $this->modifiers->count() > 0; + } + + /** + * @param string $query + */ + public function parseQuery(string $query) + { + $filteredQuery = $query; + $pattern = '/[a-z_]*:[0-9a-z-.]*/i'; + $matches = []; + preg_match_all($pattern, $query, $matches); + + foreach ($matches[0] as $match) { + $this->extractModifier($match); + $filteredQuery = str_replace($match, '', $filteredQuery); + } + $filteredQuery = trim(str_replace(['"', "'"], '', $filteredQuery)); + if (strlen($filteredQuery) > 0) { + $this->words = array_map('trim', explode(' ', $filteredQuery)); + } } /** - * The search will assume that the user does not have so many accounts - * that this search should be paginated. - * - * @param array $words - * * @return Collection */ - public function searchAccounts(array $words): Collection + public function searchAccounts(): Collection { + $words = $this->words; $accounts = $this->user->accounts() ->accountTypeIn([AccountType::DEFAULT, AccountType::ASSET, AccountType::EXPENSE, AccountType::REVENUE, AccountType::BENEFICIARY]) ->get(['accounts.*']); @@ -77,14 +115,13 @@ class Search implements SearchInterface } /** - * @param array $words - * * @return Collection */ - public function searchBudgets(array $words): Collection + public function searchBudgets(): Collection { /** @var Collection $set */ - $set = auth()->user()->budgets()->get(); + $set = auth()->user()->budgets()->get(); + $words = $this->words; /** @var Collection $result */ $result = $set->filter( function (Budget $budget) use ($words) { @@ -102,14 +139,11 @@ class Search implements SearchInterface } /** - * Search assumes the user does not have that many categories. So no paginated search. - * - * @param array $words - * * @return Collection */ - public function searchCategories(array $words): Collection + public function searchCategories(): Collection { + $words = $this->words; $categories = $this->user->categories()->get(); /** @var Collection $result */ $result = $categories->filter( @@ -127,15 +161,12 @@ class Search implements SearchInterface } /** - * - * @param array $words - * * @return Collection */ - public function searchTags(array $words): Collection + public function searchTags(): Collection { - $tags = $this->user->tags()->get(); - + $words = $this->words; + $tags = $this->user->tags()->get(); /** @var Collection $result */ $result = $tags->filter( function (Tag $tag) use ($words) { @@ -152,11 +183,9 @@ class Search implements SearchInterface } /** - * @param array $words - * * @return Collection */ - public function searchTransactions(array $words): Collection + public function searchTransactions(): Collection { $pageSize = 100; $processed = 0; @@ -164,21 +193,23 @@ class Search implements SearchInterface $result = new Collection(); do { /** @var JournalCollectorInterface $collector */ - $collector = app(JournalCollectorInterface::class, [$this->user]); + $collector = app(JournalCollectorInterface::class); + $collector->setUser($this->user); $collector->setAllAssetAccounts()->setLimit($pageSize)->setPage($page); - $set = $collector->getPaginatedJournals(); + if ($this->hasModifiers()) { + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + } + $collector->disableInternalFilter(); + $set = $collector->getPaginatedJournals()->getCollection(); + $words = $this->words; + Log::debug(sprintf('Found %d journals to check. ', $set->count())); // Filter transactions that match the given triggers. $filtered = $set->filter( function (Transaction $transaction) use ($words) { - // check descr of journal: - if ($this->strpos_arr(strtolower(strval($transaction->description)), $words)) { - return $transaction; - } - // check descr of transaction - if ($this->strpos_arr(strtolower(strval($transaction->transaction_description)), $words)) { + if ($this->matchModifiers($transaction)) { return $transaction; } @@ -222,6 +253,62 @@ class Search implements SearchInterface $this->limit = $limit; } + /** + * @param User $user + */ + public function setUser(User $user) + { + $this->user = $user; + } + + /** + * @param string $string + */ + private function extractModifier(string $string) + { + $parts = explode(':', $string); + if (count($parts) === 2 && strlen(trim(strval($parts[0]))) > 0 && strlen(trim(strval($parts[1])))) { + $type = trim(strval($parts[0])); + $value = trim(strval($parts[1])); + if (in_array($type, $this->validModifiers)) { + // filter for valid type + $this->modifiers->push(['type' => $type, 'value' => $value,]); + } + } + } + + /** + * @param Transaction $transaction + * + * @return bool + * @throws FireflyException + */ + private function matchModifiers(Transaction $transaction): bool + { + Log::debug(sprintf('Now at transaction #%d', $transaction->id)); + // first "modifier" is always the text of the search: + // check descr of journal: + if (count($this->words) > 0 + && !$this->strpos_arr(strtolower(strval($transaction->description)), $this->words) + && !$this->strpos_arr(strtolower(strval($transaction->transaction_description)), $this->words) + ) { + Log::debug('Description does not match', $this->words); + + return false; + } + + // then a for-each and a switch for every possible other thingie. + foreach ($this->modifiers as $modifier) { + $res = Modifier::apply($modifier, $transaction); + if ($res === false) { + return $res; + } + } + + return true; + + } + /** * @param string $haystack * @param array $needle @@ -241,4 +328,4 @@ class Search implements SearchInterface return false; } -} +} diff --git a/app/Support/Search/SearchInterface.php b/app/Support/Search/SearchInterface.php index bd16c78853..e3962fcfea 100644 --- a/app/Support/Search/SearchInterface.php +++ b/app/Support/Search/SearchInterface.php @@ -13,6 +13,7 @@ declare(strict_types = 1); namespace FireflyIII\Support\Search; +use FireflyIII\User; use Illuminate\Support\Collection; /** @@ -23,38 +24,52 @@ use Illuminate\Support\Collection; interface SearchInterface { /** - * @param array $words - * - * @return Collection + * @return string */ - public function searchAccounts(array $words): Collection; + public function getWordsAsString(): string; /** - * @param array $words - * - * @return Collection + * @return bool */ - public function searchBudgets(array $words): Collection; + public function hasModifiers(): bool; /** - * @param array $words - * - * @return Collection + * @param string $query */ - public function searchCategories(array $words): Collection; + public function parseQuery(string $query); /** - * - * @param array $words - * * @return Collection */ - public function searchTags(array $words): Collection; + public function searchAccounts(): Collection; /** - * @param array $words - * * @return Collection */ - public function searchTransactions(array $words): Collection; + public function searchBudgets(): Collection; + + /** + * @return Collection + */ + public function searchCategories(): Collection; + + /** + * @return Collection + */ + public function searchTags(): Collection; + + /** + * @return Collection + */ + public function searchTransactions(): Collection; + + /** + * @param int $limit + */ + public function setLimit(int $limit); + + /** + * @param User $user + */ + public function setUser(User $user); } diff --git a/app/Support/Steam.php b/app/Support/Steam.php index 0185a93caf..7693cac164 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -14,6 +14,7 @@ declare(strict_types = 1); namespace FireflyIII\Support; use Carbon\Carbon; +use Crypt; use DB; use FireflyIII\Models\Account; use FireflyIII\Models\Transaction; @@ -26,7 +27,6 @@ use FireflyIII\Models\Transaction; class Steam { - /** * * @param \FireflyIII\Models\Account $account @@ -181,6 +181,21 @@ class Steam return $result; } + /** + * @param int $isEncrypted + * @param $value + * + * @return string + */ + public function decrypt(int $isEncrypted, string $value) + { + if ($isEncrypted === 1) { + return Crypt::decrypt($value); + } + + return $value; + } + /** * @param array $accounts * @@ -202,8 +217,6 @@ class Steam return $list; } - // parse PHP size: - /** * @param $string * @@ -239,4 +252,20 @@ class Steam } + // parse PHP size: + + /** + * @param string $amount + * + * @return string + */ + public function positive(string $amount): string + { + if (bccomp($amount, '0') === -1) { + $amount = bcmul($amount, '-1'); + } + + return $amount; + } + } diff --git a/app/Support/Twig/General.php b/app/Support/Twig/General.php index cfd98fcafc..5d339960fa 100644 --- a/app/Support/Twig/General.php +++ b/app/Support/Twig/General.php @@ -17,6 +17,7 @@ use Carbon\Carbon; use FireflyIII\Models\Account; use FireflyIII\Models\TransactionJournal; use Route; +use Steam; use Twig_Extension; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -43,6 +44,7 @@ class General extends Twig_Extension $this->balance(), $this->formatFilesize(), $this->mimeIcon(), + ]; } @@ -59,6 +61,7 @@ class General extends Twig_Extension $this->env(), $this->getAmountFromJournal(), $this->activeRouteStrict(), + $this->steamPositive(), $this->activeRoutePartial(), $this->activeRoutePartialWhat(), ]; @@ -288,6 +291,18 @@ class General extends Twig_Extension ); } + /** + * @return Twig_SimpleFunction + */ + protected function steamPositive() + { + return new Twig_SimpleFunction( + 'steam_positive', function (string $str): string { + return Steam::positive($str); + } + ); + } + /** * @return Twig_SimpleFunction */ diff --git a/app/Support/Twig/Transaction.php b/app/Support/Twig/Transaction.php index 5285a8ee90..f1a0b98dd5 100644 --- a/app/Support/Twig/Transaction.php +++ b/app/Support/Twig/Transaction.php @@ -19,6 +19,7 @@ use FireflyIII\Models\AccountType; use FireflyIII\Models\Transaction as TransactionModel; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Models\TransactionType; +use Steam; use Twig_Extension; use Twig_SimpleFilter; use Twig_SimpleFunction; @@ -195,7 +196,7 @@ class Transaction extends Twig_Extension return new Twig_SimpleFunction( 'transactionDestinationAccount', function (TransactionModel $transaction): string { - $name = intval($transaction->account_encrypted) === 1 ? Crypt::decrypt($transaction->account_name) : $transaction->account_name; + $name = Steam::decrypt(intval($transaction->account_encrypted), $transaction->account_name); $id = intval($transaction->account_id); $type = $transaction->account_type; @@ -217,7 +218,7 @@ class Transaction extends Twig_Extension ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') ->first(['transactions.account_id', 'accounts.encrypted', 'accounts.name', 'account_types.type']); - $name = intval($other->encrypted) === 1 ? Crypt::decrypt($other->name) : $other->name; + $name = Steam::decrypt(intval($other->encrypted), $other->name); $id = $other->account_id; $type = $other->type; } @@ -269,7 +270,7 @@ class Transaction extends Twig_Extension 'transactionSourceAccount', function (TransactionModel $transaction): string { // if the amount is negative, assume that the current account (the one in $transaction) is indeed the source account. - $name = intval($transaction->account_encrypted) === 1 ? Crypt::decrypt($transaction->account_name) : $transaction->account_name; + $name = Steam::decrypt(intval($transaction->account_encrypted), $transaction->account_name); $id = intval($transaction->account_id); $type = $transaction->account_type; @@ -289,7 +290,7 @@ class Transaction extends Twig_Extension ->leftJoin('accounts', 'accounts.id', '=', 'transactions.account_id') ->leftJoin('account_types', 'account_types.id', '=', 'accounts.account_type_id') ->first(['transactions.account_id', 'accounts.encrypted', 'accounts.name', 'account_types.type']); - $name = intval($other->encrypted) === 1 ? Crypt::decrypt($other->name) : $other->name; + $name = Steam::decrypt(intval($other->encrypted), $other->name); $id = $other->account_id; $type = $other->type; } @@ -337,21 +338,6 @@ class Transaction extends Twig_Extension ); } - /** - * @param int $isEncrypted - * @param string $value - * - * @return string - */ - private function encrypted(int $isEncrypted, string $value): string - { - if ($isEncrypted === 1) { - return Crypt::decrypt($value); - } - - return $value; - } - /** * @param TransactionModel $transaction * @@ -361,14 +347,14 @@ class Transaction extends Twig_Extension { // journal has a budget: if (isset($transaction->transaction_journal_budget_id)) { - $name = $this->encrypted(intval($transaction->transaction_journal_budget_encrypted), $transaction->transaction_journal_budget_name); + $name = Steam::decrypt(intval($transaction->transaction_journal_budget_encrypted), $transaction->transaction_journal_budget_name); return sprintf('%s', route('budgets.show', [$transaction->transaction_journal_budget_id]), $name, $name); } // transaction has a budget if (isset($transaction->transaction_budget_id)) { - $name = $this->encrypted(intval($transaction->transaction_budget_encrypted), $transaction->transaction_budget_name); + $name = Steam::decrypt(intval($transaction->transaction_budget_encrypted), $transaction->transaction_budget_name); return sprintf('%s', route('budgets.show', [$transaction->transaction_budget_id]), $name, $name); } @@ -400,14 +386,14 @@ class Transaction extends Twig_Extension { // journal has a category: if (isset($transaction->transaction_journal_category_id)) { - $name = $this->encrypted(intval($transaction->transaction_journal_category_encrypted), $transaction->transaction_journal_category_name); + $name = Steam::decrypt(intval($transaction->transaction_journal_category_encrypted), $transaction->transaction_journal_category_name); return sprintf('%s', route('categories.show', [$transaction->transaction_journal_category_id]), $name, $name); } // transaction has a category: if (isset($transaction->transaction_category_id)) { - $name = $this->encrypted(intval($transaction->transaction_category_encrypted), $transaction->transaction_category_name); + $name = Steam::decrypt(intval($transaction->transaction_category_encrypted), $transaction->transaction_category_name); return sprintf('%s', route('categories.show', [$transaction->transaction_category_id]), $name, $name); } diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index 61590816b4..f38a164993 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -27,9 +27,9 @@ use FireflyIII\Rules\Triggers\TriggerInterface; use FireflyIII\User; use Google2FA; use Illuminate\Contracts\Encryption\DecryptException; +use Illuminate\Contracts\Translation\Translator; use Illuminate\Validation\Validator; use Session; -use Symfony\Component\Translation\TranslatorInterface; /** * Class FireflyValidator @@ -40,14 +40,14 @@ class FireflyValidator extends Validator { /** - * @param TranslatorInterface $translator - * @param array $data - * @param array $rules - * @param array $messages - * @param array $customAttributes + * @param Translator $translator + * @param array $data + * @param array $rules + * @param array $messages + * @param array $customAttributes * */ - public function __construct(TranslatorInterface $translator, array $data, array $rules, array $messages = [], array $customAttributes = []) + public function __construct(Translator $translator, array $data, array $rules, array $messages = [], array $customAttributes = []) { parent::__construct($translator, $data, $rules, $messages, $customAttributes); } @@ -158,6 +158,7 @@ class FireflyValidator extends Validator public function validateMore($attribute, $value, $parameters): bool { $compare = $parameters[0] ?? '0'; + return bccomp($value, $compare) > 0; } diff --git a/composer.json b/composer.json index 659144ebc2..aa09eb9b44 100755 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ "financials", "financial", "budgets", - "administration", + "administration", "tool", "tooling", "help", @@ -48,14 +48,15 @@ "require": { "php": ">=7.0.0", "ext-intl": "*", - "laravel/framework": "5.3.29", - "davejamesmiller/laravel-breadcrumbs": "^3.0", + "laravel/framework": "5.4.*", + "davejamesmiller/laravel-breadcrumbs": "3.*", "watson/validating": "3.*", "doctrine/dbal": "^2.5", "league/commonmark": "0.15.*", + "twig/twig": "1.30.0", "rcrowe/twigbridge": "0.9.*", "league/csv": "8.*", - "laravelcollective/html": "^5.3", + "laravelcollective/html": "^5.4", "rmccue/requests": "1.*", "pragmarx/google2fa": "1.*", "bacon/bacon-qr-code": "1.*" @@ -67,8 +68,7 @@ "symfony/css-selector": "3.1.*", "symfony/dom-crawler": "3.1.*", "barryvdh/laravel-debugbar": "2.*", - "barryvdh/laravel-ide-helper": "2.*", - "johnkary/phpunit-speedtrap": "^1.0" + "barryvdh/laravel-ide-helper": "2.*" }, "autoload": { "classmap": [ @@ -79,9 +79,9 @@ } }, "autoload-dev": { - "classmap": [ - "tests/TestCase.php" - ] + "psr-4": { + "Tests\\": "tests/" + } }, "scripts": { "post-root-package-install": [ diff --git a/composer.lock b/composer.lock index b816654cd5..c67ced8a26 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "8a447ee60bb0509881af5070e5980f18", + "content-hash": "254ffef07304b93679b48182a179123f", "packages": [ { "name": "bacon/bacon-qr-code", @@ -102,60 +102,6 @@ ], "time": "2016-05-05T11:49:03+00:00" }, - { - "name": "classpreloader/classpreloader", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/ClassPreloader/ClassPreloader.git", - "reference": "bc7206aa892b5a33f4680421b69b191efd32b096" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/ClassPreloader/ClassPreloader/zipball/bc7206aa892b5a33f4680421b69b191efd32b096", - "reference": "bc7206aa892b5a33f4680421b69b191efd32b096", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^1.0|^2.0|^3.0", - "php": ">=5.5.9" - }, - "require-dev": { - "phpunit/phpunit": "^4.8|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "ClassPreloader\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Michael Dowling", - "email": "mtdowling@gmail.com" - }, - { - "name": "Graham Campbell", - "email": "graham@alt-three.com" - } - ], - "description": "Helps class loading performance by generating a single PHP file containing all of the autoloaded files for a specific use case", - "keywords": [ - "autoload", - "class", - "preload" - ], - "time": "2016-09-16T12:50:15+00:00" - }, { "name": "davejamesmiller/laravel-breadcrumbs", "version": "3.0.2", @@ -205,39 +151,6 @@ ], "time": "2017-01-30T21:16:53+00:00" }, - { - "name": "dnoegel/php-xdg-base-dir", - "version": "0.1", - "source": { - "type": "git", - "url": "https://github.com/dnoegel/php-xdg-base-dir.git", - "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/265b8593498b997dc2d31e75b89f053b5cc9621a", - "reference": "265b8593498b997dc2d31e75b89f053b5cc9621a", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "@stable" - }, - "type": "project", - "autoload": { - "psr-4": { - "XdgBaseDir\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "implementation of xdg base directory specification for php", - "time": "2014-10-24T07:27:01+00:00" - }, { "name": "doctrine/annotations", "version": "v1.3.1", @@ -518,16 +431,16 @@ }, { "name": "doctrine/dbal", - "version": "v2.5.10", + "version": "v2.5.12", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "fc376f7a61498e18520cd6fa083752a4ca08072b" + "reference": "7b9e911f9d8b30d43b96853dab26898c710d8f44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/fc376f7a61498e18520cd6fa083752a4ca08072b", - "reference": "fc376f7a61498e18520cd6fa083752a4ca08072b", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/7b9e911f9d8b30d43b96853dab26898c710d8f44", + "reference": "7b9e911f9d8b30d43b96853dab26898c710d8f44", "shasum": "" }, "require": { @@ -585,7 +498,7 @@ "persistence", "queryobject" ], - "time": "2017-01-23T23:17:10+00:00" + "time": "2017-02-08T12:53:47+00:00" }, { "name": "doctrine/inflector", @@ -709,77 +622,26 @@ "time": "2014-09-09T13:34:57+00:00" }, { - "name": "jakub-onderka/php-console-color", - "version": "0.1", + "name": "erusev/parsedown", + "version": "1.6.1", "source": { "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Console-Color.git", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1" + "url": "https://github.com/erusev/parsedown.git", + "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Color/zipball/e0b393dacf7703fc36a4efc3df1435485197e6c1", - "reference": "e0b393dacf7703fc36a4efc3df1435485197e6c1", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/20ff8bbb57205368b4b42d094642a3e52dac85fb", + "reference": "20ff8bbb57205368b4b42d094642a3e52dac85fb", "shasum": "" }, "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "jakub-onderka/php-code-style": "1.0", - "jakub-onderka/php-parallel-lint": "0.*", - "jakub-onderka/php-var-dump-check": "0.*", - "phpunit/phpunit": "3.7.*", - "squizlabs/php_codesniffer": "1.*" - }, - "type": "library", - "autoload": { - "psr-0": { - "JakubOnderka\\PhpConsoleColor": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-2-Clause" - ], - "authors": [ - { - "name": "Jakub Onderka", - "email": "jakub.onderka@gmail.com", - "homepage": "http://www.acci.cz" - } - ], - "time": "2014-04-08T15:00:19+00:00" - }, - { - "name": "jakub-onderka/php-console-highlighter", - "version": "v0.3.2", - "source": { - "type": "git", - "url": "https://github.com/JakubOnderka/PHP-Console-Highlighter.git", - "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/JakubOnderka/PHP-Console-Highlighter/zipball/7daa75df45242c8d5b75a22c00a201e7954e4fb5", - "reference": "7daa75df45242c8d5b75a22c00a201e7954e4fb5", - "shasum": "" - }, - "require": { - "jakub-onderka/php-console-color": "~0.1", "php": ">=5.3.0" }, - "require-dev": { - "jakub-onderka/php-code-style": "~1.0", - "jakub-onderka/php-parallel-lint": "~0.5", - "jakub-onderka/php-var-dump-check": "~0.1", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~1.5" - }, "type": "library", "autoload": { "psr-0": { - "JakubOnderka\\PhpConsoleHighlighter": "src/" + "Parsedown": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -788,109 +650,55 @@ ], "authors": [ { - "name": "Jakub Onderka", - "email": "acci@acci.cz", - "homepage": "http://www.acci.cz/" + "name": "Emanuil Rusev", + "email": "hello@erusev.com", + "homepage": "http://erusev.com" } ], - "time": "2015-04-20T18:58:01+00:00" - }, - { - "name": "jeremeamia/SuperClosure", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/jeremeamia/super_closure.git", - "reference": "443c3df3207f176a1b41576ee2a66968a507b3db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jeremeamia/super_closure/zipball/443c3df3207f176a1b41576ee2a66968a507b3db", - "reference": "443c3df3207f176a1b41576ee2a66968a507b3db", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^1.2|^2.0|^3.0", - "php": ">=5.4", - "symfony/polyfill-php56": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0|^5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-4": { - "SuperClosure\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jeremy Lindblom", - "email": "jeremeamia@gmail.com", - "homepage": "https://github.com/jeremeamia", - "role": "Developer" - } - ], - "description": "Serialize Closure objects, including their context and binding", - "homepage": "https://github.com/jeremeamia/super_closure", + "description": "Parser for Markdown.", + "homepage": "http://parsedown.org", "keywords": [ - "closure", - "function", - "lambda", - "parser", - "serializable", - "serialize", - "tokenizer" + "markdown", + "parser" ], - "time": "2016-12-07T09:37:55+00:00" + "time": "2016-11-02T15:56:58+00:00" }, { "name": "laravel/framework", - "version": "v5.3.29", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "6fd76dec90466dc3f703d8df72e38130f2ee6a32" + "reference": "707f32d32dce58232f7a860e0a1d62caf6f9dbfc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/6fd76dec90466dc3f703d8df72e38130f2ee6a32", - "reference": "6fd76dec90466dc3f703d8df72e38130f2ee6a32", + "url": "https://api.github.com/repos/laravel/framework/zipball/707f32d32dce58232f7a860e0a1d62caf6f9dbfc", + "reference": "707f32d32dce58232f7a860e0a1d62caf6f9dbfc", "shasum": "" }, "require": { - "classpreloader/classpreloader": "~3.0", "doctrine/inflector": "~1.0", + "erusev/parsedown": "~1.6", "ext-mbstring": "*", "ext-openssl": "*", - "jeremeamia/superclosure": "~2.2", "league/flysystem": "~1.0", "monolog/monolog": "~1.11", "mtdowling/cron-expression": "~1.0", "nesbot/carbon": "~1.20", "paragonie/random_compat": "~1.4|~2.0", "php": ">=5.6.4", - "psy/psysh": "0.7.*|0.8.*", "ramsey/uuid": "~3.0", "swiftmailer/swiftmailer": "~5.4", - "symfony/console": "3.1.*", - "symfony/debug": "3.1.*", - "symfony/finder": "3.1.*", - "symfony/http-foundation": "3.1.*", - "symfony/http-kernel": "3.1.*", - "symfony/process": "3.1.*", - "symfony/routing": "3.1.*", - "symfony/translation": "3.1.*", - "symfony/var-dumper": "3.1.*", + "symfony/console": "~3.2", + "symfony/debug": "~3.2", + "symfony/finder": "~3.2", + "symfony/http-foundation": "~3.2", + "symfony/http-kernel": "~3.2", + "symfony/process": "~3.2", + "symfony/routing": "~3.2", + "symfony/var-dumper": "~3.2", + "tijsverkoyen/css-to-inline-styles": "~2.2", "vlucas/phpdotenv": "~2.2" }, "replace": { @@ -927,31 +735,34 @@ }, "require-dev": { "aws/aws-sdk-php": "~3.0", + "doctrine/dbal": "~2.5", "mockery/mockery": "~0.9.4", "pda/pheanstalk": "~3.0", - "phpunit/phpunit": "~5.4", + "phpunit/phpunit": "~5.7", "predis/predis": "~1.0", - "symfony/css-selector": "3.1.*", - "symfony/dom-crawler": "3.1.*" + "symfony/css-selector": "~3.2", + "symfony/dom-crawler": "~3.2" }, "suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", - "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.4).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.5).", "fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", - "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~5.3|~6.0).", + "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).", + "laravel/tinker": "Required to use the tinker console command (~1.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", + "nexmo/client": "Required to use the Nexmo transport (~1.0).", "pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", "predis/predis": "Required to use the redis cache and queue drivers (~1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~2.0).", - "symfony/css-selector": "Required to use some of the crawler integration testing tools (3.1.*).", - "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (3.1.*).", - "symfony/psr-http-message-bridge": "Required to use psr7 bridging features (0.2.*)." + "symfony/css-selector": "Required to use some of the crawler integration testing tools (~3.2).", + "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~3.2).", + "symfony/psr-http-message-bridge": "Required to psr7 bridging features (0.2.*)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3-dev" + "dev-master": "5.4-dev" } }, "autoload": { @@ -979,32 +790,32 @@ "framework", "laravel" ], - "time": "2017-01-06T14:33:56+00:00" + "time": "2017-02-15T14:31:32+00:00" }, { "name": "laravelcollective/html", - "version": "v5.3.1", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/LaravelCollective/html.git", - "reference": "2f7f2e127c6fed47f269ea29ab5efeb8f65e9d35" + "reference": "7570f25d58a00fd6909c0563808590f9cdb14d47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/LaravelCollective/html/zipball/2f7f2e127c6fed47f269ea29ab5efeb8f65e9d35", - "reference": "2f7f2e127c6fed47f269ea29ab5efeb8f65e9d35", + "url": "https://api.github.com/repos/LaravelCollective/html/zipball/7570f25d58a00fd6909c0563808590f9cdb14d47", + "reference": "7570f25d58a00fd6909c0563808590f9cdb14d47", "shasum": "" }, "require": { - "illuminate/http": "5.3.*", - "illuminate/routing": "5.3.*", - "illuminate/session": "5.3.*", - "illuminate/support": "5.3.*", - "illuminate/view": "5.3.*", + "illuminate/http": "5.4.*", + "illuminate/routing": "5.4.*", + "illuminate/session": "5.4.*", + "illuminate/support": "5.4.*", + "illuminate/view": "5.4.*", "php": ">=5.6.4" }, "require-dev": { - "illuminate/database": "5.3.*", + "illuminate/database": "5.4.*", "mockery/mockery": "~0.9.4", "phpunit/phpunit": "~5.4" }, @@ -1033,7 +844,7 @@ ], "description": "HTML and Form Builders for the Laravel Framework", "homepage": "http://laravelcollective.com", - "time": "2016-12-13T14:23:36+00:00" + "time": "2017-01-26T19:27:05+00:00" }, { "name": "league/commonmark", @@ -1163,16 +974,16 @@ }, { "name": "league/flysystem", - "version": "1.0.34", + "version": "1.0.35", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "469ad53c13ea19a0e54e3e5d70f61227ddcc0299" + "reference": "dda7f3ab94158a002d9846a97dc18ebfb7acc062" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/469ad53c13ea19a0e54e3e5d70f61227ddcc0299", - "reference": "469ad53c13ea19a0e54e3e5d70f61227ddcc0299", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/dda7f3ab94158a002d9846a97dc18ebfb7acc062", + "reference": "dda7f3ab94158a002d9846a97dc18ebfb7acc062", "shasum": "" }, "require": { @@ -1242,7 +1053,7 @@ "sftp", "storage" ], - "time": "2017-01-30T17:41:17+00:00" + "time": "2017-02-09T11:33:58+00:00" }, { "name": "monolog/monolog", @@ -1419,57 +1230,6 @@ ], "time": "2017-01-16T07:55:07+00:00" }, - { - "name": "nikic/php-parser", - "version": "v3.0.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "adf44419c0fc014a0f191db6f89d3e55d4211744" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/adf44419c0fc014a0f191db6f89d3e55d4211744", - "reference": "adf44419c0fc014a0f191db6f89d3e55d4211744", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.5" - }, - "require-dev": { - "phpunit/phpunit": "~4.0|~5.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2016-12-06T11:30:35+00:00" - }, { "name": "paragonie/random_compat", "version": "v2.0.4", @@ -1626,79 +1386,6 @@ ], "time": "2016-10-10T12:19:37+00:00" }, - { - "name": "psy/psysh", - "version": "v0.8.1", - "source": { - "type": "git", - "url": "https://github.com/bobthecow/psysh.git", - "reference": "701e8a1cc426ee170f1296f5d9f6b8a26ad25c4a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/701e8a1cc426ee170f1296f5d9f6b8a26ad25c4a", - "reference": "701e8a1cc426ee170f1296f5d9f6b8a26ad25c4a", - "shasum": "" - }, - "require": { - "dnoegel/php-xdg-base-dir": "0.1", - "jakub-onderka/php-console-highlighter": "0.3.*", - "nikic/php-parser": "~1.3|~2.0|~3.0", - "php": ">=5.3.9", - "symfony/console": "~2.3.10|^2.4.2|~3.0", - "symfony/var-dumper": "~2.7|~3.0" - }, - "require-dev": { - "friendsofphp/php-cs-fixer": "~1.11", - "hoa/console": "~3.16|~1.14", - "phpunit/phpunit": "~4.4|~5.0", - "symfony/finder": "~2.1|~3.0" - }, - "suggest": { - "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", - "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", - "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", - "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." - }, - "bin": [ - "bin/psysh" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "0.9.x-dev" - } - }, - "autoload": { - "files": [ - "src/Psy/functions.php" - ], - "psr-4": { - "Psy\\": "src/Psy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" - } - ], - "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", - "keywords": [ - "REPL", - "console", - "interactive", - "shell" - ], - "time": "2017-01-15T17:54:13+00:00" - }, { "name": "ramsey/uuid", "version": "3.5.2", @@ -1896,16 +1583,16 @@ }, { "name": "swiftmailer/swiftmailer", - "version": "v5.4.5", + "version": "v5.4.6", "source": { "type": "git", "url": "https://github.com/swiftmailer/swiftmailer.git", - "reference": "cd142238a339459b10da3d8234220963f392540c" + "reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/cd142238a339459b10da3d8234220963f392540c", - "reference": "cd142238a339459b10da3d8234220963f392540c", + "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e", + "reference": "81fdccfaf8bdc5d5d7a1ef6bb3a61bbb1a6c4a3e", "shasum": "" }, "require": { @@ -1946,20 +1633,20 @@ "mail", "mailer" ], - "time": "2016-12-29T10:02:40+00:00" + "time": "2017-02-13T07:52:53+00:00" }, { "name": "symfony/console", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52" + "reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/047f16485d68c083bd5d9b73ff16f9cb9c1a9f52", - "reference": "047f16485d68c083bd5d9b73ff16f9cb9c1a9f52", + "url": "https://api.github.com/repos/symfony/console/zipball/0e5e6899f82230fcb1153bcaf0e106ffaa44b870", + "reference": "0e5e6899f82230fcb1153bcaf0e106ffaa44b870", "shasum": "" }, "require": { @@ -1970,17 +1657,19 @@ "require-dev": { "psr/log": "~1.0", "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/filesystem": "~2.8|~3.0", "symfony/process": "~2.8|~3.0" }, "suggest": { "psr/log": "For using the console logger", "symfony/event-dispatcher": "", + "symfony/filesystem": "", "symfony/process": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2007,20 +1696,73 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-01-08T20:43:43+00:00" + "time": "2017-02-16T14:07:22+00:00" }, { - "name": "symfony/debug", + "name": "symfony/css-selector", "version": "v3.1.10", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "c6661361626b3cf5cf2089df98b3b5006a197e85" + "url": "https://github.com/symfony/css-selector.git", + "reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/c6661361626b3cf5cf2089df98b3b5006a197e85", - "reference": "c6661361626b3cf5cf2089df98b3b5006a197e85", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d", + "reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d", + "shasum": "" + }, + "require": { + "php": ">=5.5.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "time": "2017-01-02T20:31:54+00:00" + }, + { + "name": "symfony/debug", + "version": "v3.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/debug.git", + "reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/debug/zipball/9b98854cb45bc59d100b7d4cc4cf9e05f21026b9", + "reference": "9b98854cb45bc59d100b7d4cc4cf9e05f21026b9", "shasum": "" }, "require": { @@ -2037,7 +1779,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2064,11 +1806,11 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-01-28T00:04:57+00:00" + "time": "2017-02-16T16:34:18+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v3.2.2", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", @@ -2128,16 +1870,16 @@ }, { "name": "symfony/finder", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "59687a255d1562f2c17b012418273862083d85f7" + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/59687a255d1562f2c17b012418273862083d85f7", - "reference": "59687a255d1562f2c17b012418273862083d85f7", + "url": "https://api.github.com/repos/symfony/finder/zipball/8c71141cae8e2957946b403cc71a67213c0380d6", + "reference": "8c71141cae8e2957946b403cc71a67213c0380d6", "shasum": "" }, "require": { @@ -2146,7 +1888,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2173,20 +1915,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-01-02T20:31:54+00:00" + "time": "2017-01-02T20:32:22+00:00" }, { "name": "symfony/http-foundation", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "cef0ad49a2e90455cfc649522025b5a2929648c0" + "reference": "a90da6dd679605d88c9803a57a6fc1fb7a19a6e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/cef0ad49a2e90455cfc649522025b5a2929648c0", - "reference": "cef0ad49a2e90455cfc649522025b5a2929648c0", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/a90da6dd679605d88c9803a57a6fc1fb7a19a6e0", + "reference": "a90da6dd679605d88c9803a57a6fc1fb7a19a6e0", "shasum": "" }, "require": { @@ -2199,7 +1941,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2226,20 +1968,20 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com", - "time": "2017-01-08T20:43:43+00:00" + "time": "2017-02-16T22:46:52+00:00" }, { "name": "symfony/http-kernel", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "c830387dec1b48c100473d10a6a356c3c3ae2a13" + "reference": "4cd0d4bc31819095c6ef13573069f621eb321081" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/c830387dec1b48c100473d10a6a356c3c3ae2a13", - "reference": "c830387dec1b48c100473d10a6a356c3c3ae2a13", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4cd0d4bc31819095c6ef13573069f621eb321081", + "reference": "4cd0d4bc31819095c6ef13573069f621eb321081", "shasum": "" }, "require": { @@ -2267,7 +2009,7 @@ "symfony/stopwatch": "~2.8|~3.0", "symfony/templating": "~2.8|~3.0", "symfony/translation": "~2.8|~3.0", - "symfony/var-dumper": "~2.8|~3.0" + "symfony/var-dumper": "~3.2" }, "suggest": { "symfony/browser-kit": "", @@ -2281,7 +2023,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2308,7 +2050,7 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com", - "time": "2017-01-28T02:53:17+00:00" + "time": "2017-02-16T23:59:56+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -2479,16 +2221,16 @@ }, { "name": "symfony/process", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "2605753c5f8c531623d24d002825ebb1d6a22248" + "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/2605753c5f8c531623d24d002825ebb1d6a22248", - "reference": "2605753c5f8c531623d24d002825ebb1d6a22248", + "url": "https://api.github.com/repos/symfony/process/zipball/0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856", + "reference": "0ab87c1e7570b3534a6e51eb4ca8e9f6d7327856", "shasum": "" }, "require": { @@ -2497,7 +2239,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2524,20 +2266,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-01-21T17:13:55+00:00" + "time": "2017-02-16T14:07:22+00:00" }, { "name": "symfony/routing", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "f25581d4eb0a82962c291917f826166f0dcd8a9a" + "reference": "af464432c177dbcdbb32295113b7627500331f2d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/f25581d4eb0a82962c291917f826166f0dcd8a9a", - "reference": "f25581d4eb0a82962c291917f826166f0dcd8a9a", + "url": "https://api.github.com/repos/symfony/routing/zipball/af464432c177dbcdbb32295113b7627500331f2d", + "reference": "af464432c177dbcdbb32295113b7627500331f2d", "shasum": "" }, "require": { @@ -2566,7 +2308,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2599,20 +2341,20 @@ "uri", "url" ], - "time": "2017-01-28T00:04:57+00:00" + "time": "2017-01-28T02:37:08+00:00" }, { "name": "symfony/translation", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "d5a20fab5f63f44c233c69b3041c3cb1d4945e45" + "reference": "d6825c6bb2f1da13f564678f9f236fe8242c0029" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/d5a20fab5f63f44c233c69b3041c3cb1d4945e45", - "reference": "d5a20fab5f63f44c233c69b3041c3cb1d4945e45", + "url": "https://api.github.com/repos/symfony/translation/zipball/d6825c6bb2f1da13f564678f9f236fe8242c0029", + "reference": "d6825c6bb2f1da13f564678f9f236fe8242c0029", "shasum": "" }, "require": { @@ -2636,7 +2378,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2663,20 +2405,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-01-21T17:01:39+00:00" + "time": "2017-02-16T22:46:52+00:00" }, { "name": "symfony/var-dumper", - "version": "v3.1.10", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "16df11647e5b992d687cb4eeeb9a882d5f5c26b9" + "reference": "cb50260b674ee1c2d4ab49f2395a42e0b4681e20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/16df11647e5b992d687cb4eeeb9a882d5f5c26b9", - "reference": "16df11647e5b992d687cb4eeeb9a882d5f5c26b9", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cb50260b674ee1c2d4ab49f2395a42e0b4681e20", + "reference": "cb50260b674ee1c2d4ab49f2395a42e0b4681e20", "shasum": "" }, "require": { @@ -2692,7 +2434,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -2726,20 +2468,67 @@ "debug", "dump" ], - "time": "2017-01-24T13:02:38+00:00" + "time": "2017-02-16T22:46:52+00:00" }, { - "name": "twig/twig", - "version": "v1.31.0", + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.0", "source": { "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7" + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ddc9e3e20ee9c0b6908f401ac8353635b750eca7", - "reference": "ddc9e3e20ee9c0b6908f401ac8353635b750eca7", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b", + "reference": "ab03919dfd85a74ae0372f8baf9f3c7d5c03b04b", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7", + "symfony/css-selector": "^2.7|~3.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8|5.1.*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "time": "2016-09-20T12:50:39+00:00" + }, + { + "name": "twig/twig", + "version": "v1.30.0", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "c6ff71094fde15d12398eaba029434b013dc5e59" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c6ff71094fde15d12398eaba029434b013dc5e59", + "reference": "c6ff71094fde15d12398eaba029434b013dc5e59", "shasum": "" }, "require": { @@ -2747,12 +2536,12 @@ }, "require-dev": { "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~3.2" + "symfony/phpunit-bridge": "~3.2@dev" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.31-dev" + "dev-master": "1.30-dev" } }, "autoload": { @@ -2787,7 +2576,7 @@ "keywords": [ "templating" ], - "time": "2017-01-11T19:36:15+00:00" + "time": "2016-12-23T11:06:22+00:00" }, { "name": "vlucas/phpdotenv", @@ -2947,16 +2736,16 @@ }, { "name": "barryvdh/laravel-ide-helper", - "version": "v2.2.3", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/barryvdh/laravel-ide-helper.git", - "reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af" + "reference": "555d3e37009bdb78f5d8bcea6eb8a816529a5cfa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/a7fc2ec489aada6062d3a63ddc915004a21e38af", - "reference": "a7fc2ec489aada6062d3a63ddc915004a21e38af", + "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/555d3e37009bdb78f5d8bcea6eb8a816529a5cfa", + "reference": "555d3e37009bdb78f5d8bcea6eb8a816529a5cfa", "shasum": "" }, "require": { @@ -3009,7 +2798,7 @@ "phpstorm", "sublime" ], - "time": "2017-01-05T21:20:42+00:00" + "time": "2017-02-13T19:20:12+00:00" }, { "name": "barryvdh/reflection-docblock", @@ -3207,56 +2996,6 @@ ], "time": "2015-05-11T14:41:42+00:00" }, - { - "name": "johnkary/phpunit-speedtrap", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/johnkary/phpunit-speedtrap.git", - "reference": "76a26f8a903a9434608cdad2b41c40cd134ea326" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/johnkary/phpunit-speedtrap/zipball/76a26f8a903a9434608cdad2b41c40cd134ea326", - "reference": "76a26f8a903a9434608cdad2b41c40cd134ea326", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*|~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "psr-0": { - "JohnKary": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "John Kary", - "email": "john@johnkary.net" - } - ], - "description": "Find slow tests in your PHPUnit test suite", - "homepage": "https://github.com/johnkary/phpunit-speedtrap", - "keywords": [ - "phpunit", - "profile", - "slow" - ], - "time": "2015-09-13T19:01:00+00:00" - }, { "name": "maximebf/debugbar", "version": "1.13.1", @@ -3320,16 +3059,16 @@ }, { "name": "mockery/mockery", - "version": "0.9.7", + "version": "0.9.8", "source": { "type": "git", "url": "https://github.com/padraic/mockery.git", - "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371" + "reference": "1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/padraic/mockery/zipball/4de7969f4664da3cef1ccd83866c9f59378c3371", - "reference": "4de7969f4664da3cef1ccd83866c9f59378c3371", + "url": "https://api.github.com/repos/padraic/mockery/zipball/1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855", + "reference": "1e5e2ffdc4d71d7358ed58a6fdd30a4a0c506855", "shasum": "" }, "require": { @@ -3381,7 +3120,7 @@ "test double", "testing" ], - "time": "2016-12-19T14:50:55+00:00" + "time": "2017-02-09T13:29:38+00:00" }, { "name": "myclabs/deep-copy", @@ -3880,16 +3619,16 @@ }, { "name": "phpunit/phpunit", - "version": "5.7.9", + "version": "5.7.14", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "69f832b87c731d5cacad7f91948778fe98335fdd" + "reference": "4906b8faf23e42612182fd212eb6f4c0f2954b57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/69f832b87c731d5cacad7f91948778fe98335fdd", - "reference": "69f832b87c731d5cacad7f91948778fe98335fdd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4906b8faf23e42612182fd212eb6f4c0f2954b57", + "reference": "4906b8faf23e42612182fd212eb6f4c0f2954b57", "shasum": "" }, "require": { @@ -3906,14 +3645,14 @@ "phpunit/php-text-template": "~1.2", "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "~1.2.2", + "sebastian/comparator": "^1.2.4", "sebastian/diff": "~1.2", "sebastian/environment": "^1.3.4 || ^2.0", "sebastian/exporter": "~2.0", - "sebastian/global-state": "^1.0 || ^2.0", + "sebastian/global-state": "^1.1", "sebastian/object-enumerator": "~2.0", "sebastian/resource-operations": "~1.0", - "sebastian/version": "~1.0|~2.0", + "sebastian/version": "~1.0.3|~2.0", "symfony/yaml": "~2.1|~3.0" }, "conflict": { @@ -3958,7 +3697,7 @@ "testing", "xunit" ], - "time": "2017-01-28T06:14:33+00:00" + "time": "2017-02-19T07:22:16+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -4350,16 +4089,16 @@ }, { "name": "sebastian/object-enumerator", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35" + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", - "reference": "96f8a3f257b69e8128ad74d3a7fd464bcbaa3b35", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", "shasum": "" }, "require": { @@ -4392,7 +4131,7 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2016-11-19T07:35:10+00:00" + "time": "2017-02-18T15:18:39+00:00" }, { "name": "sebastian/recursion-context", @@ -4534,16 +4273,16 @@ }, { "name": "symfony/class-loader", - "version": "v3.2.2", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/class-loader.git", - "reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6" + "reference": "2847d56f518ad5721bf85aa9174b3aa3fd12aa03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/class-loader/zipball/0152f7a47acd564ca62c652975c2b32ac6d613a6", - "reference": "0152f7a47acd564ca62c652975c2b32ac6d613a6", + "url": "https://api.github.com/repos/symfony/class-loader/zipball/2847d56f518ad5721bf85aa9174b3aa3fd12aa03", + "reference": "2847d56f518ad5721bf85aa9174b3aa3fd12aa03", "shasum": "" }, "require": { @@ -4586,60 +4325,7 @@ ], "description": "Symfony ClassLoader Component", "homepage": "https://symfony.com", - "time": "2017-01-10T14:14:38+00:00" - }, - { - "name": "symfony/css-selector", - "version": "v3.1.10", - "source": { - "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d", - "reference": "722a87478a72d95dc2a3bcf41dc9c2d13fd4cb2d", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\CssSelector\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony CssSelector Component", - "homepage": "https://symfony.com", - "time": "2017-01-02T20:31:54+00:00" + "time": "2017-01-21T17:06:35+00:00" }, { "name": "symfony/dom-crawler", @@ -4699,16 +4385,16 @@ }, { "name": "symfony/yaml", - "version": "v3.2.2", + "version": "v3.2.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "50eadbd7926e31842893c957eca362b21592a97d" + "reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/50eadbd7926e31842893c957eca362b21592a97d", - "reference": "50eadbd7926e31842893c957eca362b21592a97d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/9724c684646fcb5387d579b4bfaa63ee0b0c64c8", + "reference": "9724c684646fcb5387d579b4bfaa63ee0b0c64c8", "shasum": "" }, "require": { @@ -4750,7 +4436,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-01-03T13:51:32+00:00" + "time": "2017-02-16T22:46:52+00:00" }, { "name": "webmozart/assert", diff --git a/config/app.php b/config/app.php old mode 100755 new mode 100644 index 4933ad1c8c..f92541fb61 --- a/config/app.php +++ b/config/app.php @@ -26,8 +26,8 @@ return [ 'providers' => [ /* - * Laravel Framework Service Providers... - */ + * Laravel Framework Service Providers... + */ Illuminate\Auth\AuthServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Bus\BusServiceProvider::class, @@ -46,7 +46,7 @@ return [ Illuminate\Queue\QueueServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, - Illuminate\Session\SessionServiceProvider::class, + FireflyIII\Providers\FireflySessionProvider::class, Illuminate\Translation\TranslationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class, Illuminate\View\ViewServiceProvider::class, @@ -56,6 +56,7 @@ return [ /* * Application Service Providers... */ + FireflyIII\Providers\LogServiceProvider::class, FireflyIII\Providers\AppServiceProvider::class, FireflyIII\Providers\AuthServiceProvider::class, // FireflyIII\Providers\BroadcastServiceProvider::class, @@ -74,7 +75,6 @@ return [ /* * More service providers. */ - FireflyIII\Providers\CrudServiceProvider::class, FireflyIII\Providers\AccountServiceProvider::class, FireflyIII\Providers\AttachmentServiceProvider::class, FireflyIII\Providers\BillServiceProvider::class, @@ -92,11 +92,12 @@ return [ ], 'aliases' => [ - 'App' => Illuminate\Support\Facades\App::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Auth' => Illuminate\Support\Facades\Auth::class, 'Blade' => Illuminate\Support\Facades\Blade::class, + 'Broadcast' => Illuminate\Support\Facades\Broadcast::class, + 'Bus' => Illuminate\Support\Facades\Bus::class, 'Cache' => Illuminate\Support\Facades\Cache::class, 'Config' => Illuminate\Support\Facades\Config::class, 'Cookie' => Illuminate\Support\Facades\Cookie::class, diff --git a/config/firefly.php b/config/firefly.php index adae9e8c07..7e28edf8dd 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -24,7 +24,7 @@ return [ ], 'encryption' => (is_null(env('USE_ENCRYPTION')) || env('USE_ENCRYPTION') === true), 'chart' => 'chartjs', - 'version' => '4.3.4', + 'version' => '4.3.5', 'csv_import_enabled' => true, 'maxUploadSize' => 5242880, 'allowedMimes' => ['image/png', 'image/jpeg', 'application/pdf'], @@ -153,6 +153,7 @@ return [ 'budgetList' => 'FireflyIII\Support\Binder\BudgetList', 'journalList' => 'FireflyIII\Support\Binder\JournalList', 'categoryList' => 'FireflyIII\Support\Binder\CategoryList', + 'tagList' => 'FireflyIII\Support\Binder\TagList', 'start_date' => 'FireflyIII\Support\Binder\Date', 'end_date' => 'FireflyIII\Support\Binder\Date', ], @@ -176,7 +177,7 @@ return [ 'transaction_type' => 'FireflyIII\Rules\Triggers\TransactionType', 'category_is' => 'FireflyIII\Rules\Triggers\CategoryIs', 'budget_is' => 'FireflyIII\Rules\Triggers\BudgetIs', - 'tag_is' => 'FireflyIII\Rules\Triggers\TagIs', + 'tag_is' => 'FireflyIII\Rules\Triggers\TagIs', ], 'rule-actions' => [ 'set_category' => 'FireflyIII\Rules\Actions\SetCategory', @@ -208,4 +209,7 @@ return [ ], 'default_currency' => 'EUR', 'default_language' => 'en_US', + 'search_modifiers' => ['amount_is', 'amount', 'amount_max', 'amount_min', 'amount_less', 'amount_more', 'source', 'destination', 'category', + 'budget', 'bill', 'type', 'date', 'date_before', 'date_after','on','before','after'], + // tag notes has_attachments ]; diff --git a/database/seeds/AccountTypeSeeder.php b/database/seeds/AccountTypeSeeder.php index 64422f3a5d..8f8690f33a 100644 --- a/database/seeds/AccountTypeSeeder.php +++ b/database/seeds/AccountTypeSeeder.php @@ -21,8 +21,6 @@ class AccountTypeSeeder extends Seeder { public function run() { - DB::table('account_types')->delete(); - AccountType::create(['type' => 'Default account']); AccountType::create(['type' => 'Cash account']); AccountType::create(['type' => 'Asset account']); @@ -31,6 +29,7 @@ class AccountTypeSeeder extends Seeder AccountType::create(['type' => 'Initial balance account']); AccountType::create(['type' => 'Beneficiary account']); AccountType::create(['type' => 'Import account']); + AccountType::create(['type' => 'Loan']); } diff --git a/database/seeds/TransactionCurrencySeeder.php b/database/seeds/TransactionCurrencySeeder.php index f1204569a3..5d8fe07845 100644 --- a/database/seeds/TransactionCurrencySeeder.php +++ b/database/seeds/TransactionCurrencySeeder.php @@ -21,8 +21,6 @@ class TransactionCurrencySeeder extends Seeder { public function run() { - DB::table('transaction_currencies')->delete(); - TransactionCurrency::create(['code' => 'EUR', 'name' => 'Euro', 'symbol' => '€', 'decimal_places' => 2]); TransactionCurrency::create(['code' => 'USD', 'name' => 'US Dollar', 'symbol' => '$', 'decimal_places' => 2]); TransactionCurrency::create(['code' => 'HUF', 'name' => 'Hungarian forint', 'symbol' => 'Ft', 'decimal_places' => 2]); diff --git a/database/seeds/TransactionTypeSeeder.php b/database/seeds/TransactionTypeSeeder.php index 690d333aba..06ff214776 100644 --- a/database/seeds/TransactionTypeSeeder.php +++ b/database/seeds/TransactionTypeSeeder.php @@ -21,9 +21,6 @@ class TransactionTypeSeeder extends Seeder { public function run() { - - DB::table('transaction_types')->delete(); - TransactionType::create(['type' => TransactionType::WITHDRAWAL]); TransactionType::create(['type' => TransactionType::DEPOSIT]); TransactionType::create(['type' => TransactionType::TRANSFER]); diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000000..c8ce8bea02 --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,16 @@ +version: '2' + +services: + firefly-db: + volumes: + - firefly-dev-storage:/var/lib/mysql + firefly-app: + volumes: + - .:/var/www/firefly-iii + environment: + - INIT_DATABASE=yes + - FF_APP_ENV=development + +volumes: + firefly-dev-storage: + driver: local diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000000..68fdff69a1 --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,12 @@ +version: '2' + +services: + firefly-app: + environment: + - FF_APP_ENV=production + volumes: + - firefly-app-storage:/var/www/firefly-iii/storage + +volumes: + firefly-app-storage: + driver: local diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000000..92f79e2ea6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +version: '2' + +services: + firefly-db: + image: mysql:8 + environment: + - MYSQL_DATABASE=firefly_db + - MYSQL_USER=firefly_db + - MYSQL_PASSWORD=firefly_db_secret + - MYSQL_RANDOM_ROOT_PASSWORD=yes + volumes: + - firefly-storage:/var/lib/mysql + + firefly-app: + image: firefly-iii + build: . + environment: + - FF_DB_HOST=firefly-db + - FF_DB_NAME=firefly_db + - FF_DB_USER=firefly_db + - FF_DB_PASSWORD=firefly_db_secret + - FF_APP_KEY=SomeRandomStringOf32CharsExactly + ports: + - "80:80" + links: + - firefly-db + +volumes: + firefly-storage: + driver: local diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 0000000000..0baf22e862 --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +cat .env.docker | envsubst > .env + +if [ "${INIT_DATABASE:="no"}" = "yes" ]; then + echo "Init database detected, checking mysql status" + # depends on your machine, but it may take a file to boot mysql container the first time + until php artisan firefly:verify &>/dev/null + do + echo "waiting mysql" + sleep 10 + done + php artisan migrate:refresh --seed +fi + +exec apache2-foreground diff --git a/phpunit.coverage.xml b/phpunit.coverage.xml index 75e3afd143..d643a5d6ec 100755 --- a/phpunit.coverage.xml +++ b/phpunit.coverage.xml @@ -10,11 +10,12 @@ beStrictAboutOutputDuringTests="true" stopOnFailure="true"> - - ./tests/acceptance + + ./tests/Feature - - ./tests/unit + + + ./tests/Unit diff --git a/phpunit.xml b/phpunit.xml index d439428075..b0e315533c 100755 --- a/phpunit.xml +++ b/phpunit.xml @@ -10,18 +10,14 @@ beStrictAboutOutputDuringTests="true" stopOnFailure="true"> - - ./tests/acceptance + + ./tests/Feature - - ./tests/unit + + + ./tests/Unit - - - - - ./app diff --git a/public/js/ff/charts.defaults.js b/public/js/ff/charts.defaults.js index c670667dd1..4679f6565b 100644 --- a/public/js/ff/charts.defaults.js +++ b/public/js/ff/charts.defaults.js @@ -11,6 +11,11 @@ /** global: accounting */ var defaultChartOptions = { + elements: { + line: { + cubicInterpolationMode: 'monotone' + } + }, scales: { xAxes: [ { diff --git a/public/js/ff/index.js b/public/js/ff/index.js index ba6c9993e1..1cd119c383 100644 --- a/public/js/ff/index.js +++ b/public/js/ff/index.js @@ -8,7 +8,7 @@ * See the LICENSE file for details. */ -/** global: Tour, showTour, accountFrontpageUri, billCount, accountExpenseUri, accountRevenueUri */ +/** global: Tour, showTour, accountFrontpageUri, token, billCount, accountExpenseUri, accountRevenueUri */ $(function () { "use strict"; @@ -34,7 +34,7 @@ $(function () { function endTheTour() { "use strict"; - $.post('json/end-tour'); + $.post('json/end-tour', {_token: token}); } diff --git a/public/js/ff/reports/index.js b/public/js/ff/reports/index.js index b57faf8b04..df65b9704f 100644 --- a/public/js/ff/reports/index.js +++ b/public/js/ff/reports/index.js @@ -98,8 +98,8 @@ function setOptionalFromCookies() { arr.forEach(function (val) { $('#inputCategories').find('option[value="' + val + '"]').prop('selected', true); }); - $('#inputCategories').multiselect(defaultMultiSelect); } + $('#inputCategories').multiselect(defaultMultiSelect); // and budgets! if ((readCookie('report-budgets') !== null)) { @@ -107,8 +107,17 @@ function setOptionalFromCookies() { arr.forEach(function (val) { $('#inputBudgets').find('option[value="' + val + '"]').prop('selected', true); }); - $('#inputBudgets').multiselect(defaultMultiSelect); } + $('#inputBudgets').multiselect(defaultMultiSelect); + + // and tags! + if ((readCookie('report-tags') !== null)) { + arr = readCookie('report-tags').split(','); + arr.forEach(function (val) { + $('#inputBudgets').find('option[value="' + val + '"]').prop('selected', true); + }); + } + $('#inputTags').multiselect(defaultMultiSelect); } function catchSubmit() { @@ -117,45 +126,20 @@ function catchSubmit() { var picker = $('#inputDateRange').data('daterangepicker'); // all account ids: - var count = 0; - var accounts = []; - $.each($('.account-checkbox'), function (i, v) { - var c = $(v); - if (c.prop('checked')) { - accounts.push(c.val()); - count++; - } - }); - - // all category ids: - var categories = []; - $.each($('.category-checkbox'), function (i, v) { - var c = $(v); - if (c.prop('checked')) { - categories.push(c.val()); - } - }); - - // all budget ids: - var budgets = []; - $.each($('.budget-checkbox'), function (i, v) { - var c = $(v); - if (c.prop('checked')) { - budgets.push(c.val()); - } - }); - + var accounts = $('#inputAccounts').val(); + var categories = $('#inputCategories').val(); + var budgets = $('#inputBudgets').val(); + var tags = $('#inputTags').val(); // remember all - if (count > 0) { - // set cookie to remember choices. - createCookie('report-type', $('select[name="report_type"]').val(), 365); - createCookie('report-accounts', accounts, 365); - createCookie('report-categories', categories, 365); - createCookie('report-budgets', budgets, 365); - createCookie('report-start', moment(picker.startDate).format("YYYYMMDD"), 365); - createCookie('report-end', moment(picker.endDate).format("YYYYMMDD"), 365); - } + // set cookie to remember choices. + createCookie('report-type', $('select[name="report_type"]').val(), 365); + createCookie('report-accounts', accounts, 365); + createCookie('report-categories', categories, 365); + createCookie('report-budgets', budgets, 365); + createCookie('report-tags', tags, 365); + createCookie('report-start', moment(picker.startDate).format("YYYYMMDD"), 365); + createCookie('report-end', moment(picker.endDate).format("YYYYMMDD"), 365); return true; } diff --git a/resources/lang/de_DE/config.php b/resources/lang/de_DE/config.php index 783fe0a459..ef642a7e8b 100644 --- a/resources/lang/de_DE/config.php +++ b/resources/lang/de_DE/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'de, Deutsch, de_DE.utf8', + 'locale' => 'de, Deutsch, de_DE, de_DE.utf8, de_DE.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%e. %B %Y', 'date_time' => '%e %B %Y, @ %T', diff --git a/resources/lang/de_DE/firefly.php b/resources/lang/de_DE/firefly.php index e0198d089f..c7c9a77db5 100644 --- a/resources/lang/de_DE/firefly.php +++ b/resources/lang/de_DE/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Alles anzeigen', 'never' => 'Nie', 'search_results_for' => 'Suchergebnisse für ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'Die Nachricht an :email ist nicht zustellbar, sodass Sie keinen Zugang haben.', 'deleted_error' => 'Die Zugangsdaten stimmen nicht überein.', 'general_blocked_error' => 'Ihr Benutzerkonto wurde deaktiviert, sodass Sie sich nicht anmelden können.', @@ -555,6 +557,7 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?', 'select_more_than_one_account' => 'Bitte mehr als ein Konto wählen', 'select_more_than_one_category' => 'Bitte mehr als eine Kategorie wählen', 'select_more_than_one_budget' => 'Bitte mehr als ein Budget wählen', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'Von :start bis :end', // categories: @@ -712,6 +715,7 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?', 'report_type_audit' => 'Übersicht der Transaktionen (Prüfung)', 'report_type_category' => 'Kategorie-Bericht', 'report_type_budget' => 'Budgetbericht', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Übersicht über Kategorien, Budgets und Rechnungen', 'more_info_help' => 'Weitere Informationen über diese Art von Berichten finden Sie in der Hilfe. Drücken Sie hierfür das (?)-Symbol in der oberen rechten Ecke.', 'report_included_accounts' => 'Eingezogene Konten', @@ -730,8 +734,9 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?', 'report_has_no_extra_options' => 'Dieser Bericht hat keine zusätzliche Optionen', 'reports_submit' => 'Zeige Bericht', 'end_after_start_date' => 'Enddatum des Berichts muss nach dem Startdatum liegen.', - 'select_category' => 'Wählen Sie eine oder mehrere Kategorien aus.', - 'select_budget' => 'Wählen Sie ein oder mehrere Budgets aus.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Einnahmen pro Kategorie', 'expense_per_category' => 'Ausgaben pro Kategorie', 'expense_per_budget' => 'Ausgaben pro Budget', @@ -960,4 +965,7 @@ Sollen zusätzlich Ihre Girokonten angezeigt werden?', 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/en_US/auth.php b/resources/lang/en_US/auth.php old mode 100755 new mode 100644 diff --git a/resources/lang/en_US/config.php b/resources/lang/en_US/config.php index 0c23d3f6cd..b5ed958eca 100644 --- a/resources/lang/en_US/config.php +++ b/resources/lang/en_US/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'en, English, en_US, en_US.utf8', + 'locale' => 'en, English, en_US, en_US.utf8, en_US.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%B %e, %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/en_US/demo.php b/resources/lang/en_US/demo.php index e7f8ea934d..3efa9c60a3 100644 --- a/resources/lang/en_US/demo.php +++ b/resources/lang/en_US/demo.php @@ -21,4 +21,4 @@ return [ 'import-index' => 'Of course, any CSV file can be imported into Firefly III ', 'import-configure-security' => 'Because of security concerns, your upload has been replaced with a local file.', 'import-configure-configuration' => 'The configuration you see below is correct for the local file.', -]; \ No newline at end of file +]; diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index d54d34d4a6..b0d2efd35f 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Show everything', 'never' => 'Never', 'search_results_for' => 'Search results for ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'The message sent to :email bounced, so no access for you.', 'deleted_error' => 'These credentials do not match our records.', 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Categories, budgets and bills overview', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; diff --git a/resources/lang/en_US/pagination.php b/resources/lang/en_US/pagination.php old mode 100755 new mode 100644 diff --git a/resources/lang/en_US/passwords.php b/resources/lang/en_US/passwords.php old mode 100755 new mode 100644 diff --git a/resources/lang/es_ES/config.php b/resources/lang/es_ES/config.php index 58220429bf..223b3f8bd3 100644 --- a/resources/lang/es_ES/config.php +++ b/resources/lang/es_ES/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'en, English, en_US, en_US.utf8', + 'locale' => 'es, Spanish, es_ES, es_ES.utf8, es_ES.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%B %e, %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/es_ES/firefly.php b/resources/lang/es_ES/firefly.php index a91170cd53..73e438c75f 100644 --- a/resources/lang/es_ES/firefly.php +++ b/resources/lang/es_ES/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Show everything', 'never' => 'Never', 'search_results_for' => 'Search results for ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'The message sent to :email bounced, so no access for you.', 'deleted_error' => 'These credentials do not match our records.', 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Categories, budgets and bills overview', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/fr_FR/config.php b/resources/lang/fr_FR/config.php index 9ddc4761b8..c5214455e4 100644 --- a/resources/lang/fr_FR/config.php +++ b/resources/lang/fr_FR/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'fr, French, fr_FR, fr_FR.utf8', + 'locale' => 'fr, French, fr_FR, fr_FR.utf8, fr_FR.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%e %B %Y', 'date_time' => '%B %e %Y @ %T', diff --git a/resources/lang/fr_FR/firefly.php b/resources/lang/fr_FR/firefly.php index cfd9123263..73f7e6e223 100644 --- a/resources/lang/fr_FR/firefly.php +++ b/resources/lang/fr_FR/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Tout Afficher', 'never' => 'Jamais', 'search_results_for' => 'Résultats de recherche pour ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'Le message envoyé à :email a été rejeté, donc pas d\'accès pour vous.', 'deleted_error' => 'Ces informations d\'identification ne sont pas présentes dans nos données.', 'general_blocked_error' => 'Votre compte a été désactivé, vous ne pouvez plus vous connecter.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Historique des transactions', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Vue d’ensemble des budgets, des catégories et des factures', 'more_info_help' => 'Plus d’informations sur ces types de rapports se trouvent dans les pages d’aide. Appuyez sur l’icône ( ?) dans le coin supérieur droit.', 'report_included_accounts' => 'Comptes inclus', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/hr_HR/config.php b/resources/lang/hr_HR/config.php index aed39872de..61ed65512d 100644 --- a/resources/lang/hr_HR/config.php +++ b/resources/lang/hr_HR/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'hr, Croatian, hr_HR, hr_HR.utf8', + 'locale' => 'hr, Croatian, hr_HR, hr_HR.utf8, hr_HR.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%e %B %Y', 'date_time' => '%e %B %Y, @ %T', diff --git a/resources/lang/hr_HR/firefly.php b/resources/lang/hr_HR/firefly.php index a91170cd53..73e438c75f 100644 --- a/resources/lang/hr_HR/firefly.php +++ b/resources/lang/hr_HR/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Show everything', 'never' => 'Never', 'search_results_for' => 'Search results for ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'The message sent to :email bounced, so no access for you.', 'deleted_error' => 'These credentials do not match our records.', 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Categories, budgets and bills overview', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/nl_NL/config.php b/resources/lang/nl_NL/config.php index d27314468a..608b288833 100644 --- a/resources/lang/nl_NL/config.php +++ b/resources/lang/nl_NL/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'nl, Dutch, nl_NL, nl_NL.utf8', + 'locale' => 'nl, Dutch, nl_NL, nl_NL.utf8, nl_NL.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%e %B %Y', 'date_time' => '%e %B %Y, @ %T', diff --git a/resources/lang/nl_NL/firefly.php b/resources/lang/nl_NL/firefly.php index 65b5810fb7..f27beb8fec 100644 --- a/resources/lang/nl_NL/firefly.php +++ b/resources/lang/nl_NL/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Laat alles zien', 'never' => 'Nooit', 'search_results_for' => 'Zoekresultaten voor ":query"', + 'advanced_search' => 'Geavanceerd zoeken', + 'advanced_search_intro' => 'Er zijn een paar parameters die je in je zoekopdracht kan gebruiken om betere resultaten te krijgen. Ze werken alleen op transacties. Klik op het -icoontje om hier meer over te lezen.', 'bounced_error' => 'Het emailtje naar :email kwam nooit aan.', 'deleted_error' => 'Deze gegevens zijn niet correct.', 'general_blocked_error' => 'Je account is uitgeschakeld, je kan helaas niet inloggen.', @@ -454,7 +456,7 @@ return [ 'deleted_currency' => 'Valuta :name verwijderd', 'created_currency' => 'Nieuwe valuta :name opgeslagen', 'updated_currency' => 'Valuta :name bijgewerkt', - 'ask_site_owner' => 'Vraag :site_owner of deze valuta wilt toevoegen, verwijderen of wijzigen.', + 'ask_site_owner' => 'Vraag :owner of deze valuta wilt toevoegen, verwijderen of wijzigen.', 'currencies_intro' => 'Firefly III ondersteunt diverse valuta die je hier kan instellen en bewerken.', 'make_default_currency' => 'maak standaard', 'default_currency' => 'standaard', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Selecteer meer dan één rekening', 'select_more_than_one_category' => 'Selecteer meer dan één categorie', 'select_more_than_one_budget' => 'Selecteer meer dan één budget', + 'select_more_than_one_tag' => 'Selecteer meer dan één tag', 'from_to' => 'Van :start tot en met :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transactiehistorie-overzicht (audit)', 'report_type_category' => 'Categorierapport', 'report_type_budget' => 'Budgetrapport', + 'report_type_tag' => 'Tagrapport', 'report_type_meta-history' => 'Overzicht van categorieën, budgetten en contracten', 'more_info_help' => 'Meer informatie over deze rapporten vind je in de hulppagina\'s. Klik daarvoor op het (?) icoontje rechtsboven.', 'report_included_accounts' => 'Accounts in rapport', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'Er zijn geen extra opties voor dit overzicht', 'reports_submit' => 'Bekijk overzicht', 'end_after_start_date' => 'Einddatum moet na begindatum liggen.', - 'select_category' => 'Selecteer minstens één categorie.', - 'select_budget' => 'Selecteer minstens één budget.', + 'select_category' => 'Selecteer categorie(ën)', + 'select_budget' => 'Selecteer budget(ten).', + 'select_tag' => 'Selecteer tag(s).', 'income_per_category' => 'Inkomen per categorie', 'expense_per_category' => 'Uitgaven per categorie', 'expense_per_budget' => 'Uitgaven per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'De import is klaar! Je kan de transacties nu terugvinden in Firefly.', 'import_finished_text_without_link' => 'Er is geen tag die al je transacties bevat. Kijk links in het menu onder "Transacties" en zoek daar je nieuwe transacties op.', 'import_finished_text_with_link' => 'Je kan je geïmporteerde transacties op deze pagina terug vinden.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'Deze functie werkt niet als je Firefly III gebruikt in combinatie met Sandstorm.IO.', ]; \ No newline at end of file diff --git a/resources/lang/pl_PL/config.php b/resources/lang/pl_PL/config.php index 29dfe740f4..3ccba5874d 100644 --- a/resources/lang/pl_PL/config.php +++ b/resources/lang/pl_PL/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'pl, Polski, pl_PL, pl_PL.utf8', + 'locale' => 'pl, Polish, polski, pl_PL, pl_PL.utf8, pl_PL.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%e %B %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/pl_PL/firefly.php b/resources/lang/pl_PL/firefly.php index d101e6129f..7a136e4ae1 100644 --- a/resources/lang/pl_PL/firefly.php +++ b/resources/lang/pl_PL/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Pokaż wszystko', 'never' => 'Nigdy', 'search_results_for' => 'Wyniki wyszukiwania dla ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'Wiadomość wysłana na adres :email została odrzucona, więc nie ma dostępu dla Ciebie.', 'deleted_error' => 'Te poświadczenia nie zgadzają się z naszymi danymi.', 'general_blocked_error' => 'Twoje konto zostało zablokowane. Dlatego nie możesz się zalogować.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Proszę wybierz więcej niż jedno konto', 'select_more_than_one_category' => 'Proszę wybierz więcej niż jedną kategorię', 'select_more_than_one_budget' => 'Proszę wybierz więcej niż jeden budżet', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'Od :start do :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Przegląd historii transakcji (audyt)', 'report_type_category' => 'Raport kategorii', 'report_type_budget' => 'Raport budżetów', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Przegląd kategorii, budżetów i rachunków', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Uwzględnione konta', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'Ten raport nie ma dodatkowych opcji', 'reports_submit' => 'Zobacz raport', 'end_after_start_date' => 'Data zakończenia raportu musi być po dacie rozpoczęcia.', - 'select_category' => 'Wybierz jedną lub więcej kategorii.', - 'select_budget' => 'Wybierz jeden lub więcej budżetów.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Dochód wg kategorii', 'expense_per_category' => 'Wydatek wg kategorii', 'expense_per_budget' => 'Wydatek wg budżetu', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/pt_BR/config.php b/resources/lang/pt_BR/config.php index 1800829bde..297140c4ca 100644 --- a/resources/lang/pt_BR/config.php +++ b/resources/lang/pt_BR/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'pt_BR, pt_BR.utf8', + 'locale' => 'pt-br, pt_BR, pt_BR.utf8, pt_BR.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%e de %B de %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/pt_BR/firefly.php b/resources/lang/pt_BR/firefly.php index 6d270fdea5..57e33c9901 100644 --- a/resources/lang/pt_BR/firefly.php +++ b/resources/lang/pt_BR/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Mostrar tudo', 'never' => 'Nunca', 'search_results_for' => 'Pesquisar resultados por ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'A mensagem enviado para :email ressaltado, não tem acesso para você.', 'deleted_error' => 'Estas credenciais não correspondem aos nossos registros.', 'general_blocked_error' => 'Sua conta foi desativada, você não pode entrar.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Por favor, selecione mais de uma conta', 'select_more_than_one_category' => 'Por favor, selecione mais de uma categoria', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Visão geral do histórico de transação (auditoria)', 'report_type_category' => 'Relatório por Categorias', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Visão geral de categorias, orçamentos e faturas', 'more_info_help' => 'Mais informações sobre esses tipos de relatórios podem ser encontradas nas páginas de ajuda. Pressione o ícone (?) no canto superior direito.', 'report_included_accounts' => 'Contas incluídas', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'Este relatório não tem mais opções', 'reports_submit' => 'Visualizar relatório', 'end_after_start_date' => 'Data de término do relatório deve ser depois da data de início.', - 'select_category' => 'Selecione uma ou mais categorias.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Receitas por categoria', 'expense_per_category' => 'Despesa por categoria', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/ru_RU/config.php b/resources/lang/ru_RU/config.php index 5544349117..4e7ce17f0f 100644 --- a/resources/lang/ru_RU/config.php +++ b/resources/lang/ru_RU/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'ru, Russian, ru_RU, ru_RU.utf8', + 'locale' => 'ru, Russian, ru_RU, ru_RU.utf8, ru_RU.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%B %e, %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/ru_RU/firefly.php b/resources/lang/ru_RU/firefly.php index a91170cd53..73e438c75f 100644 --- a/resources/lang/ru_RU/firefly.php +++ b/resources/lang/ru_RU/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Show everything', 'never' => 'Never', 'search_results_for' => 'Search results for ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'The message sent to :email bounced, so no access for you.', 'deleted_error' => 'These credentials do not match our records.', 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Categories, budgets and bills overview', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/zh_HK/config.php b/resources/lang/zh_HK/config.php index 58220429bf..827ebea3f0 100644 --- a/resources/lang/zh_HK/config.php +++ b/resources/lang/zh_HK/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'en, English, en_US, en_US.utf8', + 'locale' => 'en, English, en_US, en_US.utf8, en_US.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%B %e, %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/zh_HK/firefly.php b/resources/lang/zh_HK/firefly.php index a91170cd53..73e438c75f 100644 --- a/resources/lang/zh_HK/firefly.php +++ b/resources/lang/zh_HK/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => 'Show everything', 'never' => 'Never', 'search_results_for' => 'Search results for ":query"', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => 'The message sent to :email bounced, so no access for you.', 'deleted_error' => 'These credentials do not match our records.', 'general_blocked_error' => 'Your account has been disabled, so you cannot login.', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => 'Categories, budgets and bills overview', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/lang/zh_TW/config.php b/resources/lang/zh_TW/config.php index 8e724f5689..827ebea3f0 100644 --- a/resources/lang/zh_TW/config.php +++ b/resources/lang/zh_TW/config.php @@ -10,7 +10,7 @@ */ return [ - 'locale' => 'en, English, en_US, en_US.utf8 test', + 'locale' => 'en, English, en_US, en_US.utf8, en_US.UTF-8', 'month' => '%B %Y', 'month_and_day' => '%B %e, %Y', 'date_time' => '%B %e, %Y, @ %T', diff --git a/resources/lang/zh_TW/firefly.php b/resources/lang/zh_TW/firefly.php index 9fddfcf9d8..d609852336 100644 --- a/resources/lang/zh_TW/firefly.php +++ b/resources/lang/zh_TW/firefly.php @@ -26,6 +26,8 @@ return [ 'showEverything' => '全部顯示', 'never' => '從來沒有', 'search_results_for' => '":query" 的搜尋結果', + 'advanced_search' => 'Advanced search', + 'advanced_search_intro' => 'There are several modifiers that you can use in your search to narrow down the results. If you use any of these, the search will only return transactions. Please click the -icon for more information.', 'bounced_error' => '無法傳送電郵至 :email ,因此無法訪問。', 'deleted_error' => '帳號或密碼錯誤。', 'general_blocked_error' => '您的帳戶已被禁用,所以您不能登錄。', @@ -554,6 +556,7 @@ return [ 'select_more_than_one_account' => 'Please select more than one account', 'select_more_than_one_category' => 'Please select more than one category', 'select_more_than_one_budget' => 'Please select more than one budget', + 'select_more_than_one_tag' => 'Please select more than one tag', 'from_to' => 'From :start to :end', // categories: @@ -711,6 +714,7 @@ return [ 'report_type_audit' => 'Transaction history overview (audit)', 'report_type_category' => 'Category report', 'report_type_budget' => 'Budget report', + 'report_type_tag' => 'Tag report', 'report_type_meta-history' => '類別、 預算與賬單的概覽', 'more_info_help' => 'More information about these types of reports can be found in the help pages. Press the (?) icon in the top right corner.', 'report_included_accounts' => 'Included accounts', @@ -729,8 +733,9 @@ return [ 'report_has_no_extra_options' => 'This report has no extra options', 'reports_submit' => 'View report', 'end_after_start_date' => 'End date of report must be after start date.', - 'select_category' => 'Select one or more categories.', - 'select_budget' => 'Select one or more budgets.', + 'select_category' => 'Select category(ies)', + 'select_budget' => 'Select budget(s).', + 'select_tag' => 'Select tag(s).', 'income_per_category' => 'Income per category', 'expense_per_category' => 'Expense per category', 'expense_per_budget' => 'Expense per budget', @@ -959,4 +964,7 @@ return [ 'import_finished_intro' => 'The import has finished! You can now see the new transactions in Firefly.', 'import_finished_text_without_link' => 'It seems there is no tag that points to all your imported transactions. Please look for your imported data in the menu on the left, under "Transactions".', 'import_finished_text_with_link' => 'You can find a list of your imported transactions on the page of the tag that was created for this import.', + + // sandstorm.io errors and messages: + 'sandstorm_not_available' => 'This function is not available when you are using Firefly III within a Sandstorm.io environment.', ]; \ No newline at end of file diff --git a/resources/views/accounts/create.twig b/resources/views/accounts/create.twig index 07e55d4f55..2063b86e79 100644 --- a/resources/views/accounts/create.twig +++ b/resources/views/accounts/create.twig @@ -40,7 +40,7 @@ {% if what == 'asset' %} {{ ExpandedForm.balance('openingBalance') }} - {{ ExpandedForm.date('openingBalanceDate', phpdate('Y-m-d')) }} + {{ ExpandedForm.date('openingBalanceDate') }} {{ ExpandedForm.select('accountRole', roles,null,{'helpText' : 'asset_account_role_help'|_}) }} {{ ExpandedForm.balance('virtualBalance') }} {% endif %} @@ -76,4 +76,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/accounts/edit.twig b/resources/views/accounts/edit.twig index 29cd807ac2..e01e7f98ee 100644 --- a/resources/views/accounts/edit.twig +++ b/resources/views/accounts/edit.twig @@ -86,4 +86,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/demo/accounts/index.twig b/resources/views/demo/accounts/index.twig index 1e42bbc675..9d3cf18a02 100644 --- a/resources/views/demo/accounts/index.twig +++ b/resources/views/demo/accounts/index.twig @@ -1 +1 @@ -{{ trans('demo.accounts-index') }} \ No newline at end of file +{{ trans('demo.accounts-index') }} diff --git a/resources/views/demo/budgets/index.twig b/resources/views/demo/budgets/index.twig index 737932b3df..5717ecfce4 100644 --- a/resources/views/demo/budgets/index.twig +++ b/resources/views/demo/budgets/index.twig @@ -1 +1 @@ -{{ trans('demo.budgets-index') }} \ No newline at end of file +{{ trans('demo.budgets-index') }} diff --git a/resources/views/demo/currencies/index.twig b/resources/views/demo/currencies/index.twig index 9d155e1181..1ea152a0f2 100644 --- a/resources/views/demo/currencies/index.twig +++ b/resources/views/demo/currencies/index.twig @@ -1 +1 @@ -{{ trans('demo.currencies-index') }} \ No newline at end of file +{{ trans('demo.currencies-index') }} diff --git a/resources/views/demo/home.twig b/resources/views/demo/home.twig index 84f855689a..85268e795a 100644 --- a/resources/views/demo/home.twig +++ b/resources/views/demo/home.twig @@ -1 +1 @@ -{{ trans('demo.index', {asset: route('accounts.index', ['asset']), budgets: route('budgets.index'), reports: route('reports.index')})|raw }} \ No newline at end of file +{{ trans('demo.index', {asset: route('accounts.index', ['asset']), budgets: route('budgets.index'), reports: route('reports.index')})|raw }} diff --git a/resources/views/demo/import/configure.twig b/resources/views/demo/import/configure.twig index 1d5adc6a31..a94b4914bb 100644 --- a/resources/views/demo/import/configure.twig +++ b/resources/views/demo/import/configure.twig @@ -1,3 +1,3 @@ {{ trans('demo.import-configure-security') }}

-{{ trans('demo.import-configure-configuration') }} \ No newline at end of file +{{ trans('demo.import-configure-configuration') }} diff --git a/resources/views/demo/import/index.twig b/resources/views/demo/import/index.twig index 00e5a8d4ce..31fe3ab386 100644 --- a/resources/views/demo/import/index.twig +++ b/resources/views/demo/import/index.twig @@ -1 +1 @@ -{{ trans('demo.import-index') }} \ No newline at end of file +{{ trans('demo.import-index') }} diff --git a/resources/views/demo/index.twig b/resources/views/demo/index.twig index 84f855689a..85268e795a 100644 --- a/resources/views/demo/index.twig +++ b/resources/views/demo/index.twig @@ -1 +1 @@ -{{ trans('demo.index', {asset: route('accounts.index', ['asset']), budgets: route('budgets.index'), reports: route('reports.index')})|raw }} \ No newline at end of file +{{ trans('demo.index', {asset: route('accounts.index', ['asset']), budgets: route('budgets.index'), reports: route('reports.index')})|raw }} diff --git a/resources/views/demo/piggy-banks/index.twig b/resources/views/demo/piggy-banks/index.twig index ea776d4f25..7c0415fc31 100644 --- a/resources/views/demo/piggy-banks/index.twig +++ b/resources/views/demo/piggy-banks/index.twig @@ -1 +1 @@ -{{ trans('demo.piggy-banks-index') }} \ No newline at end of file +{{ trans('demo.piggy-banks-index') }} diff --git a/resources/views/demo/reports/index.twig b/resources/views/demo/reports/index.twig index c7d5d9aab4..535fb63c44 100644 --- a/resources/views/demo/reports/index.twig +++ b/resources/views/demo/reports/index.twig @@ -4,4 +4,4 @@ {{ trans('demo.reports-index-examples', { one: route('reports.report.default', ['1,2,3','currentMonthStart','currentMonthEnd']), two: route('reports.report.default', ['1,2,3','20160101','20161231']), - three: route('reports.report.budget', ['1,2,3','2,1','20160101','20161231'])})|raw }} \ No newline at end of file + three: route('reports.report.budget', ['1,2,3','2,1','20160101','20161231'])})|raw }} diff --git a/resources/views/demo/transactions/index.twig b/resources/views/demo/transactions/index.twig index 8a212172ce..247ad41218 100644 --- a/resources/views/demo/transactions/index.twig +++ b/resources/views/demo/transactions/index.twig @@ -1 +1 @@ -{{ trans('demo.transactions-index') }} \ No newline at end of file +{{ trans('demo.transactions-index') }} diff --git a/resources/views/emails/error-html.twig b/resources/views/emails/error-html.twig index afc890506a..5594a2a7eb 100644 --- a/resources/views/emails/error-html.twig +++ b/resources/views/emails/error-html.twig @@ -34,7 +34,7 @@ This can help fix the bug you just encountered.

- If you prefer, you can also open a new issue on Github. + If you prefer, you can also open a new issue on Github.

diff --git a/resources/views/emails/error-text.twig b/resources/views/emails/error-text.twig index 913d54d741..e195cdb631 100644 --- a/resources/views/emails/error-text.twig +++ b/resources/views/emails/error-text.twig @@ -21,7 +21,7 @@ the bug you just encountered. If you prefer, you can also open a new issue here: -https://github.com/firefly-iii/firefly-iii/issues/new +https://github.com/firefly-iii/firefly-iii/issues The full stacktrace is below: diff --git a/resources/views/error.twig b/resources/views/error.twig index 6d5f52c6ab..a41611d4f3 100644 --- a/resources/views/error.twig +++ b/resources/views/error.twig @@ -10,7 +10,12 @@

- {{ message |default('General unknown errror') }} +

{{ message |default('General unknown errror') }}

+
+
+ {% endblock %} diff --git a/resources/views/errors/404.twig b/resources/views/errors/404.twig index 41481b8501..d84ff35ca6 100644 --- a/resources/views/errors/404.twig +++ b/resources/views/errors/404.twig @@ -1,254 +1,47 @@ - - - + + + 404 + + + + + + + + {% include('partials.favicons') %} - -
-

Sorry, the page you are looking for could not be found.

+ +
+ +
+
+

404 — Firefly III cannot find this page.

+
+
+ +
+
+

+ The page you have requested does not exist. Please check that you have not entered + the wrong URL. Did you make a typo perhaps? +

+
+
+
+
+

+ If you are sure this page should exist, please open a ticket on + Github. +

+
+
+ diff --git a/resources/views/errors/FireflyException.twig b/resources/views/errors/FireflyException.twig index 9d8343e04c..01028a7e9d 100644 --- a/resources/views/errors/FireflyException.twig +++ b/resources/views/errors/FireflyException.twig @@ -38,6 +38,20 @@

+ {% if not debug %} +
+
+

+ More information about this error may be available in the log files. Search for the error above and a stack trace + will appear. This stack trace may help you track down what's going wrong. +

+

+ If you cannot find the cause of this error or when you need some help, please open a ticket on + Github. +

+
+
+ {% endif %} {% if debug %} @@ -51,5 +65,6 @@ {% endif %} + diff --git a/resources/views/export/index.twig b/resources/views/export/index.twig index afe83f4c9c..3ebcc538ea 100644 --- a/resources/views/export/index.twig +++ b/resources/views/export/index.twig @@ -107,4 +107,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/import/csv/roles.twig b/resources/views/import/csv/roles.twig index 74cf95b948..0df197187b 100644 --- a/resources/views/import/csv/roles.twig +++ b/resources/views/import/csv/roles.twig @@ -45,7 +45,13 @@ {% for i in 0..(data.columnCount-1) %} - {{ trans('csv.column') }} #{{ loop.index }} + + {% if data.columnHeaders[i] == '' %} + {{ trans('csv.column') }} #{{ loop.index }} + {% else %} + {{ data.columnHeaders[i] }} + {% endif %} + {% if data.columns[i]|length == 0 %} {{ trans('csv.no_example_data') }} diff --git a/resources/views/javascript/variables.twig b/resources/views/javascript/variables.twig index 8d188af209..6e02953236 100644 --- a/resources/views/javascript/variables.twig +++ b/resources/views/javascript/variables.twig @@ -26,4 +26,5 @@ var frac_digits = {{ localeconv.frac_digits }}; var noDataForChart = '{{ trans('firefly.no_data_for_chart')|escape }}'; var showFullList = '{{ trans('firefly.show_full_list') }}'; var showOnlyTop = '{{ trans('firefly.show_only_top',{number:listLength}) }}'; -var accountingConfig = {{ accounting|json_encode|raw }}; \ No newline at end of file +var accountingConfig = {{ accounting|json_encode|raw }}; +var token = '{{ csrf_token() }}'; diff --git a/resources/views/layout/default.twig b/resources/views/layout/default.twig index fc86a04dce..08f211925c 100644 --- a/resources/views/layout/default.twig +++ b/resources/views/layout/default.twig @@ -72,13 +72,13 @@ - - + {% if not SANDSTORM %} + {% endif %} diff --git a/resources/views/list/journals-tasker.twig b/resources/views/list/journals-tasker.twig index 184ab9431f..7502719e27 100644 --- a/resources/views/list/journals-tasker.twig +++ b/resources/views/list/journals-tasker.twig @@ -33,7 +33,11 @@ -
{% if sorting %}{% endif %}
+
{% if sorting %}{% endif %}
@@ -58,10 +62,17 @@ - - {{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }} - - {{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }} + {% if transaction.transaction_type_type == 'Transfer' %} + + {{ formatByCode(transaction.transaction_currency_code, steam_positive(transaction.transaction_amount)) }} + + {{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }} + {% else %} + + {{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }} + + {{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }} + {% endif %} diff --git a/resources/views/list/piggy-banks.twig b/resources/views/list/piggy-banks.twig index c754498b8f..2d6556f483 100644 --- a/resources/views/list/piggy-banks.twig +++ b/resources/views/list/piggy-banks.twig @@ -32,7 +32,7 @@ - {{ piggyBank.name }} + {{ piggyBank.name }} {{ piggyBank.savedSoFar|formatAmount }} diff --git a/resources/views/partials/menu-sidebar.twig b/resources/views/partials/menu-sidebar.twig index 8de86ca538..c9fc3db022 100644 --- a/resources/views/partials/menu-sidebar.twig +++ b/resources/views/partials/menu-sidebar.twig @@ -136,6 +136,7 @@ +
  • @@ -147,9 +148,11 @@ diff --git a/resources/views/piggy-banks/create.twig b/resources/views/piggy-banks/create.twig index e144dc9838..b9e132dea0 100644 --- a/resources/views/piggy-banks/create.twig +++ b/resources/views/piggy-banks/create.twig @@ -63,4 +63,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/piggy-banks/edit.twig b/resources/views/piggy-banks/edit.twig index df25b8aebc..85f225c05b 100644 --- a/resources/views/piggy-banks/edit.twig +++ b/resources/views/piggy-banks/edit.twig @@ -65,4 +65,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/preferences/index.twig b/resources/views/preferences/index.twig index 5432d9887f..0b00562525 100644 --- a/resources/views/preferences/index.twig +++ b/resources/views/preferences/index.twig @@ -281,4 +281,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/reports/index.twig b/resources/views/reports/index.twig index 85771558c0..d46984b7ea 100644 --- a/resources/views/reports/index.twig +++ b/resources/views/reports/index.twig @@ -28,6 +28,7 @@ + diff --git a/resources/views/reports/options/budget.twig b/resources/views/reports/options/budget.twig index 85d9bac773..103363f156 100644 --- a/resources/views/reports/options/budget.twig +++ b/resources/views/reports/options/budget.twig @@ -1,8 +1,10 @@ -

    - {{ 'select_budget'|_ }} -

    - +
    + +
    + +
    +
    diff --git a/resources/views/reports/options/category.twig b/resources/views/reports/options/category.twig index 126467ca26..2ff52d301a 100644 --- a/resources/views/reports/options/category.twig +++ b/resources/views/reports/options/category.twig @@ -1,8 +1,11 @@ -

    - {{ 'select_category'|_ }} -

    - \ No newline at end of file +
    + +
    + + +
    +
    diff --git a/resources/views/reports/options/tag.twig b/resources/views/reports/options/tag.twig new file mode 100644 index 0000000000..54d4663a0d --- /dev/null +++ b/resources/views/reports/options/tag.twig @@ -0,0 +1,10 @@ +
    + +
    + +
    +
    diff --git a/resources/views/reports/partials/budgets.twig b/resources/views/reports/partials/budgets.twig index be4b938c4b..97fef8c762 100644 --- a/resources/views/reports/partials/budgets.twig +++ b/resources/views/reports/partials/budgets.twig @@ -11,26 +11,33 @@ - {% for budgetLine in budgets.getBudgetLines %} - + {% set sum_budgeted = 0 %} + {% set sum_spent = 0 %} + {% set sum_left = 0 %} + {% set sum_overspent = 0 %} + {% for line in budgets %} - {% if budgetLine.getBudget.id %} - - {{ budgetLine.getBudget.name }} - - {% else %} + {% set sum_budgeted = sum_budgeted + line.budgeted %} + {% set sum_spent = sum_spent + line.spent %} + {% set sum_left = sum_left + line.left %} + {% set sum_overspent = sum_overspent + line.overspent %} + + + {% if line.type == 'no-budget' %} {{ 'no_budget'|_ }} + {% else %} + + {{ line.name }} + {% endif %} - - - {% if budgetLine.getBudgetLimit.id %} - - - {{ budgetLine.getBudgetLimit.start_date.formatLocalized(monthAndDayFormat) }} + {% if line.type == 'budget-line' %} + + + {{ line.start.formatLocalized(monthAndDayFormat) }} — - {{ budgetLine.getBudgetLimit.end_date.formatLocalized(monthAndDayFormat) }} + {{ line.end.formatLocalized(monthAndDayFormat) }} {% else %} @@ -38,47 +45,23 @@ {% endif %} - - - {% if budgetLine.getBudgetLimit.id %} - - {{ budgetLine.getBudgetLimit.amount|formatAmount }} - - {% else %} - - {{ 0|formatAmount }} - - {% endif %} - - - {% if budgetLine.getSpent != 0 %} - {{ budgetLine.getSpent|formatAmount }} - - {% endif %} - - {% if budgetLine.getSpent == 0 %} - {{ budgetLine.getSpent|formatAmount }} - {% endif %} + + {{ line.budgeted|formatAmount }} + + + {{ line.spent|formatAmount }} - {% if budgetLine.getSpent != 0 %} + {% if line.spent != 0 %} - + data-location="budget-spent-amount" data-budget-id="{{ line.id }}"> {% endif %} - - - {% if(budgetLine.getOverspent == 0) %} - {{ budgetLine.getLeft|formatAmount }} - {% endif %} + + {{ line.left|formatAmount }} - - {% if budgetLine.getOverspent != 0 %} - {{ budgetLine.getOverspent|formatAmount }} - {% endif %} + + {{ line.overspent|formatAmount }} {% endfor %} @@ -87,18 +70,11 @@ {{ 'sum'|_ }}   - {{ budgets.getBudgeted|formatAmount }} - - {% if budgets.getSpent != 0 %} - {{ budgets.getSpent|formatAmountPlain }} - {% endif %} - {% if budgets.getSpent == 0 %} - {{ budgets.getSpent|formatAmount }} - {% endif %} - + {{ sum_budgeted|formatAmount }} + {{ sum_spent|formatAmount }}   - {{ budgets.getLeft|formatAmount }} - {{ budgets.getOverspent|formatAmountPlain }} + {{ sum_left|formatAmount }} + {{ sum_overspent|formatAmount }} diff --git a/resources/views/rules/rule-group/select-transactions.twig b/resources/views/rules/rule-group/select-transactions.twig index e33b186cd9..b12e7fb14f 100644 --- a/resources/views/rules/rule-group/select-transactions.twig +++ b/resources/views/rules/rule-group/select-transactions.twig @@ -49,4 +49,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/search/index.twig b/resources/views/search/index.twig index e166a612c7..5bfb623b9a 100644 --- a/resources/views/search/index.twig +++ b/resources/views/search/index.twig @@ -16,15 +16,36 @@
    +
    +
    +

    {{ 'advanced_search'|_ }}

    +
    +
    +

    + {{ 'advanced_search_intro'|_ }} +

    + {# search form #} +
    +
    + +
    + +
    +
    +
    +
    + +
    +
    +
    +
    +

    {{ trans('firefly.results_limited', {count: limit}) }}

    - -
    - - - {% if result.transactions|length > 0 %} -
    + {% if hasModifiers %} +
    +

    {{ 'transactions'|_ }}

    @@ -33,72 +54,90 @@

    {{ trans('firefly.search_found_transactions', {count: result.transactions|length}) }}

    - {% include 'search.partials.transactions' with {'transactions' : result.transactions} %} + {% include 'search.partials.transactions-large' with {'journals' : result.transactions} %}
    - {% endif %} - {% if result.categories|length > 0 %} -
    -
    -
    -

    {{ 'categories'|_ }}

    -
    -
    -

    - {{ trans('firefly.search_found_categories', {count: result.categories|length}) }} -

    - {% include 'search.partials.categories' %} +
    + {% else %} +
    + {% if result.transactions|length > 0 %} +
    +
    +
    +

    {{ 'transactions'|_ }}

    +
    +
    +

    + {{ trans('firefly.search_found_transactions', {count: result.transactions|length}) }} +

    + {% include 'search.partials.transactions' with {'transactions' : result.transactions} %} +
    -
    - {% endif %} - {% if result.tags|length > 0 %} -
    -
    -
    -

    {{ 'tags'|_ }}

    -
    -
    -

    - {{ trans('firefly.search_found_tags', {count: result.tags|length}) }} -

    - {% include 'search.partials.tags' %} + {% endif %} + {% if result.categories|length > 0 %} +
    +
    +
    +

    {{ 'categories'|_ }}

    +
    +
    +

    + {{ trans('firefly.search_found_categories', {count: result.categories|length}) }} +

    + {% include 'search.partials.categories' %} +
    -
    - {% endif %} - {% if result.accounts|length > 0 %} -
    -
    -
    -

    {{ 'accounts'|_ }}

    -
    -
    -

    - {{ trans('firefly.search_found_accounts', {count: result.accounts|length}) }} -

    - {% include 'search.partials.accounts' %} + {% endif %} + {% if result.tags|length > 0 %} +
    +
    +
    +

    {{ 'tags'|_ }}

    +
    +
    +

    + {{ trans('firefly.search_found_tags', {count: result.tags|length}) }} +

    + {% include 'search.partials.tags' %} +
    -
    - {% endif %} - {% if result.budgets|length > 0 %} -
    -
    -
    -

    {{ 'budgets'|_ }}

    -
    -
    -

    - {{ trans('firefly.search_found_budgets', {count: result.budgets|length}) }} -

    - {% include 'search.partials.budgets' %} + {% endif %} + {% if result.accounts|length > 0 %} +
    +
    +
    +

    {{ 'accounts'|_ }}

    +
    +
    +

    + {{ trans('firefly.search_found_accounts', {count: result.accounts|length}) }} +

    + {% include 'search.partials.accounts' %} +
    -
    - {% endif %} -
    + {% endif %} + {% if result.budgets|length > 0 %} +
    +
    +
    +

    {{ 'budgets'|_ }}

    +
    +
    +

    + {{ trans('firefly.search_found_budgets', {count: result.budgets|length}) }} +

    + {% include 'search.partials.budgets' %} +
    +
    +
    + {% endif %} +
    + {% endif %} {% endif %} diff --git a/resources/views/search/partials/transactions-large.twig b/resources/views/search/partials/transactions-large.twig new file mode 100644 index 0000000000..7502719e27 --- /dev/null +++ b/resources/views/search/partials/transactions-large.twig @@ -0,0 +1,139 @@ +{{ journals.render|raw }} + + + + + + + + + + + + + {% if not hideBudgets %} + + {% endif %} + + + {% if not hideCategories %} + + {% endif %} + + + {% if not hideBills %} + + {% endif %} + + + + {% for transaction in journals %} + + + + + + + + + + + + {% if not hideBudgets %} + + {% endif %} + + + {% if not hideCategories %} + + {% endif %} + + + {% if not hideBills %} + + {% endif %} + + {% endfor %} + +
    {{ trans('list.description') }}{{ trans('list.amount') }}
    + + + {% if transaction.transaction_description|length > 0 %} + {{ transaction.transaction_description }} ({{ transaction.description }}) + {% else %} + {{ transaction.description }} + {% endif %} + + {{ splitJournalIndicator(transaction.journal_id) }} + + {% if transaction.transactionJournal.attachments|length > 0 %} + + {% endif %} + + + + {% if transaction.transaction_type_type == 'Transfer' %} + + {{ formatByCode(transaction.transaction_currency_code, steam_positive(transaction.transaction_amount)) }} + + {{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }} + {% else %} + + {{ formatByCode(transaction.transaction_currency_code, transaction.transaction_amount) }} + + {{ optionalJournalAmount(transaction.journal_id, transaction.transaction_amount, transaction.transaction_currency_code, transaction.transaction_type_type) }} + {% endif %} + + +
    + +
    +
    + {{ journals.render|raw }} +
    +
    + diff --git a/resources/views/tags/create.twig b/resources/views/tags/create.twig index 8d85dcc86a..bf78d6c3c6 100644 --- a/resources/views/tags/create.twig +++ b/resources/views/tags/create.twig @@ -91,4 +91,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/resources/views/tags/edit.twig b/resources/views/tags/edit.twig index 4012de4137..dcf7557d85 100644 --- a/resources/views/tags/edit.twig +++ b/resources/views/tags/edit.twig @@ -94,4 +94,4 @@ {% block styles %} -{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/routes/web.php b/routes/web.php index 8a7b9c8eb7..c446a58ff9 100755 --- a/routes/web.php +++ b/routes/web.php @@ -74,7 +74,6 @@ Route::group( Route::get('/flash', ['uses' => 'HomeController@testFlash', 'as' => 'test-flash']); Route::get('/home', ['uses' => 'HomeController@index', 'as' => 'home']); Route::post('/daterange', ['uses' => 'HomeController@dateRange', 'as' => 'daterange']); - Route::get('/routes', ['uses' => 'HomeController@routes', 'as' => 'all-routes']); } ); @@ -479,6 +478,7 @@ Route::group( Route::get('audit/{accountList}/{start_date}/{end_date}', ['uses' => 'ReportController@auditReport', 'as' => 'report.audit']); Route::get('category/{accountList}/{categoryList}/{start_date}/{end_date}', ['uses' => 'ReportController@categoryReport', 'as' => 'report.category']); Route::get('budget/{accountList}/{budgetList}/{start_date}/{end_date}', ['uses' => 'ReportController@budgetReport', 'as' => 'report.budget']); + Route::get('tag/{accountList}/{tagList}/{start_date}/{end_date}', ['uses' => 'ReportController@tagReport', 'as' => 'report.tag']); Route::post('', ['uses' => 'ReportController@postIndex', 'as' => 'index.post']); } diff --git a/test.sh b/test.sh index a88423359e..fbd2ec4b1e 100755 --- a/test.sh +++ b/test.sh @@ -51,9 +51,6 @@ fi # enable testing config cp $TESTINGENV $ORIGINALENV -# clear cache: -php artisan cache:clear - # reset database (optional) if [[ $resetTestFlag == "true" ]] then @@ -85,6 +82,13 @@ echo "Copy test database over original" # take database from copy: cp $DATABASECOPY $DATABASE +echo "clear caches and what-not.." +php artisan cache:clear +php artisan config:clear +php artisan route:clear +php artisan twig:clean +php artisan view:clear + # run PHPUnit if [[ $testflag == "" ]] then diff --git a/tests/CreatesApplication.php b/tests/CreatesApplication.php new file mode 100644 index 0000000000..547152f6a9 --- /dev/null +++ b/tests/CreatesApplication.php @@ -0,0 +1,22 @@ +make(Kernel::class)->bootstrap(); + + return $app; + } +} diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php deleted file mode 100644 index 74a0a460d6..0000000000 --- a/tests/ExampleTest.php +++ /dev/null @@ -1,27 +0,0 @@ -visit('/') - ->see('Firefly'); - } -} diff --git a/tests/acceptance/Controllers/AccountControllerTest.php b/tests/Feature/Controllers/AccountControllerTest.php similarity index 56% rename from tests/acceptance/Controllers/AccountControllerTest.php rename to tests/Feature/Controllers/AccountControllerTest.php index e42a5a8d1a..2f7ca99259 100644 --- a/tests/acceptance/Controllers/AccountControllerTest.php +++ b/tests/Feature/Controllers/AccountControllerTest.php @@ -1,13 +1,16 @@ be($this->user()); - $this->call('GET', route('accounts.create', ['asset'])); - $this->assertResponseStatus(200); + $response = $this->get(route('accounts.create', ['asset'])); + $response->assertStatus(200); // has bread crumb - $this->see('