diff --git a/app/Export/Collector/AttachmentCollector.php b/app/Export/Collector/AttachmentCollector.php
index 706fc12ab8..2f67d299c7 100644
--- a/app/Export/Collector/AttachmentCollector.php
+++ b/app/Export/Collector/AttachmentCollector.php
@@ -11,13 +11,15 @@ declare(strict_types = 1);
namespace FireflyIII\Export\Collector;
use Amount;
-use Auth;
use Crypt;
use FireflyIII\Models\Attachment;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\TransactionJournal;
+use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use Illuminate\Contracts\Encryption\DecryptException;
+use Illuminate\Support\Collection;
use Log;
+use Storage;
/**
* Class AttachmentCollector
@@ -28,6 +30,12 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
{
/** @var string */
private $explanationString = '';
+ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
+ private $exportDisk;
+ /** @var AttachmentRepositoryInterface */
+ private $repository;
+ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
+ private $uploadDisk;
/**
* AttachmentCollector constructor.
@@ -36,6 +44,11 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
*/
public function __construct(ExportJob $job)
{
+ $this->repository = app('FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface');
+ // make storage:
+ $this->uploadDisk = Storage::disk('upload');
+ $this->exportDisk = Storage::disk('export');
+
parent::__construct($job);
}
@@ -45,35 +58,18 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
public function run()
{
// grab all the users attachments:
- $attachments = Auth::user()->attachments()->get();
-
- Log::debug('Found ' . $attachments->count() . ' attachments.');
+ $attachments = $this->getAttachments();
/** @var Attachment $attachment */
foreach ($attachments as $attachment) {
- $originalFile = storage_path('upload') . DIRECTORY_SEPARATOR . 'at-' . $attachment->id . '.data';
- if (file_exists($originalFile)) {
- Log::debug('Stored 1 attachment');
- try {
- $decrypted = Crypt::decrypt(file_get_contents($originalFile));
- $newFile = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-Attachment nr. ' . $attachment->id . ' - '
- . $attachment->filename;
- file_put_contents($newFile, $decrypted);
- $this->getFiles()->push($newFile);
-
- // explain:
- $this->explain($attachment);
- } catch (DecryptException $e) {
- Log::error('Catchable error: could not decrypt attachment #' . $attachment->id);
- }
-
- }
+ $this->exportAttachment($attachment);
}
// put the explanation string in a file and attach it as well.
- $explanationFile = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-Source of all your attachments explained.txt';
- file_put_contents($explanationFile, $this->explanationString);
- $this->getFiles()->push($explanationFile);
+ $file = $this->job->key . '-Source of all your attachments explained.txt';
+ $this->exportDisk->put($file, $this->explanationString);
+ Log::debug('Also put explanation file "' . $file . '" in the zip.');
+ $this->getFiles()->push($file);
}
/**
@@ -96,4 +92,57 @@ class AttachmentCollector extends BasicCollector implements CollectorInterface
$this->explanationString .= $string;
}
+
+ /**
+ * @param Attachment $attachment
+ *
+ * @return bool
+ */
+ private function exportAttachment(Attachment $attachment): bool
+ {
+ $file = $attachment->fileName();
+ Log::debug('Original file is at "' . $file . '".');
+ if ($this->uploadDisk->exists($file)) {
+ try {
+ $decrypted = Crypt::decrypt($this->uploadDisk->get($file));
+ $exportFile = $this->exportFileName($attachment);
+ $this->exportDisk->put($exportFile, $decrypted);
+ $this->getFiles()->push($exportFile);
+ Log::debug('Stored file content in new file "' . $exportFile . '", which will be in the final zip file.');
+
+ // explain:
+ $this->explain($attachment);
+ } catch (DecryptException $e) {
+ Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
+ }
+
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns the new file name for the export file.
+ *
+ * @param $attachment
+ *
+ * @return string
+ */
+ private function exportFileName($attachment): string
+ {
+
+ return sprintf('%s-Attachment nr. %s - %s', $this->job->key, strval($attachment->id), $attachment->filename);
+ }
+
+ /**
+ * @return Collection
+ */
+ private function getAttachments(): Collection
+ {
+ $attachments = $this->repository->get();
+
+ Log::debug('Found ' . $attachments->count() . ' attachments.');
+
+ return $attachments;
+ }
}
diff --git a/app/Export/Collector/UploadCollector.php b/app/Export/Collector/UploadCollector.php
index 817385fc93..48cd660287 100644
--- a/app/Export/Collector/UploadCollector.php
+++ b/app/Export/Collector/UploadCollector.php
@@ -15,6 +15,8 @@ use Crypt;
use FireflyIII\Models\ExportJob;
use Illuminate\Contracts\Encryption\DecryptException;
use Log;
+use Storage;
+
/**
* Class UploadCollector
*
@@ -22,6 +24,12 @@ use Log;
*/
class UploadCollector extends BasicCollector implements CollectorInterface
{
+ /** @var string */
+ private $expected;
+ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
+ private $exportDisk;
+ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
+ private $uploadDisk;
/**
* AttachmentCollector constructor.
@@ -31,6 +39,11 @@ class UploadCollector extends BasicCollector implements CollectorInterface
public function __construct(ExportJob $job)
{
parent::__construct($job);
+
+ // make storage:
+ $this->uploadDisk = Storage::disk('upload');
+ $this->exportDisk = Storage::disk('export');
+ $this->expected = 'csv-upload-' . Auth::user()->id . '-';
}
/**
@@ -39,31 +52,68 @@ class UploadCollector extends BasicCollector implements CollectorInterface
public function run()
{
// grab upload directory.
- $path = storage_path('upload');
- $files = scandir($path);
- // only allow old uploads for this user:
- $expected = 'csv-upload-' . Auth::user()->id . '-';
- $len = strlen($expected);
+ $files = $this->uploadDisk->files();
+ Log::debug('Found ' . count($files) . ' files in the upload directory.');
+
foreach ($files as $entry) {
- if (substr($entry, 0, $len) === $expected) {
- try {
- // this is an original upload.
- $parts = explode('-', str_replace(['.csv.encrypted', $expected], '', $entry));
- $originalUpload = intval($parts[1]);
- $date = date('Y-m-d \a\t H-i-s', $originalUpload);
- $newFileName = 'Old CSV import dated ' . $date . '.csv';
- $content = Crypt::decrypt(file_get_contents($path . DIRECTORY_SEPARATOR . $entry));
- $fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-' . $newFileName;
+ $this->processOldUpload($entry);
+ }
+ }
- // write to file:
- file_put_contents($fullPath, $content);
+ /**
+ * @param string $entry
+ *
+ * @return string
+ */
+ private function getOriginalUploadDate(string $entry): string
+ {
+ // this is an original upload.
+ $parts = explode('-', str_replace(['.csv.encrypted', $this->expected], '', $entry));
+ $originalUpload = intval($parts[1]);
+ $date = date('Y-m-d \a\t H-i-s', $originalUpload);
- // add entry to set:
- $this->getFiles()->push($fullPath);
- } catch (DecryptException $e) {
- Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped.');
- }
+ return $date;
+ }
+
+ /**
+ * @param string $entry
+ *
+ * @return bool
+ */
+ private function isValidFile(string $entry): bool
+ {
+ $len = strlen($this->expected);
+ if (substr($entry, 0, $len) === $this->expected) {
+ Log::debug($entry . ' is part of this users original uploads.');
+
+ return true;
+ }
+ Log::debug($entry . ' is not part of this users original uploads.');
+
+ return false;
+ }
+
+ /**
+ * @param $entry
+ */
+ private function processOldUpload(string $entry)
+ {
+ $content = '';
+
+ if ($this->isValidFile($entry)) {
+ try {
+ $content = Crypt::decrypt($this->uploadDisk->get($entry));
+ } catch (DecryptException $e) {
+ Log::error('Could not decrypt old CSV import file ' . $entry . '. Skipped because ' . $e->getMessage());
}
}
+ if (strlen($content) > 0) {
+ // continue with file:
+ $date = $this->getOriginalUploadDate($entry);
+ $file = $this->job->key . '-Old CSV import dated ' . $date . '.csv';
+ Log::debug('Will put "' . $file . '" in the zip file.');
+ $this->exportDisk->put($file, $content);
+ $this->getFiles()->push($file);
+ }
}
}
diff --git a/app/Export/ConfigurationFile.php b/app/Export/ConfigurationFile.php
index a7c989b8d9..c78e6501b7 100644
--- a/app/Export/ConfigurationFile.php
+++ b/app/Export/ConfigurationFile.php
@@ -11,6 +11,8 @@ declare(strict_types = 1);
namespace FireflyIII\Export;
use FireflyIII\Models\ExportJob;
+use Log;
+use Storage;
/**
* Class ConfigurationFile
@@ -19,6 +21,8 @@ use FireflyIII\Models\ExportJob;
*/
class ConfigurationFile
{
+ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
+ private $exportDisk;
/** @var ExportJob */
private $job;
@@ -29,7 +33,8 @@ class ConfigurationFile
*/
public function __construct(ExportJob $job)
{
- $this->job = $job;
+ $this->job = $job;
+ $this->exportDisk = Storage::disk('export');
}
/**
@@ -51,9 +56,10 @@ class ConfigurationFile
foreach ($fields as $field) {
$configuration['roles'][] = $types[$field];
}
-
- $file = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-configuration.json';
- file_put_contents($file, json_encode($configuration, JSON_PRETTY_PRINT));
+ $file = $this->job->key . '-configuration.json';
+ Log::debug('Created JSON config file.');
+ Log::debug('Will put "' . $file . '" in the ZIP file.');
+ $this->exportDisk->put($file, json_encode($configuration, JSON_PRETTY_PRINT));
return $file;
}
diff --git a/app/Export/Exporter/CsvExporter.php b/app/Export/Exporter/CsvExporter.php
index 9a8d414a06..f0d2675cf8 100644
--- a/app/Export/Exporter/CsvExporter.php
+++ b/app/Export/Exporter/CsvExporter.php
@@ -14,6 +14,7 @@ use FireflyIII\Export\Entry;
use FireflyIII\Models\ExportJob;
use League\Csv\Writer;
use SplFileObject;
+use Storage;
/**
* Class CsvExporter
@@ -25,9 +26,6 @@ class CsvExporter extends BasicExporter implements ExporterInterface
/** @var string */
private $fileName;
- /** @var resource */
- private $handler;
-
/**
* CsvExporter constructor.
*
@@ -36,6 +34,7 @@ class CsvExporter extends BasicExporter implements ExporterInterface
public function __construct(ExportJob $job)
{
parent::__construct($job);
+
}
/**
@@ -54,9 +53,11 @@ class CsvExporter extends BasicExporter implements ExporterInterface
// create temporary file:
$this->tempFile();
+ // necessary for CSV writer:
+ $fullPath = storage_path('export') . DIRECTORY_SEPARATOR . $this->fileName;
+
// create CSV writer:
- $writer = Writer::createFromPath(new SplFileObject($this->fileName, 'a+'), 'w');
- //the $writer object open mode will be 'w'!!
+ $writer = Writer::createFromPath(new SplFileObject($fullPath, 'a+'), 'w');
// all rows:
$rows = [];
@@ -76,8 +77,6 @@ class CsvExporter extends BasicExporter implements ExporterInterface
private function tempFile()
{
- $fileName = $this->job->key . '-records.csv';
- $this->fileName = storage_path('export') . DIRECTORY_SEPARATOR . $fileName;
- $this->handler = fopen($this->fileName, 'w');
+ $this->fileName = $this->job->key . '-records.csv';
}
}
diff --git a/app/Export/Processor.php b/app/Export/Processor.php
index 9f59c7e2b4..41adf0722d 100644
--- a/app/Export/Processor.php
+++ b/app/Export/Processor.php
@@ -16,6 +16,8 @@ use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\TransactionJournal;
use Illuminate\Support\Collection;
+use Log;
+use Storage;
use ZipArchive;
/**
@@ -88,6 +90,13 @@ class Processor
$args = [$this->accounts, Auth::user(), $this->settings['startDate'], $this->settings['endDate']];
$journalCollector = app('FireflyIII\Repositories\Journal\JournalCollector', $args);
$this->journals = $journalCollector->collect();
+ Log::debug(
+ 'Collected ' .
+ $this->journals->count() . ' journals (between ' .
+ $this->settings['startDate']->format('Y-m-d') . ' and ' .
+ $this->settings['endDate']->format('Y-m-d')
+ . ').'
+ );
}
public function collectOldUploads()
@@ -103,10 +112,13 @@ class Processor
*/
public function convertJournals()
{
+ $count = 0;
/** @var TransactionJournal $journal */
foreach ($this->journals as $journal) {
$this->exportEntries->push(Entry::fromJournal($journal));
+ $count++;
}
+ Log::debug('Converted ' . $count . ' journals to "Entry" objects.');
}
public function createConfigFile()
@@ -118,24 +130,32 @@ class Processor
public function createZipFile()
{
$zip = new ZipArchive;
- $filename = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '.zip';
+ $file = $this->job->key . '.zip';
+ $fullPath = storage_path('export') . '/' . $file;
+ Log::debug('Will create zip file at ' . $fullPath);
- if ($zip->open($filename, ZipArchive::CREATE) !== true) {
+ if ($zip->open($fullPath, ZipArchive::CREATE) !== true) {
throw new FireflyException('Cannot store zip file.');
}
// for each file in the collection, add it to the zip file.
- $search = storage_path('export') . DIRECTORY_SEPARATOR . $this->job->key . '-';
- /** @var string $file */
- foreach ($this->getFiles() as $file) {
- $zipName = str_replace($search, '', $file);
- $zip->addFile($file, $zipName);
+ $disk = Storage::disk('export');
+ foreach ($this->getFiles() as $entry) {
+ // is part of this job?
+ $zipFileName = str_replace($this->job->key . '-', '', $entry);
+ $result = $zip->addFromString($zipFileName, $disk->get($entry));
+ if (!$result) {
+ Log::error('Could not add "' . $entry . '" into zip file as "' . $zipFileName . '".');
+ }
}
+
$zip->close();
// delete the files:
foreach ($this->getFiles() as $file) {
- unlink($file);
+ Log::debug('Will now delete file "' . $file . '".');
+ $disk->delete($file);
}
+ Log::debug('Done!');
}
/**
@@ -145,9 +165,11 @@ class Processor
{
$exporterClass = Config::get('firefly.export_formats.' . $this->exportFormat);
$exporter = app($exporterClass, [$this->job]);
+ Log::debug('Going to export ' . $this->exportEntries->count() . ' export entries into ' . $this->exportFormat . ' format.');
$exporter->setEntries($this->exportEntries);
$exporter->run();
$this->files->push($exporter->getFileName());
+ Log::debug('Added "' . $exporter->getFileName() . '" to the list of files to include in the zip.');
}
/**
diff --git a/app/Helpers/Attachments/AttachmentHelper.php b/app/Helpers/Attachments/AttachmentHelper.php
index 08e9086af4..d23e74b35f 100644
--- a/app/Helpers/Attachments/AttachmentHelper.php
+++ b/app/Helpers/Attachments/AttachmentHelper.php
@@ -10,6 +10,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\MessageBag;
use Input;
use Log;
+use Storage;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use TypeError;
@@ -30,6 +31,9 @@ class AttachmentHelper implements AttachmentHelperInterface
/** @var int */
protected $maxUploadSize;
+ /** @var \Illuminate\Contracts\Filesystem\Filesystem */
+ protected $uploadDisk;
+
/**
*
*/
@@ -39,6 +43,7 @@ class AttachmentHelper implements AttachmentHelperInterface
$this->allowedMimes = Config::get('firefly.allowedMimes');
$this->errors = new MessageBag;
$this->messages = new MessageBag;
+ $this->uploadDisk = Storage::disk('upload');
}
/**
@@ -148,15 +153,13 @@ class AttachmentHelper implements AttachmentHelperInterface
$attachment->uploaded = 0;
$attachment->save();
- $path = $file->getRealPath(); // encrypt and move file to storage.
- $content = file_get_contents($path);
+ $fileObject = $file->openFile('r');
+ $fileObject->rewind();
+ $content = $fileObject->fread($file->getSize());
$encrypted = Crypt::encrypt($content);
// store it:
- $upload = $this->getAttachmentLocation($attachment);
- if (is_writable(dirname($upload))) {
- file_put_contents($upload, $encrypted);
- }
+ $this->uploadDisk->put($attachment->fileName(), $encrypted);
$attachment->uploaded = 1; // update attachment
$attachment->save();
diff --git a/app/Http/Controllers/Chart/CategoryController.php b/app/Http/Controllers/Chart/CategoryController.php
index 409d20a21a..bdefe371f0 100644
--- a/app/Http/Controllers/Chart/CategoryController.php
+++ b/app/Http/Controllers/Chart/CategoryController.php
@@ -7,6 +7,7 @@ namespace FireflyIII\Http\Controllers\Chart;
use Carbon\Carbon;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Category;
+use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface as CRI;
use FireflyIII\Repositories\Category\SingleCategoryRepositoryInterface as SCRI;
use FireflyIII\Support\CacheProperties;
@@ -153,7 +154,7 @@ class CategoryController extends Controller
*
* @return \Symfony\Component\HttpFoundation\Response
*/
- public function frontpage(CRI $repository)
+ public function frontpage(CRI $repository, ARI $accountRepository)
{
$start = session('start', Carbon::now()->startOfMonth());
@@ -170,8 +171,9 @@ class CategoryController extends Controller
}
// get data for categories (and "no category"):
- $set = $repository->spentForAccountsPerMonth(new Collection, $start, $end);
- $outside = $repository->sumSpentNoCategory(new Collection, $start, $end);
+ $accounts = $accountRepository->getAccounts(['Default account', 'Asset account', 'Cash account']);
+ $set = $repository->spentForAccountsPerMonth($accounts, $start, $end);
+ $outside = $repository->sumSpentNoCategory($accounts, $start, $end);
// this is a "fake" entry for the "no category" entry.
$entry = new stdClass();
diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php
index 27e65214af..b0f15e5d1a 100644
--- a/app/Http/Controllers/ExportController.php
+++ b/app/Http/Controllers/ExportController.php
@@ -19,6 +19,7 @@ use FireflyIII\Http\Requests\ExportFormRequest;
use FireflyIII\Models\ExportJob;
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface as EJRI;
+use Log;
use Preferences;
use Response;
use View;
@@ -51,7 +52,7 @@ class ExportController extends Controller
$quoted = sprintf('"%s"', addcslashes($name, '"\\'));
$job->change('export_downloaded');
-
+ Log::debug('Will send user file "' . $file . '".');
return response(file_get_contents($file), 200)
->header('Content-Description', 'File Transfer')
diff --git a/app/Models/Attachment.php b/app/Models/Attachment.php
index 4eeaad603c..8397fda56d 100644
--- a/app/Models/Attachment.php
+++ b/app/Models/Attachment.php
@@ -36,6 +36,22 @@ class Attachment extends Model
protected $fillable = ['attachable_id', 'attachable_type', 'user_id', 'md5', 'filename', 'mime', 'title', 'notes', 'description', 'size', 'uploaded'];
+ /**
+ * @param Attachment $value
+ *
+ * @return Attachment
+ */
+ public static function routeBinder(Attachment $value)
+ {
+ if (Auth::check()) {
+
+ if ($value->user_id == Auth::user()->id) {
+ return $value;
+ }
+ }
+ throw new NotFoundHttpException;
+ }
+
/**
* Get all of the owning imageable models.
*/
@@ -45,14 +61,30 @@ class Attachment extends Model
}
/**
- * @codeCoverageIgnore
- * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ * Returns the expected filename for this attachment.
+ *
+ * @return string
*/
- public function user()
+ public function fileName(): string
{
- return $this->belongsTo('FireflyIII\User');
+ return sprintf('at-%s.data', strval($this->id));
}
+ /**
+ * @codeCoverageIgnore
+ *
+ * @param $value
+ *
+ * @return null|string
+ */
+ public function getDescriptionAttribute($value)
+ {
+ if (is_null($value)) {
+ return null;
+ }
+
+ return Crypt::decrypt($value);
+ }
/**
* @codeCoverageIgnore
@@ -70,14 +102,6 @@ class Attachment extends Model
return Crypt::decrypt($value);
}
- /**
- * @param string $value
- */
- public function setFilenameAttribute($value)
- {
- $this->attributes['filename'] = Crypt::encrypt($value);
- }
-
/**
* @codeCoverageIgnore
*
@@ -95,11 +119,19 @@ class Attachment extends Model
}
/**
- * @param string $value
+ * @codeCoverageIgnore
+ *
+ * @param $value
+ *
+ * @return null|string
*/
- public function setMimeAttribute($value)
+ public function getNotesAttribute($value)
{
- $this->attributes['mime'] = Crypt::encrypt($value);
+ if (is_null($value)) {
+ return null;
+ }
+
+ return Crypt::decrypt($value);
}
/**
@@ -118,30 +150,6 @@ class Attachment extends Model
return Crypt::decrypt($value);
}
- /**
- * @param string $value
- */
- public function setTitleAttribute($value)
- {
- $this->attributes['title'] = Crypt::encrypt($value);
- }
-
- /**
- * @codeCoverageIgnore
- *
- * @param $value
- *
- * @return null|string
- */
- public function getDescriptionAttribute($value)
- {
- if (is_null($value)) {
- return null;
- }
-
- return Crypt::decrypt($value);
- }
-
/**
* @param string $value
*/
@@ -151,19 +159,19 @@ class Attachment extends Model
}
/**
- * @codeCoverageIgnore
- *
- * @param $value
- *
- * @return null|string
+ * @param string $value
*/
- public function getNotesAttribute($value)
+ public function setFilenameAttribute($value)
{
- if (is_null($value)) {
- return null;
- }
+ $this->attributes['filename'] = Crypt::encrypt($value);
+ }
- return Crypt::decrypt($value);
+ /**
+ * @param string $value
+ */
+ public function setMimeAttribute($value)
+ {
+ $this->attributes['mime'] = Crypt::encrypt($value);
}
/**
@@ -175,19 +183,20 @@ class Attachment extends Model
}
/**
- * @param Attachment $value
- *
- * @return Attachment
+ * @param string $value
*/
- public static function routeBinder(Attachment $value)
+ public function setTitleAttribute($value)
{
- if (Auth::check()) {
+ $this->attributes['title'] = Crypt::encrypt($value);
+ }
- if ($value->user_id == Auth::user()->id) {
- return $value;
- }
- }
- throw new NotFoundHttpException;
+ /**
+ * @codeCoverageIgnore
+ * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
+ */
+ public function user()
+ {
+ return $this->belongsTo('FireflyIII\User');
}
}
diff --git a/app/Models/ExportJob.php b/app/Models/ExportJob.php
index a03e1bca94..17583ef18c 100644
--- a/app/Models/ExportJob.php
+++ b/app/Models/ExportJob.php
@@ -12,6 +12,7 @@ namespace FireflyIII\Models;
use Auth;
use Illuminate\Database\Eloquent\Model;
+use Log;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
@@ -50,6 +51,7 @@ class ExportJob extends Model
*/
public function change($status)
{
+ Log::debug('Job ' . $this->key . ' to status "' . $status . '".');
$this->status = $status;
$this->save();
}
diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php
index d8520d0d54..5165d497f8 100644
--- a/app/Repositories/Attachment/AttachmentRepository.php
+++ b/app/Repositories/Attachment/AttachmentRepository.php
@@ -3,7 +3,9 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\Attachment;
+use Auth;
use FireflyIII\Models\Attachment;
+use Illuminate\Support\Collection;
/**
* Class AttachmentRepository
@@ -26,9 +28,18 @@ class AttachmentRepository implements AttachmentRepositoryInterface
$file = $helper->getAttachmentLocation($attachment);
unlink($file);
$attachment->delete();
+
return true;
}
+ /**
+ * @return Collection
+ */
+ public function get(): Collection
+ {
+ return Auth::user()->attachments()->get();
+ }
+
/**
* @param Attachment $attachment
* @param array $data
diff --git a/app/Repositories/Attachment/AttachmentRepositoryInterface.php b/app/Repositories/Attachment/AttachmentRepositoryInterface.php
index 0cd01dff73..2c25be8baa 100644
--- a/app/Repositories/Attachment/AttachmentRepositoryInterface.php
+++ b/app/Repositories/Attachment/AttachmentRepositoryInterface.php
@@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace FireflyIII\Repositories\Attachment;
use FireflyIII\Models\Attachment;
+use Illuminate\Support\Collection;
/**
* Interface AttachmentRepositoryInterface
@@ -20,6 +21,11 @@ interface AttachmentRepositoryInterface
*/
public function destroy(Attachment $attachment): bool;
+ /**
+ * @return Collection
+ */
+ public function get(): Collection;
+
/**
* @param Attachment $attachment
* @param array $attachmentData
diff --git a/app/Support/Amount.php b/app/Support/Amount.php
index 3eb21e4522..49f5f6d0cc 100644
--- a/app/Support/Amount.php
+++ b/app/Support/Amount.php
@@ -63,8 +63,8 @@ class Amount
/**
*
- * @param TransactionJournal $journal
- * @param bool $coloured
+ * @param \FireflyIII\Models\TransactionJournal $journal
+ * @param bool $coloured
*
* @return string
*/
diff --git a/config/filesystems.php b/config/filesystems.php
index 3fffcf0a2f..20f5c4d2e3 100644
--- a/config/filesystems.php
+++ b/config/filesystems.php
@@ -48,6 +48,15 @@ return [
'root' => storage_path('app'),
],
+ 'upload' => [
+ 'driver' => 'local',
+ 'root' => storage_path('upload'),
+ ],
+ 'export' => [
+ 'driver' => 'local',
+ 'root' => storage_path('export'),
+ ],
+
'ftp' => [
'driver' => 'ftp',
'host' => 'ftp.example.com',
diff --git a/public/android-chrome-144x144.png b/public/android-chrome-144x144.png
index 5bbc2e7a61..0fbc935ef5 100644
Binary files a/public/android-chrome-144x144.png and b/public/android-chrome-144x144.png differ
diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png
index 325f76a32c..fb8549caef 100644
Binary files a/public/android-chrome-192x192.png and b/public/android-chrome-192x192.png differ
diff --git a/public/android-chrome-36x36.png b/public/android-chrome-36x36.png
index 8bbc22da5c..c101427bd7 100644
Binary files a/public/android-chrome-36x36.png and b/public/android-chrome-36x36.png differ
diff --git a/public/android-chrome-48x48.png b/public/android-chrome-48x48.png
index 948730fdca..3817a33ab7 100644
Binary files a/public/android-chrome-48x48.png and b/public/android-chrome-48x48.png differ
diff --git a/public/android-chrome-72x72.png b/public/android-chrome-72x72.png
index 55a7375e8c..92ae9f437b 100644
Binary files a/public/android-chrome-72x72.png and b/public/android-chrome-72x72.png differ
diff --git a/public/android-chrome-96x96.png b/public/android-chrome-96x96.png
index 7ecebf0a2e..3602979589 100644
Binary files a/public/android-chrome-96x96.png and b/public/android-chrome-96x96.png differ
diff --git a/public/apple-touch-icon-114x114.png b/public/apple-touch-icon-114x114.png
index aa4623e402..498ea65bd1 100644
Binary files a/public/apple-touch-icon-114x114.png and b/public/apple-touch-icon-114x114.png differ
diff --git a/public/apple-touch-icon-120x120.png b/public/apple-touch-icon-120x120.png
index 69f186adff..542d5330e4 100644
Binary files a/public/apple-touch-icon-120x120.png and b/public/apple-touch-icon-120x120.png differ
diff --git a/public/apple-touch-icon-144x144.png b/public/apple-touch-icon-144x144.png
index b02e2e380d..d4aab1e910 100644
Binary files a/public/apple-touch-icon-144x144.png and b/public/apple-touch-icon-144x144.png differ
diff --git a/public/apple-touch-icon-152x152.png b/public/apple-touch-icon-152x152.png
index 927af49f12..9e51ddfb64 100644
Binary files a/public/apple-touch-icon-152x152.png and b/public/apple-touch-icon-152x152.png differ
diff --git a/public/apple-touch-icon-180x180.png b/public/apple-touch-icon-180x180.png
index f3eb5fb0e0..c0f50f32f5 100644
Binary files a/public/apple-touch-icon-180x180.png and b/public/apple-touch-icon-180x180.png differ
diff --git a/public/apple-touch-icon-57x57.png b/public/apple-touch-icon-57x57.png
index f2141ad174..414e32f2ee 100644
Binary files a/public/apple-touch-icon-57x57.png and b/public/apple-touch-icon-57x57.png differ
diff --git a/public/apple-touch-icon-60x60.png b/public/apple-touch-icon-60x60.png
index dd7b9d7f8c..e05470b64b 100644
Binary files a/public/apple-touch-icon-60x60.png and b/public/apple-touch-icon-60x60.png differ
diff --git a/public/apple-touch-icon-72x72.png b/public/apple-touch-icon-72x72.png
index 360ad6b514..d2080d08e2 100644
Binary files a/public/apple-touch-icon-72x72.png and b/public/apple-touch-icon-72x72.png differ
diff --git a/public/apple-touch-icon-76x76.png b/public/apple-touch-icon-76x76.png
index 25cd70ee50..47bd65a56d 100644
Binary files a/public/apple-touch-icon-76x76.png and b/public/apple-touch-icon-76x76.png differ
diff --git a/public/apple-touch-icon-precomposed.png b/public/apple-touch-icon-precomposed.png
index d37f2828ac..0b6bb71456 100644
Binary files a/public/apple-touch-icon-precomposed.png and b/public/apple-touch-icon-precomposed.png differ
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
index f3eb5fb0e0..c0f50f32f5 100644
Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ
diff --git a/public/browserconfig.xml b/public/browserconfig.xml
index d01e2c2194..6d6066d3f2 100644
--- a/public/browserconfig.xml
+++ b/public/browserconfig.xml
@@ -2,11 +2,11 @@