Deprecate the export function.

This commit is contained in:
James Cole 2019-06-07 18:19:24 +02:00
parent 9c5df6ab6e
commit 779650f63d
No known key found for this signature in database
GPG Key ID: C16961E655E74B5E
23 changed files with 13 additions and 2193 deletions

View File

@ -1,154 +0,0 @@
<?php
/**
* AttachmentCollector.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Collector;
use Carbon\Carbon;
use Crypt;
use FireflyIII\Models\Attachment;
use FireflyIII\Repositories\Attachment\AttachmentRepositoryInterface;
use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Collection;
use Log;
use Storage;
/**
* Class AttachmentCollector.
*
* @deprecated
* @codeCoverageIgnore
*/
class AttachmentCollector extends BasicCollector implements CollectorInterface
{
/** @var Carbon The end date of the range. */
private $end;
/** @var \Illuminate\Contracts\Filesystem\Filesystem File system */
private $exportDisk;
/** @var AttachmentRepositoryInterface Attachment repository */
private $repository;
/** @var Carbon Start date of range */
private $start;
/** @var \Illuminate\Contracts\Filesystem\Filesystem Disk with uploads on it */
private $uploadDisk;
/**
* AttachmentCollector constructor.
*/
public function __construct()
{
/** @var AttachmentRepositoryInterface repository */
$this->repository = app(AttachmentRepositoryInterface::class);
// make storage:
$this->uploadDisk = Storage::disk('upload');
$this->exportDisk = Storage::disk('export');
parent::__construct();
}
/**
* Run the routine.
*
* @return bool
*/
public function run(): bool
{
// grab all the users attachments:
$attachments = $this->getAttachments();
/** @var Attachment $attachment */
foreach ($attachments as $attachment) {
$this->exportAttachment($attachment);
}
return true;
}
/**
* Set the start and end date.
*
* @param Carbon $start
* @param Carbon $end
*/
public function setDates(Carbon $start, Carbon $end)
{
$this->start = $start;
$this->end = $end;
}
/** @noinspection MultipleReturnStatementsInspection */
/**
* Export attachments.
*
* @param Attachment $attachment
*
* @return bool
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
private function exportAttachment(Attachment $attachment): bool
{
$file = $attachment->fileName();
$decrypted = false;
if ($this->uploadDisk->exists($file)) {
try {
$decrypted = Crypt::decrypt($this->uploadDisk->get($file));
} catch (DecryptException|FileNotFoundException $e) {
Log::error('Catchable error: could not decrypt attachment #' . $attachment->id . ' because: ' . $e->getMessage());
return false;
}
}
if (false === $decrypted) {
return false;
}
$exportFile = $this->exportFileName($attachment);
$this->exportDisk->put($exportFile, $decrypted);
$this->getEntries()->push($exportFile);
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, (string)$attachment->id, $attachment->filename);
}
/**
* Get the attachments.
*
* @return Collection
*/
private function getAttachments(): Collection
{
$this->repository->setUser($this->user);
return $this->repository->getBetween($this->start, $this->end);
}
}

View File

@ -1,94 +0,0 @@
<?php
/**
* BasicCollector.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Collector;
use FireflyIII\Models\ExportJob;
use FireflyIII\User;
use Illuminate\Support\Collection;
/**
* Class BasicCollector.
*
* @codeCoverageIgnore
* @deprecated
*/
class BasicCollector
{
/** @var ExportJob The job to export. */
protected $job;
/** @var User The user */
protected $user;
/** @var Collection All the entries. */
private $entries;
/**
* BasicCollector constructor.
*/
public function __construct()
{
$this->entries = new Collection;
}
/**
* Get all entries.
*
* @return Collection
*/
public function getEntries(): Collection
{
return $this->entries;
}
/**
* Set entries.
*
* @param Collection $entries
*/
public function setEntries(Collection $entries): void
{
$this->entries = $entries;
}
/**
* Set export job.
*
* @param ExportJob $job
*/
public function setJob(ExportJob $job): void
{
$this->job = $job;
$this->user = $job->user;
}
/**
* Set user.
*
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
}

View File

@ -1,67 +0,0 @@
<?php
/**
* CollectorInterface.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Collector;
use FireflyIII\Models\ExportJob;
use Illuminate\Support\Collection;
/**
* Interface CollectorInterface.
*
* @codeCoverageIgnore
* @deprecated
*/
interface CollectorInterface
{
/**
* Get entries.
*
* @return Collection
*/
public function getEntries(): Collection;
/**
* Run the collector.
*
* @return bool
*/
public function run(): bool;
/**
* Set entries.
*
* @param Collection $entries
*/
public function setEntries(Collection $entries);
/**
* Set export job.
*
* @param ExportJob $job
*
* @return mixed
*/
public function setJob(ExportJob $job);
}

View File

@ -1,123 +0,0 @@
<?php
/**
* UploadCollector.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Collector;
use Crypt;
use Exception;
use Illuminate\Contracts\Encryption\DecryptException;
use Log;
use Storage;
/**
* Class UploadCollector.
*
* @codeCoverageIgnore
* @deprecated
*/
class UploadCollector extends BasicCollector implements CollectorInterface
{
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $exportDisk;
/** @var \Illuminate\Contracts\Filesystem\Filesystem */
private $uploadDisk;
/**
* AttachmentCollector constructor.
*/
public function __construct()
{
parent::__construct();
$this->uploadDisk = Storage::disk('upload');
$this->exportDisk = Storage::disk('export');
}
/**
* Is called from the outside to actually start the export.
*
* @return bool
*/
public function run(): bool
{
Log::debug('Going to collect attachments', ['key' => $this->job->key]);
$this->collectModernUploads();
return true;
}
/**
* This method collects all the uploads that are uploaded using the new importer. So after the summer of 2016.
*
* @return bool
*/
private function collectModernUploads(): bool
{
$set = $this->job->user->importJobs()->whereIn('status', ['import_complete', 'finished'])->get(['import_jobs.*']);
Log::debug(sprintf('Found %d import jobs', $set->count()));
$keys = [];
if ($set->count() > 0) {
$keys = $set->pluck('key')->toArray();
}
foreach ($keys as $key) {
$this->processModernUpload($key);
}
return true;
}
/** @noinspection MultipleReturnStatementsInspection */
/**
* Process new file uploads.
*
* @param string $key
*
* @return bool
*/
private function processModernUpload(string $key): bool
{
// find job associated with import file:
$job = $this->job->user->importJobs()->where('key', $key)->first();
if (null === $job) {
return false;
}
// find the file for this import:
$content = '';
try {
$content = Crypt::decrypt($this->uploadDisk->get(sprintf('%s.upload', $key)));
} catch (Exception | DecryptException $e) {
Log::error(sprintf('Could not decrypt old import file "%s". Skipped because: %s', $key, $e->getMessage()));
}
if ('' !== $content) {
// add to export disk.
$date = $job->created_at->format('Y-m-d');
$file = sprintf('%s-Old %s import dated %s.%s', $this->job->key, strtoupper($job->file_type), $date, $job->file_type);
$this->exportDisk->put($file, $content);
$this->getEntries()->push($file);
}
return true;
}
}

View File

@ -1,189 +0,0 @@
<?php
/**
* Entry.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Entry;
use FireflyIII\Models\Transaction;
/**
* To extend the exported object, in case of new features in Firefly III for example,
* do the following:.
*
* - Add the field(s) to this class. If you add more than one related field, add a new object.
* - Make sure the "fromJournal"-routine fills these fields.
* - Add them to the static function that returns its type (key=value. Remember that the only
* valid types can be found in config/csv.php (under "roles").
*
* These new entries should be should be strings and numbers as much as possible.
*
*
*
* Class Entry
*
* @SuppressWarnings(PHPMD.LongVariable)
* @SuppressWarnings(PHPMD.TooManyFields)
*
* @codeCoverageIgnore
* @deprecated
*/
final class Entry
{
/** @var string The amount. */
public $amount;
/** @var string Asset account BIC */
public $asset_account_bic;
/** @var string Asset account IBAN */
public $asset_account_iban;
/** @var string Asset account ID */
public $asset_account_id;
/** @var string Asset account name */
public $asset_account_name;
/** @var string Asset account number */
public $asset_account_number;
/** @var string Asset account currency code */
public $asset_currency_code;
/** @var string Bill ID */
public $bill_id;
/** @var string Bill name */
public $bill_name;
/** @var string Budget ID */
public $budget_id;
/** @var string Budget name */
public $budget_name;
/** @var string Category ID */
public $category_id;
/** @var string Category name */
public $category_name;
/** @var string The currency code. */
public $currency_code;
/** @var string The date. */
public $date;
/** @var string The description */
public $description;
/** @var string Foreign amount */
public $foreign_amount = '0';
/** @var string The foreign currency code */
public $foreign_currency_code = '';
/** @var int ID of the journal */
public $journal_id;
/** @var string Notes */
public $notes;
/** @var string Opposing account BIC */
public $opposing_account_bic;
/** @var string Opposing account IBAN */
public $opposing_account_iban;
/** @var string Opposing account ID */
public $opposing_account_id;
/** @var string Opposing account name */
public $opposing_account_name;
/** @var string Opposing account number */
public $opposing_account_number;
/** @var string Opposing account code */
public $opposing_currency_code;
/** @var string Tags */
public $tags;
/** @var int ID of the transaction */
public $transaction_id = 0;
/** @var string Transaction type */
public $transaction_type;
/**
* Entry constructor.
*/
private function __construct()
{
}
/**
* Converts a given transaction (as collected by the collector) into an export entry.
*
* @SuppressWarnings(PHPMD.CyclomaticComplexity) // complex but little choice.
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) // cannot be helped
*
* @param Transaction $transaction
*
* @return Entry
*/
public static function fromTransaction(Transaction $transaction): Entry
{
$entry = new self();
$entry->journal_id = $transaction->journal_id;
$entry->transaction_id = $transaction->id;
$entry->date = $transaction->date->format('Ymd');
$entry->description = $transaction->description;
if ('' !== (string)$transaction->transaction_description) {
$entry->description = $transaction->transaction_description . '(' . $transaction->description . ')';
}
$entry->currency_code = $transaction->transactionCurrency->code;
$entry->amount = (string)round($transaction->transaction_amount, $transaction->transactionCurrency->decimal_places);
$entry->foreign_currency_code = null === $transaction->foreign_currency_id ? null : $transaction->foreignCurrency->code;
$entry->foreign_amount = null === $transaction->foreign_currency_id
? null
: (string)round(
$transaction->transaction_foreign_amount,
$transaction->foreignCurrency->decimal_places
);
$entry->transaction_type = $transaction->transaction_type_type;
$entry->asset_account_id = (string)$transaction->account_id;
$entry->asset_account_name = $transaction->account_name;
$entry->asset_account_iban = $transaction->account_iban;
$entry->asset_account_number = $transaction->account_number;
$entry->asset_account_bic = $transaction->account_bic;
$entry->asset_currency_code = $transaction->account_currency_code;
$entry->opposing_account_id = (string)$transaction->opposing_account_id;
$entry->opposing_account_name = $transaction->opposing_account_name;
$entry->opposing_account_iban = $transaction->opposing_account_iban;
$entry->opposing_account_number = $transaction->opposing_account_number;
$entry->opposing_account_bic = $transaction->opposing_account_bic;
$entry->opposing_currency_code = $transaction->opposing_currency_code;
// budget
$entry->budget_id = (string)$transaction->transaction_budget_id;
$entry->budget_name = $transaction->transaction_budget_name;
if (null === $transaction->transaction_budget_id) {
$entry->budget_id = $transaction->transaction_journal_budget_id;
$entry->budget_name = $transaction->transaction_journal_budget_name;
}
// category
$entry->category_id = (string)$transaction->transaction_category_id;
$entry->category_name = $transaction->transaction_category_name;
if (null === $transaction->transaction_category_id) {
$entry->category_id = $transaction->transaction_journal_category_id;
$entry->category_name = $transaction->transaction_journal_category_name;
}
// budget
$entry->bill_id = (string)$transaction->bill_id;
$entry->bill_name = $transaction->bill_name;
$entry->tags = $transaction->tags;
$entry->notes = $transaction->notes;
return $entry;
}
}

View File

@ -1,375 +0,0 @@
<?php
/**
* ExpandedProcessor.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
/** @noinspection PhpDynamicAsStaticMethodCallInspection */
declare(strict_types=1);
namespace FireflyIII\Export;
use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Export\Collector\AttachmentCollector;
use FireflyIII\Export\Collector\UploadCollector;
use FireflyIII\Export\Entry\Entry;
use FireflyIII\Export\Exporter\ExporterInterface;
use FireflyIII\Helpers\Filter\InternalTransferFilter;
use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\Note;
use FireflyIII\Models\Transaction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Log;
use ZipArchive;
/**
* Class ExpandedProcessor.
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects) // its doing a lot.
*
* @codeCoverageIgnore
* @deprecated
*/
class ExpandedProcessor implements ProcessorInterface
{
/** @var Collection All accounts */
public $accounts;
/** @var string The export format */
public $exportFormat;
/** @var bool Should include attachments */
public $includeAttachments;
/** @var bool Should include old uploads */
public $includeOldUploads;
/** @var ExportJob The export job itself */
public $job;
/** @var array The settings */
public $settings;
/** @var Collection The entries to export. */
private $exportEntries;
/** @var Collection The files to export */
private $files;
/** @var Collection The journals. */
private $journals;
/**
* Processor constructor.
*/
public function __construct()
{
$this->journals = new Collection;
$this->exportEntries = new Collection;
$this->files = new Collection;
}
/**
* Collect all attachments
*
* @return bool
*/
public function collectAttachments(): bool
{
/** @var AttachmentCollector $attachmentCollector */
$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());
return true;
}
/**
* Collects all transaction journals.
*
* @return bool
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function collectJournals(): bool
{
return true;
// use journal collector thing.
/** @var TODO replace me. $collector */
//$collector = app();
$collector->setUser($this->job->user);
$collector->setAccounts($this->accounts)->setRange($this->settings['startDate'], $this->settings['endDate'])
->withOpposingAccount()->withBudgetInformation()->withCategoryInformation()
->removeFilter(InternalTransferFilter::class);
$transactions = $collector->getTransactions();
// get some more meta data for each entry:
$ids = $transactions->pluck('journal_id')->toArray();
$assetIds = $transactions->pluck('account_id')->toArray();
$opposingIds = $transactions->pluck('opposing_account_id')->toArray();
$notes = $this->getNotes($ids);
$tags = $this->getTags($ids);
/** @var array $ibans */
$ibans = array_merge($this->getIbans($assetIds), $this->getIbans($opposingIds));
$currencies = $this->getAccountCurrencies($ibans);
$transactions->each(
function (Transaction $transaction) use ($notes, $tags, $ibans, $currencies) {
$journalId = (int)$transaction->journal_id;
$accountId = (int)$transaction->account_id;
$opposingId = (int)$transaction->opposing_account_id;
$currencyId = (int)($ibans[$accountId]['currency_id'] ?? 0.0);
$opposingCurrencyId = (int)($ibans[$opposingId]['currency_id'] ?? 0.0);
$transaction->notes = $notes[$journalId] ?? '';
$transaction->tags = implode(',', $tags[$journalId] ?? []);
$transaction->account_number = $ibans[$accountId]['accountNumber'] ?? '';
$transaction->account_bic = $ibans[$accountId]['BIC'] ?? '';
$transaction->account_currency_code = $currencies[$currencyId] ?? '';
$transaction->opposing_account_number = $ibans[$opposingId]['accountNumber'] ?? '';
$transaction->opposing_account_bic = $ibans[$opposingId]['BIC'] ?? '';
$transaction->opposing_currency_code = $currencies[$opposingCurrencyId] ?? '';
}
);
$this->journals = $transactions;
return true;
}
/**
* Returns, if present, for the given journal ID's the notes.
*
* @param array $array
*
* @return array
*/
private function getNotes(array $array): array
{
$array = array_unique($array);
$notes = Note::where('notes.noteable_type', TransactionJournal::class)
->whereIn('notes.noteable_id', $array)
->get(['notes.*']);
$return = [];
/** @var Note $note */
foreach ($notes as $note) {
if ('' !== trim((string)$note->text)) {
$id = (int)$note->noteable_id;
$return[$id] = $note->text;
}
}
return $return;
}
/**
* Returns a comma joined list of all the users tags linked to these journals.
*
* @param array $array
*
* @return array
* @throws \Illuminate\Contracts\Encryption\DecryptException
*/
private function getTags(array $array): array
{
$set = DB::table('tag_transaction_journal')
->whereIn('tag_transaction_journal.transaction_journal_id', $array)
->leftJoin('tags', 'tag_transaction_journal.tag_id', '=', 'tags.id')
->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'tag_transaction_journal.transaction_journal_id')
->where('transaction_journals.user_id', $this->job->user_id)
->get(['tag_transaction_journal.transaction_journal_id', 'tags.tag']);
$result = [];
foreach ($set as $entry) {
$id = (int)$entry->transaction_journal_id;
$result[$id] = $result[$id] ?? [];
$result[$id][] = $entry->tag;
}
return $result;
}
/**
* Get all IBAN / SWIFT / account numbers.
*
* @param array $array
*
* @return array
*/
private function getIbans(array $array): array
{
$array = array_unique($array);
$return = [];
$set = AccountMeta::whereIn('account_id', $array)
->leftJoin('accounts', 'accounts.id', 'account_meta.account_id')
->where('accounts.user_id', $this->job->user_id)
->whereIn('account_meta.name', ['accountNumber', 'BIC', 'currency_id'])
->get(['account_meta.id', 'account_meta.account_id', 'account_meta.name', 'account_meta.data']);
/** @var AccountMeta $meta */
foreach ($set as $meta) {
$id = (int)$meta->account_id;
$return[$id][$meta->name] = $meta->data;
}
return $return;
}
/**
* Get currencies.
*
* @param array $array
*
* @return array
*/
private function getAccountCurrencies(array $array): array
{
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class);
$return = [];
$ids = [];
$repository->setUser($this->job->user);
foreach ($array as $value) {
$ids[] = (int)($value['currency_id'] ?? 0.0);
}
$ids = array_unique($ids);
$result = $repository->getByIds($ids);
foreach ($result as $currency) {
$return[$currency->id] = $currency->code;
}
return $return;
}
/**
* Get old oploads.
*
* @return bool
*/
public function collectOldUploads(): bool
{
/** @var UploadCollector $uploadCollector */
$uploadCollector = app(UploadCollector::class);
$uploadCollector->setJob($this->job);
$uploadCollector->run();
$this->files = $this->files->merge($uploadCollector->getEntries());
return true;
}
/**
* Convert journals to export objects.
*
* @return bool
*/
public function convertJournals(): bool
{
$this->journals->each(
function (Transaction $transaction) {
$this->exportEntries->push(Entry::fromTransaction($transaction));
}
);
Log::debug(sprintf('Count %d entries in exportEntries (convertJournals)', $this->exportEntries->count()));
return true;
}
/**
* Create a ZIP file locally (!) in storage_path('export').
*
* @return bool
*
* @throws FireflyException
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
*/
public function createZipFile(): bool
{
$zip = new ZipArchive;
$file = $this->job->key . '.zip';
$localPath = storage_path('export') . '/' . $file;
if (true !== $zip->open($localPath, ZipArchive::CREATE)) {
throw new FireflyException('Cannot store zip file.');
}
// for each file in the collection, add it to the zip file.
$disk = Storage::disk('export');
foreach ($this->getFiles() as $entry) {
// is part of this job?
$zipFileName = str_replace($this->job->key . '-', '', $entry);
$zip->addFromString($zipFileName, $disk->get($entry));
}
$zip->close();
// delete the files:
$this->deleteFiles();
return true;
}
/**
* Get files.
*
* @return Collection
*/
public function getFiles(): Collection
{
return $this->files;
}
/**
* Delete files.
*/
private function deleteFiles(): void
{
$disk = Storage::disk('export');
foreach ($this->getFiles() as $file) {
$disk->delete($file);
}
}
/**
* Export the journals.
*
* @return bool
*/
public function exportJournals(): bool
{
$exporterClass = config('firefly.export_formats.' . $this->exportFormat);
/** @var ExporterInterface $exporter */
$exporter = app($exporterClass);
$exporter->setJob($this->job);
$exporter->setEntries($this->exportEntries);
$exporter->run();
$this->files->push($exporter->getFileName());
return true;
}
/**
* Save export job settings to class.
*
* @param array $settings
*/
public function setSettings(array $settings): void
{
// 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'];
}
}

View File

@ -1,80 +0,0 @@
<?php
/**
* BasicExporter.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Exporter;
use FireflyIII\Models\ExportJob;
use Illuminate\Support\Collection;
/**
* Class BasicExporter.
*
* @codeCoverageIgnore
* @deprecated
*/
class BasicExporter
{
/** @var ExportJob The export job */
protected $job;
/** @var Collection The entries */
private $entries;
/**
* BasicExporter constructor.
*/
public function __construct()
{
$this->entries = new Collection;
}
/**
* Get all entries.
*
* @return Collection
*/
public function getEntries(): Collection
{
return $this->entries;
}
/**
* Set all entries.
*
* @param Collection $entries
*/
public function setEntries(Collection $entries): void
{
$this->entries = $entries;
}
/**
* Set the job.
*
* @param ExportJob $job
*/
public function setJob(ExportJob $job): void
{
$this->job = $job;
}
}

View File

@ -1,90 +0,0 @@
<?php
/**
* CsvExporter.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Exporter;
use FireflyIII\Export\Entry\Entry;
use Illuminate\Support\Facades\Storage;
use League\Csv\Writer;
/**
* Class CsvExporter.
*
* @codeCoverageIgnore
* @deprecated
*/
class CsvExporter extends BasicExporter implements ExporterInterface
{
/** @var string Filename */
private $fileName;
/**
* Get file name.
*
* @return string
*/
public function getFileName(): string
{
return $this->fileName;
}
/**
* Run collector.
*
* @return bool
*
*/
public function run(): bool
{
// choose file name:
$this->fileName = $this->job->key . '-records.csv';
//we create the CSV into memory
$writer = Writer::createFromString('');
$rows = [];
// get field names for header row:
$first = $this->getEntries()->first();
$headers = [];
if (null !== $first) {
$headers = array_keys(get_object_vars($first));
}
$rows[] = $headers;
/** @var Entry $entry */
foreach ($this->getEntries() as $entry) {
$line = [];
foreach ($headers as $header) {
$line[] = $entry->$header;
}
$rows[] = $line;
}
$writer->insertAll($rows);
$disk = Storage::disk('export');
$disk->put($this->fileName, $writer->getContent());
return true;
}
}

View File

@ -1,72 +0,0 @@
<?php
/**
* ExporterInterface.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export\Exporter;
use FireflyIII\Models\ExportJob;
use Illuminate\Support\Collection;
/**
* Interface ExporterInterface.
*
* @codeCoverageIgnore
* @deprecated
*/
interface ExporterInterface
{
/**
* Get entries.
*
* @return Collection
*/
public function getEntries(): Collection;
/**
* Get file name.
*
* @return string
*/
public function getFileName(): string;
/**
* Run exporter.
*
* @return bool
*/
public function run(): bool;
/**
* Set entries.
*
* @param Collection $entries
*/
public function setEntries(Collection $entries);
/**
* Set job.
*
* @param ExportJob $job
*/
public function setJob(ExportJob $job);
}

View File

@ -1,97 +0,0 @@
<?php
/**
* ProcessorInterface.php
* Copyright (c) 2018 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Export;
use Illuminate\Support\Collection;
/**
* Interface ProcessorInterface.
*
* @codeCoverageIgnore
* @deprecated
*/
interface ProcessorInterface
{
/**
* Processor constructor.
*/
public function __construct();
/**
* Collect all attachments.
*
* @return bool
*/
public function collectAttachments(): bool;
/**
* Collect all journals.
*
* @return bool
*/
public function collectJournals(): bool;
/**
* Collect old uploads.
*
* @return bool
*/
public function collectOldUploads(): bool;
/**
* Convert all journals.
*
* @return bool
*/
public function convertJournals(): bool;
/**
* Create a zip file.
*
* @return bool
*/
public function createZipFile(): bool;
/**
* Export journals.
*
* @return bool
*/
public function exportJournals(): bool;
/**
* Get all files.
*
* @return Collection
*/
public function getFiles(): Collection;
/**
* Set the settings.
*
* @param array $settings
*/
public function setSettings(array $settings);
}

View File

@ -204,7 +204,7 @@ class DebugController extends Controller
'rules.select', 'search.search', 'test-flash', 'transactions.link.delete', 'transactions.link.switch',
'two-factor.lost', 'reports.options', 'debug', 'import.create-job', 'import.download', 'import.start', 'import.status.json',
'preferences.delete-code', 'rules.test-triggers', 'piggy-banks.remove-money', 'piggy-banks.add-money',
'accounts.reconcile.transactions', 'accounts.reconcile.overview', 'export.download',
'accounts.reconcile.transactions', 'accounts.reconcile.overview',
'transactions.clone', 'two-factor.index', 'api.v1', 'installer.', 'attachments.view', 'import.create',
'import.job.download', 'import.job.start', 'import.job.status.json', 'import.job.store', 'recurring.events',
'recurring.suggest',

View File

@ -1,198 +0,0 @@
<?php
/**
* ExportController.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Controllers;
use Carbon\Carbon;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Export\ProcessorInterface;
use FireflyIII\Http\Middleware\IsDemoUser;
use FireflyIII\Http\Requests\ExportFormRequest;
use FireflyIII\Models\ExportJob;
use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use FireflyIII\Repositories\ExportJob\ExportJobRepositoryInterface;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response as LaravelResponse;
/**
* Class ExportController.
*/
class ExportController extends Controller
{
/**
* ExportController constructor.
*/
public function __construct()
{
parent::__construct();
$this->middleware(
function ($request, $next) {
app('view')->share('mainTitleIcon', 'fa-file-archive-o');
app('view')->share('title', (string)trans('firefly.export_and_backup_data'));
return $next($request);
}
);
$this->middleware(IsDemoUser::class)->except(['index']);
}
/**
* Download exported file.
*
* @param ExportJobRepositoryInterface $repository
* @param ExportJob $job
*
* @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
*
* @throws FireflyException
*/
public function download(ExportJobRepositoryInterface $repository, ExportJob $job)
{
$file = $job->key . '.zip';
$date = date('Y-m-d \a\t H-i-s');
$name = 'Export job on ' . $date . '.zip';
$quoted = sprintf('"%s"', addcslashes($name, '"\\'));
if (!$repository->exists($job)) {
throw new FireflyException('Against all expectations, zip file "' . $file . '" does not exist.');
}
$content = $repository->getContent($job);
$repository->changeStatus($job, 'export_downloaded');
/** @var LaravelResponse $response */
$response = response($content);
$response
->header('Content-Description', 'File Transfer')
->header('Content-Type', 'application/octet-stream')
->header('Content-Disposition', 'attachment; filename=' . $quoted)
->header('Content-Transfer-Encoding', 'binary')
->header('Connection', 'Keep-Alive')
->header('Expires', '0')
->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0')
->header('Pragma', 'public')
->header('Content-Length', strlen($content));
return $response;
}
/**
* Get current export status.
*
* @param ExportJob $job
*
* @return \Illuminate\Http\JsonResponse
*/
public function getStatus(ExportJob $job): JsonResponse
{
return response()->json(['status' => (string)trans('firefly.' . $job->status)]);
}
/**
* Index of export routine.
*
* @param ExportJobRepositoryInterface $jobs
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(ExportJobRepositoryInterface $jobs)
{
// create new export job.
$job = $jobs->create();
// does the user have shared accounts?
$formats = array_keys(config('firefly.export_formats'));
$defaultFormat = app('preferences')->get('export_format', config('firefly.default_export_format'))->data;
$first = session('first')->format('Y-m-d');
$today = Carbon::now()->format('Y-m-d');
return view('export.index', compact('job', 'formats', 'defaultFormat', 'first', 'today'));
}
/**
* Submit the job.
*
* @param ExportFormRequest $request
* @param AccountRepositoryInterface $repository
* @param ExportJobRepositoryInterface $jobs
*
* @return JsonResponse
*
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
public function postIndex(ExportFormRequest $request, AccountRepositoryInterface $repository, ExportJobRepositoryInterface $jobs): JsonResponse
{
$job = $jobs->findByKey($request->get('job'));
$accounts = $request->get('accounts') ?? [];
$settings = [
'accounts' => $repository->getAccountsById($accounts),
'startDate' => new Carbon($request->get('export_start_range')),
'endDate' => new Carbon($request->get('export_end_range')),
'exportFormat' => $request->get('exportFormat'),
'includeAttachments' => $request->boolean('include_attachments'),
'includeOldUploads' => $request->boolean('include_old_uploads'),
'job' => $job,
];
$jobs->changeStatus($job, 'export_status_make_exporter');
/** @var ProcessorInterface $processor */
$processor = app(ProcessorInterface::class);
$processor->setSettings($settings);
// Collect journals:
$jobs->changeStatus($job, 'export_status_collecting_journals');
$processor->collectJournals();
$jobs->changeStatus($job, 'export_status_collected_journals');
// Transform to exportable entries:
$jobs->changeStatus($job, 'export_status_converting_to_export_format');
$processor->convertJournals();
$jobs->changeStatus($job, 'export_status_converted_to_export_format');
// Transform to (temporary) file:
$jobs->changeStatus($job, 'export_status_creating_journal_file');
$processor->exportJournals();
$jobs->changeStatus($job, 'export_status_created_journal_file');
// Collect attachments, if applicable.
if ($settings['includeAttachments']) {
$jobs->changeStatus($job, 'export_status_collecting_attachments');
$processor->collectAttachments();
$jobs->changeStatus($job, 'export_status_collected_attachments');
}
// Collect old uploads
if ($settings['includeOldUploads']) {
$jobs->changeStatus($job, 'export_status_collecting_old_uploads');
$processor->collectOldUploads();
$jobs->changeStatus($job, 'export_status_collected_old_uploads');
}
// Create ZIP file:
$jobs->changeStatus($job, 'export_status_creating_zip_file');
$processor->createZipFile();
$jobs->changeStatus($job, 'export_status_created_zip_file');
$jobs->changeStatus($job, 'export_status_finished');
return response()->json('ok');
}
}

View File

@ -1,69 +0,0 @@
<?php
/**
* ExportFormRequest.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
/**
* Class ExportFormRequest.
*/
class ExportFormRequest extends Request
{
/**
* Verify the request.
*
* @return bool
*/
public function authorize(): bool
{
// Only allow logged in users
return auth()->check();
}
/**
* Rules for this request.
*
* @return array
*/
public function rules(): array
{
/** @var Carbon $sessionFirst */
$sessionFirst = clone session('first');
$first = $sessionFirst->subDay()->format('Y-m-d');
$today = Carbon::now()->addDay()->format('Y-m-d');
$formats = implode(',', array_keys(config('firefly.export_formats')));
// fixed
return [
'export_start_range' => 'required|date|after:' . $first,
'export_end_range' => 'required|date|before:' . $today,
'accounts' => 'required',
'job' => 'required|belongsToUser:export_jobs,key',
'accounts.*' => 'required|exists:accounts,id|belongsToUser:accounts',
'include_attachments' => 'in:0,1',
'include_config' => 'in:0,1',
'exportFormat' => 'in:' . $formats,
];
}
}

View File

@ -25,7 +25,7 @@ namespace FireflyIII\Http\Requests;
use Carbon\Carbon;
/**
* Class ExportFormRequest.
* Class SelectTransactionsRequest.
*
* @codeCoverageIgnore
*/

View File

@ -1,115 +0,0 @@
<?php
/**
* ExportJob.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Models;
use FireflyIII\User;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Class ExportJob.
*
* @property User $user
* @property string $key
* @property int $user_id
* @property string status
* @property int id
* @property int $id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string $status
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob query()
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob whereKey($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob whereStatus($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ExportJob whereUserId($value)
* @mixin \Eloquent
*/
class ExportJob extends Model
{
/**
* The attributes that should be casted to native types.
*
* @var array
*/
protected $casts
= [
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* Route binder. Converts the key in the URL to the specified object (or throw 404).
*
* @param string $value
*
* @return ExportJob
*
* @throws NotFoundHttpException
*/
public static function routeBinder(string $value): ExportJob
{
if (auth()->check()) {
$key = trim($value);
/** @var User $user */
$user = auth()->user();
/** @var ExportJob $exportJob */
$exportJob = $user->exportJobs()->where('key', $key)->first();
if (null !== $exportJob) {
return $exportJob;
}
}
throw new NotFoundHttpException;
}
/**
* Change the status of this export job.
*
* @param $status
*
* @deprecated
* @codeCoverageIgnore
*/
public function change($status): void
{
$this->status = $status;
$this->save();
}
/**
* Returns the user this objects belongs to.
*
*
* @return BelongsTo
* @codeCoverageIgnore
*/
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
}

View File

@ -1,91 +0,0 @@
<?php
/**
* ExportJobServiceProvider.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Providers;
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;
/**
* @codeCoverageIgnore
* Class ExportJobServiceProvider.
*/
class ExportJobServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*/
public function boot(): void
{
}
/**
* Register the application services.
*/
public function register(): void
{
$this->exportJob();
$this->importJob();
}
/**
* Register export job.
*/
private function exportJob(): void
{
$this->app->bind(
ExportJobRepositoryInterface::class,
function (Application $app) {
/** @var ExportJobRepository $repository */
$repository = app(ExportJobRepository::class);
if ($app->auth->check()) {
$repository->setUser(auth()->user());
}
return $repository;
}
);
}
/**
* Register import job.
*/
private function importJob(): void
{
$this->app->bind(
ImportJobRepositoryInterface::class,
function (Application $app) {
/** @var ImportJobRepository $repository */
$repository = app(ImportJobRepository::class);
if ($app->auth->check()) {
$repository->setUser(auth()->user());
}
return $repository;
}
);
}
}

View File

@ -23,8 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Providers;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Export\ExpandedProcessor;
use FireflyIII\Export\ProcessorInterface;
use FireflyIII\Generator\Chart\Basic\ChartJsGenerator;
use FireflyIII\Generator\Chart\Basic\GeneratorInterface;
use FireflyIII\Helpers\Attachments\AttachmentHelper;
@ -167,8 +165,6 @@ class FireflyServiceProvider extends ServiceProvider
);
// other generators
// export:
$this->app->bind(ProcessorInterface::class, ExpandedProcessor::class);
$this->app->bind(UserRepositoryInterface::class, UserRepository::class);
$this->app->bind(TransactionTypeRepositoryInterface::class, TransactionTypeRepository::class);
$this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class);

View File

@ -1,147 +0,0 @@
<?php
/**
* ExportJobRepository.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Repositories\ExportJob;
use FireflyIII\Models\ExportJob;
use FireflyIII\User;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Log;
/**
* Class ExportJobRepository.
*/
class ExportJobRepository implements ExportJobRepositoryInterface
{
/** @var User */
private $user;
/**
* Constructor.
*/
public function __construct()
{
if ('testing' === config('app.env')) {
Log::warning(sprintf('%s should not be instantiated in the TEST environment!', \get_class($this)));
}
}
/**
* @param ExportJob $job
* @param string $status
*
* @return bool
*/
public function changeStatus(ExportJob $job, string $status): bool
{
Log::debug(sprintf('Change status of job #%d to "%s"', $job->id, $status));
$job->status = $status;
$job->save();
return true;
}
/**
* @return ExportJob|null
*/
public function create(): ?ExportJob
{
$count = 0;
while ($count < 30) {
$key = Str::random(12);
$existing = $this->findByKey($key);
if (null === $existing) {
$exportJob = new ExportJob;
$exportJob->user()->associate($this->user);
$exportJob->key = Str::random(12);
$exportJob->status = 'export_status_never_started';
$exportJob->save();
// breaks the loop:
return $exportJob;
}
++$count;
}
return null;
}
/**
* @param ExportJob $job
*
* @return bool
*/
public function exists(ExportJob $job): bool
{
$disk = Storage::disk('export');
$file = $job->key . '.zip';
return $disk->exists($file);
}
/**
* @param string $key
*
* @return ExportJob|null
*/
public function findByKey(string $key): ?ExportJob
{
/** @var ExportJob $result */
$result = $this->user->exportJobs()->where('key', $key)->first(['export_jobs.*']);
if (null === $result) {
return null;
}
return $result;
}
/**
* @param ExportJob $job
*
* @return string
*/
public function getContent(ExportJob $job): string
{
$disk = Storage::disk('export');
$file = $job->key . '.zip';
try {
$content = $disk->get($file);
} catch (FileNotFoundException $e) {
Log::warning(sprintf('File not found: %s', $e->getMessage()));
$content = '';
}
return $content;
}
/**
* @param User $user
*/
public function setUser(User $user): void
{
$this->user = $user;
}
}

View File

@ -1,71 +0,0 @@
<?php
/**
* ExportJobRepositoryInterface.php
* Copyright (c) 2017 thegrumpydictator@gmail.com
*
* This file is part of Firefly III.
*
* Firefly III is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Firefly III is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/
declare(strict_types=1);
namespace FireflyIII\Repositories\ExportJob;
use FireflyIII\Models\ExportJob;
use FireflyIII\User;
/**
* Interface ExportJobRepositoryInterface.
*/
interface ExportJobRepositoryInterface
{
/**
* @param ExportJob $job
* @param string $status
*
* @return bool
*/
public function changeStatus(ExportJob $job, string $status): bool;
/**
* @return ExportJob|null
*/
public function create(): ?ExportJob;
/**
* @param ExportJob $job
*
* @return bool
*/
public function exists(ExportJob $job): bool;
/**
* @param string $key
*
* @return ExportJob|null
*/
public function findByKey(string $key): ?ExportJob;
/**
* @param ExportJob $job
*
* @return string
*/
public function getContent(ExportJob $job): string;
/**
* @param User $user
*/
public function setUser(User $user);
}

View File

@ -32,7 +32,6 @@ use FireflyIII\Models\Bill;
use FireflyIII\Models\Budget;
use FireflyIII\Models\Category;
use FireflyIII\Models\CurrencyExchangeRate;
use FireflyIII\Models\ExportJob;
use FireflyIII\Models\ImportJob;
use FireflyIII\Models\PiggyBank;
use FireflyIII\Models\Preference;
@ -78,7 +77,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Category[] $categories
* @property-read \Illuminate\Database\Eloquent\Collection|\Laravel\Passport\Client[] $clients
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\CurrencyExchangeRate[] $currencyExchangeRates
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ExportJob[] $exportJobs
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ImportJob[] $importJobs
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection|\Illuminate\Notifications\DatabaseNotification[] $notifications
* @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks
@ -234,17 +232,6 @@ class User extends Authenticatable
return $this->hasMany(CurrencyExchangeRate::class);
}
/**
* @codeCoverageIgnore
* Link to export jobs
*
* @return HasMany
*/
public function exportJobs(): HasMany
{
return $this->hasMany(ExportJob::class);
}
/**
* @codeCoverageIgnore
* Generates access token.

View File

@ -1,109 +0,0 @@
{% extends "./layout/default" %}
{% block breadcrumbs %}
{{ Breadcrumbs.render(Route.getCurrentRoute.getName) }}
{% endblock %}
{% block content %}
<form method="post" action="{{ route('export.submit') }}" accept-charset="UTF-8" class="form-horizontal" id="export">
<input name="_token" type="hidden" value="{{ csrf_token() }}">
<input name="job" type="hidden" value="{{ job.key }}">
<div class="row">
<div class="col-lg-12 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'export_and_backup_data'|_ }}</h3>
</div>
<div class="box-body">
<div id="export-loading" style="display:none;">
<p class="text-center">
{{ 'export_data_please_wait'|_ }}
</p>
<p class="text-center">
<img src="images/loading-wide.gif" alt="">
</p>
<p class="text-center text-info" id="status-message">
(Please wait for a status message to appear)
</p>
</div>
<div id="export-download" style="display:none;">
<p class="text-center text-info" id="download-holder">
<a id="download-link" class="btn btn-lg btn-success" href="{{ route('export.download', job.key) }}"><i
class="fa fa-fw fa-download"></i> Download</a>
</p>
</div>
<div id="export-error" style="display:none;">
<p class="text-center text-danger">
</p>
</div>
<div id="form-body">
<p>
{{ 'export_data_intro'|_ }}
</p>
<div class="row">
<div class="col-lg-6 col-md-8 col-sm-12 col-xs-12">
{{ ExpandedForm.date('export_start_range', first) }}
{{ ExpandedForm.date('export_end_range', today) }}
{# EXPORT FORMATS #}
<div class="form-group">
<label for="exportFormat" class="col-sm-4 control-label">{{ 'export_format'|_ }}</label>
<div class="col-sm-8">
{% if errors.has('exportFormat') %}
<div class="alert alert-danger" role="alert">
{{ errors.first('exportFormat') }}
</div>
{% endif %}
{% for format in formats %}
<div class="radio">
<label>
<input type="radio" name="exportFormat" id="exportFormat_{{ format }}" value="{{ format }}"
{% if format == defaultFormat %}checked{% endif %}>
{{ ('export_format_'~format)|_ }}
</label>
</div>
{% endfor %}
</div>
</div>
{# ACCOUNTS #}
{{ ExpandedForm.assetAccountCheckList('accounts', {' class': 'account-checkbox','select_all': true}) }}
{{ ExpandedForm.checkbox('include_attachments','1', true) }}
{{ ExpandedForm.checkbox('include_old_uploads','1', false, {helpText: 'include_old_uploads_help'|_}) }}
</div>
</div>
</div>
</div>
<div class="box-footer">
<button type="submit" class="btn pull-right btn-success" id="do-export-button">
{{ 'do_export'|_ }}
</button>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
{% block scripts %}
<script type="text/javascript">
var jobKey = "{{ job.key|escape }}";
</script>
<script type="text/javascript" src="v1/js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="v1/js/ff/export/index.js?v={{ FF_VERSION }}"></script>
{% endblock %}
{% block styles %}
<link href="v1/css/jquery-ui/jquery-ui.structure.min.css?v={{ FF_VERSION }}" type="text/css" rel="stylesheet" media="all">
<link href="v1/css/jquery-ui/jquery-ui.theme.min.css?v={{ FF_VERSION }}" type="text/css" rel="stylesheet" media="all">
{% endblock %}

View File

@ -58,6 +58,14 @@
<span>{{ 'reports'|_ }}</span>
</a>
</li>
<li class="{{ activeRoutePartial('import') }}">
<a href="{{ route('import.index') }}">
<i class="fa fa-archive fa-fw"></i>
<span>{{ 'import_transactions'|_ }}</span>
</a>
</li>
<li class="{{ activeRoutePartial('transactions') }} treeview" id="transaction-menu">
<a href="#">
<i class="fa fa-repeat fa-fw"></i>
@ -110,26 +118,10 @@
</ul>
</li>
<li class="{{ activeRoutePartial('export') }} {{ activeRoutePartial('import') }} treeview">
<a href="#">
<i class="fa fa-arrows-alt fa-fw"></i>
<span>
{{ 'import_and_export'|_ }}
</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li class="{{ activeRoutePartial('import') }}">
<a href="{{ route('import.index') }}"><i class="fa fa-archive fa-fw"></i> {{ 'import_transactions'|_ }}</a>
</li>
<li class="{{ activeRoutePartial('export') }}">
<a href="{{ route('export.index') }}"><i class="fa fa-file-archive-o fa-fw"></i> {{ 'export_and_backup_data'|_ }}</a>
</li>
</ul>
</li>
<li id="option-menu"
class="{{ activeRoutePartial('admin') }} {{ activeRoutePartial('profile') }} {{ activeRoutePartial('preferences') }} {{ activeRoutePartial('currencies') }} treeview">
<a href="#">

View File

@ -280,20 +280,6 @@ Route::group(
}
);
/**
* Export Controller
*/
Route::group(
['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'export', 'as' => 'export.'], function () {
Route::get('', ['uses' => 'ExportController@index', 'as' => 'index']);
Route::get('status/{exportJob}', ['uses' => 'ExportController@getStatus', 'as' => 'status']);
Route::get('download/{exportJob}', ['uses' => 'ExportController@download', 'as' => 'download']);
Route::post('submit', ['uses' => 'ExportController@postIndex', 'as' => 'submit']);
}
);
/**
* Chart\Account Controller (default report)
*/