diff --git a/app/Helpers/Help/Help.php b/app/Helpers/Help/Help.php index 787d4710fe..1831591db4 100644 --- a/app/Helpers/Help/Help.php +++ b/app/Helpers/Help/Help.php @@ -76,8 +76,8 @@ class Help implements HelpInterface $statusCode = $res->getStatusCode(); $content = trim($res->getBody()->getContents()); } catch (GuzzleException|Exception $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); + Log::info($e->getMessage()); + Log::info($e->getTraceAsString()); } Log::debug(sprintf('Status code is %d', $statusCode)); diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 59b0ccaf30..f1703a1884 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Auth; use FireflyConfig; use FireflyIII\Http\Controllers\Controller; +use FireflyIII\Support\Http\Controllers\RequestInformation; use FireflyIII\User; use Illuminate\Auth\Events\Registered; use Illuminate\Contracts\Validation\Validator as ValidatorContract; @@ -43,7 +44,7 @@ use Illuminate\Support\Facades\Validator; */ class RegisterController extends Controller { - use RegistersUsers; + use RegistersUsers, RequestInformation; /** * Where to redirect users after registration. @@ -135,22 +136,4 @@ class RegisterController extends Controller ] ); } - - /** - * Get a validator for an incoming registration request. - * - * @param array $data - * - * @return ValidatorContract - */ - protected function validator(array $data): ValidatorContract - { - return Validator::make( - $data, - [ - 'email' => 'required|string|email|max:255|unique:users', - 'password' => 'required|string|secure_password|confirmed', - ] - ); - } } diff --git a/app/Http/Controllers/Budget/IndexController.php b/app/Http/Controllers/Budget/IndexController.php index 882fe1d63a..78bd66d719 100644 --- a/app/Http/Controllers/Budget/IndexController.php +++ b/app/Http/Controllers/Budget/IndexController.php @@ -25,13 +25,11 @@ namespace FireflyIII\Http\Controllers\Budget; use Carbon\Carbon; -use Exception; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Support\Http\Controllers\DateCalculation; use Illuminate\Http\Request; use Illuminate\Pagination\LengthAwarePaginator; -use Log; /** * diff --git a/app/Http/Controllers/Category/NoCategoryController.php b/app/Http/Controllers/Category/NoCategoryController.php index 24af122196..19ab68dd4e 100644 --- a/app/Http/Controllers/Category/NoCategoryController.php +++ b/app/Http/Controllers/Category/NoCategoryController.php @@ -105,7 +105,7 @@ class NoCategoryController extends Controller /** * Show all transactions without a category. * - * @param Request $request + * @param Request $request * * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View */ diff --git a/app/Http/Controllers/Category/ShowController.php b/app/Http/Controllers/Category/ShowController.php index fed7bd8f07..bc03dc6f22 100644 --- a/app/Http/Controllers/Category/ShowController.php +++ b/app/Http/Controllers/Category/ShowController.php @@ -151,7 +151,7 @@ class ShowController extends Controller $transactions = $collector->getPaginatedJournals(); $transactions->setPath($path); - return view('categories.show', compact('category', 'transactions', 'periods', 'subTitle', 'subTitleIcon', 'start', 'end')); + return view('categories.show', compact('category', 'transactions', 'periods', 'subTitle', 'subTitleIcon', 'start', 'end')); } /** diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 24bd8c6157..8b6e7e8a9c 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; use FireflyConfig; +use FireflyIII\Support\Http\Controllers\RequestInformation; use FireflyIII\Support\Http\Controllers\UserNavigation; use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Bus\DispatchesJobs; @@ -38,7 +39,7 @@ use Route; */ class Controller extends BaseController { - use AuthorizesRequests, DispatchesJobs, ValidatesRequests, UserNavigation; + use AuthorizesRequests, DispatchesJobs, ValidatesRequests, UserNavigation, RequestInformation; /** @var string Format for date and time. */ protected $dateTimeFormat; @@ -90,62 +91,4 @@ class Controller extends BaseController ); } - - /** - * Get user's language. - * - * @return string - */ - protected function getLanguage(): string // get preference - { - /** @var string $language */ - $language = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data; - - return $language; - } - - /** - * @return string - */ - protected function getPageName(): string // get request info - { - return str_replace('.', '_', Route::currentRouteName()); - } - - /** - * Get the specific name of a page for intro. - * - * @return string - */ - protected function getSpecificPageName(): string // get request info - { - return null === Route::current()->parameter('what') ? '' : '_' . Route::current()->parameter('what'); - } - - /** - * Returns if user has seen demo. - * - * @return bool - */ - protected function hasSeenDemo(): bool // get request info + get preference - { - $page = $this->getPageName(); - $specificPage = $this->getSpecificPageName(); - - // indicator if user has seen the help for this page ( + special page): - $key = 'shown_demo_' . $page . $specificPage; - // is there an intro for this route? - $intro = config('intro.' . $page) ?? []; - $specialIntro = config('intro.' . $page . $specificPage) ?? []; - // some routes have a "what" parameter, which indicates a special page: - - $shownDemo = true; - // both must be array and either must be > 0 - if (\count($intro) > 0 || \count($specialIntro) > 0) { - $shownDemo = app('preferences')->get($key, false)->data; - Log::debug(sprintf('Check if user has already seen intro with key "%s". Result is %d', $key, $shownDemo)); - } - - return $shownDemo; - } } diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php index bb153411b0..ab401b393d 100644 --- a/app/Http/Controllers/DebugController.php +++ b/app/Http/Controllers/DebugController.php @@ -241,6 +241,31 @@ class DebugController extends Controller return redirect(route('home')); } + /** + * All packages that are installed. + * + * @return array + */ + protected function collectPackages(): array // get configuration + { + $packages = []; + $file = \dirname(__DIR__, 3) . '/vendor/composer/installed.json'; + if (file_exists($file)) { + // file exists! + $content = file_get_contents($file); + $json = json_decode($content, true); + foreach ($json as $package) { + $packages[] + = [ + 'name' => $package['name'], + 'version' => $package['version'], + ]; + } + } + + return $packages; + } + /** * Some common combinations. * @@ -266,29 +291,4 @@ class DebugController extends Controller return $result; } - - /** - * All packages that are installed. - * - * @return array - */ - protected function collectPackages(): array // get configuration - { - $packages = []; - $file = \dirname(__DIR__, 3) . '/vendor/composer/installed.json'; - if (file_exists($file)) { - // file exists! - $content = file_get_contents($file); - $json = json_decode($content, true); - foreach ($json as $package) { - $packages[] - = [ - 'name' => $package['name'], - 'version' => $package['version'], - ]; - } - } - - return $packages; - } } diff --git a/app/Http/Controllers/HelpController.php b/app/Http/Controllers/HelpController.php index bfd6742556..7ca1e7909a 100644 --- a/app/Http/Controllers/HelpController.php +++ b/app/Http/Controllers/HelpController.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; use FireflyIII\Helpers\Help\HelpInterface; +use FireflyIII\Support\Http\Controllers\RequestInformation; use Illuminate\Http\JsonResponse; use Log; @@ -31,24 +32,7 @@ use Log; */ class HelpController extends Controller { - /** @var HelpInterface Help interface. */ - private $help; - - /** - * HelpController constructor. - */ - public function __construct() - { - parent::__construct(); - - $this->middleware( - function ($request, $next) { - $this->help = app(HelpInterface::class); - - return $next($request); - } - ); - } + use RequestInformation; /** * Show help for a route. @@ -66,61 +50,4 @@ class HelpController extends Controller return response()->json(['html' => $html]); } - /** - * Gets the help text. - * - * @param string $route - * @param string $language - * - * @return string - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - protected function getHelpText(string $route, string $language): string // get from internet. - { - // get language and default variables. - $content = '

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

'; - - // if no such route, log error and return default text. - if (!$this->help->hasRoute($route)) { - Log::error('No such route: ' . $route); - - return $content; - } - - // help content may be cached: - if ($this->help->inCache($route, $language)) { - $content = $this->help->getFromCache($route, $language); - Log::debug(sprintf('Help text %s was in cache.', $language)); - - return $content; - } - - // get help content from Github: - $content = $this->help->getFromGitHub($route, $language); - - // content will have 0 length when Github failed. Try en_US when it does: - if ('' === $content) { - $language = 'en_US'; - - // also check cache first: - if ($this->help->inCache($route, $language)) { - Log::debug(sprintf('Help text %s was in cache.', $language)); - $content = $this->help->getFromCache($route, $language); - - return $content; - } - - $content = $this->help->getFromGitHub($route, $language); - } - - // help still empty? - if ('' !== $content) { - $this->help->putInCache($route, $language, $content); - - return $content; - } - - return '

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

'; - } } diff --git a/app/Http/Controllers/Json/BoxController.php b/app/Http/Controllers/Json/BoxController.php index b9cb4c092c..6e162f4640 100644 --- a/app/Http/Controllers/Json/BoxController.php +++ b/app/Http/Controllers/Json/BoxController.php @@ -35,6 +35,7 @@ use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Support\CacheProperties; +use FireflyIII\Support\Http\Controllers\RequestInformation; use Illuminate\Http\JsonResponse; /** @@ -42,6 +43,7 @@ use Illuminate\Http\JsonResponse; */ class BoxController extends Controller { + use RequestInformation; /** * How much money user has available. @@ -322,29 +324,5 @@ class BoxController extends Controller return $accountCurrency; } - /** - * Check if date is outside session range. - * - * @param Carbon $date - * - * @return bool - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - protected function notInSessionRange(Carbon $date): bool // Validate a preference - { - /** @var Carbon $start */ - $start = session('start', Carbon::now()->startOfMonth()); - /** @var Carbon $end */ - $end = session('end', Carbon::now()->endOfMonth()); - $result = false; - if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) { - $result = true; - } - // start and end in the past? use $end - if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) { - $result = true; - } - return $result; - } } diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php index 087f227379..bc23632b74 100644 --- a/app/Http/Controllers/PiggyBankController.php +++ b/app/Http/Controllers/PiggyBankController.php @@ -208,7 +208,7 @@ class PiggyBankController extends Controller 'targetamount' => $piggyBank->targetamount, 'targetdate' => $targetDate, 'startdate' => $startDate, - 'notes' => null === $note ? '' : $note->text, + 'notes' => null === $note ? '' : $note->text, ]; session()->flash('preFilled', $preFilled); diff --git a/app/Http/Controllers/Popup/ReportController.php b/app/Http/Controllers/Popup/ReportController.php index 452733f4c9..b1204fb5f1 100644 --- a/app/Http/Controllers/Popup/ReportController.php +++ b/app/Http/Controllers/Popup/ReportController.php @@ -30,6 +30,7 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Support\Binder\AccountList; +use FireflyIII\Support\Http\Controllers\RequestInformation; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Routing\Route; @@ -44,6 +45,7 @@ use Throwable; */ class ReportController extends Controller { + use RequestInformation; /** @var AccountRepositoryInterface The account repository */ private $accountRepository; /** @var BudgetRepositoryInterface The budget repository */ @@ -260,33 +262,5 @@ class ReportController extends Controller return $view; } - /** - * Parses attributes from URI. - * - * @param array $attributes - * - * @return array - */ - protected function parseAttributes(array $attributes): array // parse input + return result - { - $attributes['location'] = $attributes['location'] ?? ''; - $attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', new Route('get', '', [])); - try { - $attributes['startDate'] = Carbon::createFromFormat('Ymd', $attributes['startDate']); - } catch (InvalidArgumentException $e) { - Log::debug(sprintf('Not important error message: %s', $e->getMessage())); - $date = Carbon::now()->startOfMonth(); - $attributes['startDate'] = $date; - } - try { - $attributes['endDate'] = Carbon::createFromFormat('Ymd', $attributes['endDate']); - } catch (InvalidArgumentException $e) { - Log::debug(sprintf('Not important error message: %s', $e->getMessage())); - $date = Carbon::now()->startOfMonth(); - $attributes['endDate'] = $date; - } - - return $attributes; - } } diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 2219b128ce..2d4c9ad0db 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -35,6 +35,7 @@ use FireflyIII\Http\Requests\ProfileFormRequest; use FireflyIII\Http\Requests\TokenFormRequest; use FireflyIII\Models\Preference; use FireflyIII\Repositories\User\UserRepositoryInterface; +use FireflyIII\Support\Http\Controllers\RequestInformation; use FireflyIII\User; use Google2FA; use Hash; @@ -54,6 +55,7 @@ use phpseclib\Crypt\RSA; */ class ProfileController extends Controller { + use RequestInformation; /** * ProfileController constructor. */ @@ -439,30 +441,6 @@ class ProfileController extends Controller return redirect(route('login')); } - /** - * Validate users new password. - * - * @param User $user - * @param string $current - * @param string $new - * - * @return bool - * - * @throws ValidationException - */ - protected function validatePassword(User $user, string $current, string $new): bool //get request info - { - if (!Hash::check($current, $user->password)) { - throw new ValidationException((string)trans('firefly.invalid_current_password')); - } - - if ($current === $new) { - throw new ValidationException((string)trans('firefly.should_change')); - } - - return true; - } - /** * Create new RSA keys. */ @@ -485,18 +463,5 @@ class ProfileController extends Controller file_put_contents($publicKey, array_get($keys, 'publickey')); file_put_contents($privateKey, array_get($keys, 'privatekey')); } - // @codeCoverageIgnoreEnd - /** - * Get the domain of FF system. - * - * @return string - */ - protected function getDomain(): string // get request info - { - $url = url()->to('/'); - $parts = parse_url($url); - - return $parts['host']; - } } diff --git a/app/Http/Controllers/Recurring/IndexController.php b/app/Http/Controllers/Recurring/IndexController.php index a939b63a46..5981e82c1e 100644 --- a/app/Http/Controllers/Recurring/IndexController.php +++ b/app/Http/Controllers/Recurring/IndexController.php @@ -96,7 +96,8 @@ class IndexController extends Controller } $paginator = new LengthAwarePaginator($recurring, $total, $pageSize, $page); $paginator->setPath(route('recurring.index')); - return view('recurring.index', compact('paginator', 'page', 'pageSize','total')); + + return view('recurring.index', compact('paginator', 'page', 'pageSize', 'total')); } /** diff --git a/app/Http/Controllers/Report/OperationsController.php b/app/Http/Controllers/Report/OperationsController.php index 4a5fa1061c..383629446b 100644 --- a/app/Http/Controllers/Report/OperationsController.php +++ b/app/Http/Controllers/Report/OperationsController.php @@ -113,7 +113,7 @@ class OperationsController extends Controller $entries = $this->tasker->getIncomeReport($start, $end, $accounts); $type = 'income-entry'; try { - $result = view('reports.partials.income-expenses', compact('entries', 'type'))->render(); + $result = view('reports.partials.income-expenses', compact('entries', 'type'))->render(); } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.income-expenses: %s', $e->getMessage())); $result = 'Could not render view.'; @@ -165,7 +165,7 @@ class OperationsController extends Controller ) ); try { - $result = view('reports.partials.operations', compact('incomeSum', 'expensesSum'))->render(); + $result = view('reports.partials.operations', compact('incomeSum', 'expensesSum'))->render(); } catch (Throwable $e) { Log::debug(sprintf('Could not render reports.partials.operations: %s', $e->getMessage())); $result = 'Could not render view.'; diff --git a/app/Http/Controllers/Rule/SelectController.php b/app/Http/Controllers/Rule/SelectController.php index 56af135847..4de34985ed 100644 --- a/app/Http/Controllers/Rule/SelectController.php +++ b/app/Http/Controllers/Rule/SelectController.php @@ -32,6 +32,7 @@ use FireflyIII\Http\Requests\TestRuleFormRequest; use FireflyIII\Jobs\ExecuteRuleOnExistingTransactions; use FireflyIII\Models\Rule; use FireflyIII\Repositories\Account\AccountRepositoryInterface; +use FireflyIII\Support\Http\Controllers\RequestInformation; use FireflyIII\Support\Http\Controllers\RuleManagement; use FireflyIII\TransactionRules\TransactionMatcher; use FireflyIII\User; @@ -48,7 +49,7 @@ use Throwable; */ class SelectController extends Controller { - use RuleManagement; + use RuleManagement, RequestInformation; /** @var AccountRepositoryInterface The account repository */ private $accountRepos; @@ -256,27 +257,4 @@ class SelectController extends Controller } - /** - * Get a list of triggers. - * - * @param TestRuleFormRequest $request - * - * @return array - */ - protected function getValidTriggerList(TestRuleFormRequest $request): array // process input - { - $triggers = []; - $data = $request->get('rule_triggers'); - if (\is_array($data)) { - foreach ($data as $index => $triggerInfo) { - $triggers[] = [ - 'type' => $triggerInfo['name'] ?? '', - 'value' => $triggerInfo['value'] ?? '', - 'stop_processing' => 1 === (int)($triggerInfo['stop_processing'] ?? '0'), - ]; - } - } - - return $triggers; - } } diff --git a/app/Http/Controllers/Transaction/SplitController.php b/app/Http/Controllers/Transaction/SplitController.php index f0420a20a6..7f6b27707a 100644 --- a/app/Http/Controllers/Transaction/SplitController.php +++ b/app/Http/Controllers/Transaction/SplitController.php @@ -35,6 +35,7 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Support\Http\Controllers\ModelInformation; +use FireflyIII\Support\Http\Controllers\RequestInformation; use FireflyIII\Transformers\TransactionTransformer; use Illuminate\Http\Request; use Illuminate\Support\Collection; @@ -48,7 +49,7 @@ use View; */ class SplitController extends Controller { - use ModelInformation; + use ModelInformation, RequestInformation; /** @var AttachmentHelperInterface Attachment helper */ private $attachments; @@ -176,95 +177,7 @@ class SplitController extends Controller return redirect($this->getPreviousUri('transactions.edit-split.uri')); } - /** - * Create data-array from a journal. - * - * @param SplitJournalFormRequest|Request $request - * @param TransactionJournal $journal - * - * @return array - * @throws FireflyException - */ - protected function arrayFromJournal(Request $request, TransactionJournal $journal): array // convert user input. - { - $sourceAccounts = $this->repository->getJournalSourceAccounts($journal); - $destinationAccounts = $this->repository->getJournalDestinationAccounts($journal); - $array = [ - 'journal_description' => $request->old('journal_description', $journal->description), - 'journal_amount' => '0', - 'journal_foreign_amount' => '0', - 'sourceAccounts' => $sourceAccounts, - 'journal_source_id' => $request->old('journal_source_id', $sourceAccounts->first()->id), - 'journal_source_name' => $request->old('journal_source_name', $sourceAccounts->first()->name), - 'journal_destination_id' => $request->old('journal_destination_id', $destinationAccounts->first()->id), - 'destinationAccounts' => $destinationAccounts, - 'what' => strtolower($this->repository->getTransactionType($journal)), - 'date' => $request->old('date', $this->repository->getJournalDate($journal, null)), - 'tags' => implode(',', $journal->tags->pluck('tag')->toArray()), - // all custom fields: - 'interest_date' => $request->old('interest_date', $this->repository->getMetaField($journal, 'interest_date')), - 'book_date' => $request->old('book_date', $this->repository->getMetaField($journal, 'book_date')), - 'process_date' => $request->old('process_date', $this->repository->getMetaField($journal, 'process_date')), - 'due_date' => $request->old('due_date', $this->repository->getMetaField($journal, 'due_date')), - 'payment_date' => $request->old('payment_date', $this->repository->getMetaField($journal, 'payment_date')), - 'invoice_date' => $request->old('invoice_date', $this->repository->getMetaField($journal, 'invoice_date')), - 'internal_reference' => $request->old('internal_reference', $this->repository->getMetaField($journal, 'internal_reference')), - 'notes' => $request->old('notes', $this->repository->getNoteText($journal)), - - // transactions. - 'transactions' => $this->getTransactionDataFromJournal($journal), - ]; - // update transactions array with old request data. - $array['transactions'] = $this->updateWithPrevious($array['transactions'], $request->old()); - - // update journal amount and foreign amount: - $array['journal_amount'] = array_sum(array_column($array['transactions'], 'amount')); - $array['journal_foreign_amount'] = array_sum(array_column($array['transactions'], 'foreign_amount')); - - return $array; - } - - /** - * Get transaction overview from journal. - * - * @param TransactionJournal $journal - * - * @return array - * @throws FireflyException - * - * @SuppressWarnings(PHPMD.CyclomaticComplexity) - */ - protected function getTransactionDataFromJournal(TransactionJournal $journal): array // convert object - { - // use collector to collect transactions. - $collector = app(JournalCollectorInterface::class); - $collector->setUser(auth()->user()); - $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); - // filter on specific journals. - $collector->setJournals(new Collection([$journal])); - $set = $collector->getJournals(); - $transactions = []; - $transformer = new TransactionTransformer(new ParameterBag); - /** @var Transaction $transaction */ - foreach ($set as $transaction) { - $res = []; - if ((float)$transaction->transaction_amount > 0 && $journal->transactionType->type === TransactionType::DEPOSIT) { - $res = $transformer->transform($transaction); - } - if ((float)$transaction->transaction_amount < 0 && $journal->transactionType->type !== TransactionType::DEPOSIT) { - $res = $transformer->transform($transaction); - } - - if (\count($res) > 0) { - $res['amount'] = app('steam')->positive((string)$res['amount']); - $res['foreign_amount'] = app('steam')->positive((string)$res['foreign_amount']); - $transactions[] = $res; - } - } - - return $transactions; - } /** * Get info from old input. diff --git a/app/Support/Http/Controllers/RequestInformation.php b/app/Support/Http/Controllers/RequestInformation.php new file mode 100644 index 0000000000..93caf0b424 --- /dev/null +++ b/app/Support/Http/Controllers/RequestInformation.php @@ -0,0 +1,399 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Support\Http\Controllers; + +use Carbon\Carbon; +use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Exceptions\ValidationException; +use FireflyIII\Helpers\Collector\JournalCollectorInterface; +use FireflyIII\Helpers\Help\HelpInterface; +use FireflyIII\Http\Requests\SplitJournalFormRequest; +use FireflyIII\Http\Requests\TestRuleFormRequest; +use FireflyIII\Models\Transaction; +use FireflyIII\Models\TransactionJournal; +use FireflyIII\Models\TransactionType; +use FireflyIII\Support\Binder\AccountList; +use FireflyIII\Transformers\TransactionTransformer; +use FireflyIII\User; +use Hash; +use Illuminate\Contracts\Validation\Validator as ValidatorContract; +use Illuminate\Http\Request; +use Illuminate\Support\Collection; +use Illuminate\Support\Facades\Validator; +use InvalidArgumentException; +use Log; +use Route; +use Symfony\Component\HttpFoundation\ParameterBag; + +/** + * Trait RequestInformation + * + * @package FireflyIII\Support\Http\Controllers + */ +trait RequestInformation +{ + + /** + * Create data-array from a journal. + * + * @param SplitJournalFormRequest|Request $request + * @param TransactionJournal $journal + * + * @return array + * @throws FireflyException + */ + protected function arrayFromJournal(Request $request, TransactionJournal $journal): array // convert user input. + { + $sourceAccounts = $this->repository->getJournalSourceAccounts($journal); + $destinationAccounts = $this->repository->getJournalDestinationAccounts($journal); + $array = [ + 'journal_description' => $request->old('journal_description', $journal->description), + 'journal_amount' => '0', + 'journal_foreign_amount' => '0', + 'sourceAccounts' => $sourceAccounts, + 'journal_source_id' => $request->old('journal_source_id', $sourceAccounts->first()->id), + 'journal_source_name' => $request->old('journal_source_name', $sourceAccounts->first()->name), + 'journal_destination_id' => $request->old('journal_destination_id', $destinationAccounts->first()->id), + 'destinationAccounts' => $destinationAccounts, + 'what' => strtolower($this->repository->getTransactionType($journal)), + 'date' => $request->old('date', $this->repository->getJournalDate($journal, null)), + 'tags' => implode(',', $journal->tags->pluck('tag')->toArray()), + + // all custom fields: + 'interest_date' => $request->old('interest_date', $this->repository->getMetaField($journal, 'interest_date')), + 'book_date' => $request->old('book_date', $this->repository->getMetaField($journal, 'book_date')), + 'process_date' => $request->old('process_date', $this->repository->getMetaField($journal, 'process_date')), + 'due_date' => $request->old('due_date', $this->repository->getMetaField($journal, 'due_date')), + 'payment_date' => $request->old('payment_date', $this->repository->getMetaField($journal, 'payment_date')), + 'invoice_date' => $request->old('invoice_date', $this->repository->getMetaField($journal, 'invoice_date')), + 'internal_reference' => $request->old('internal_reference', $this->repository->getMetaField($journal, 'internal_reference')), + 'notes' => $request->old('notes', $this->repository->getNoteText($journal)), + + // transactions. + 'transactions' => $this->getTransactionDataFromJournal($journal), + ]; + // update transactions array with old request data. + $array['transactions'] = $this->updateWithPrevious($array['transactions'], $request->old()); + + // update journal amount and foreign amount: + $array['journal_amount'] = array_sum(array_column($array['transactions'], 'amount')); + $array['journal_foreign_amount'] = array_sum(array_column($array['transactions'], 'foreign_amount')); + + return $array; + } + + /** + * Get the domain of FF system. + * + * @return string + */ + protected function getDomain(): string // get request info + { + $url = url()->to('/'); + $parts = parse_url($url); + + return $parts['host']; + } + + /** + * Gets the help text. + * + * @param string $route + * @param string $language + * + * @return string + * @SuppressWarnings(PHPMD.ExcessiveMethodLength) + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + protected function getHelpText(string $route, string $language): string // get from internet. + { + $help = app(HelpInterface::class); + // get language and default variables. + $content = '

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

'; + + // if no such route, log error and return default text. + if (!$help->hasRoute($route)) { + Log::error('No such route: ' . $route); + + return $content; + } + + // help content may be cached: + if ($help->inCache($route, $language)) { + $content = $help->getFromCache($route, $language); + Log::debug(sprintf('Help text %s was in cache.', $language)); + + return $content; + } + + // get help content from Github: + $content = $help->getFromGitHub($route, $language); + + // content will have 0 length when Github failed. Try en_US when it does: + if ('' === $content) { + $language = 'en_US'; + + // also check cache first: + if ($help->inCache($route, $language)) { + Log::debug(sprintf('Help text %s was in cache.', $language)); + $content = $help->getFromCache($route, $language); + + return $content; + } + + $content = $help->getFromGitHub($route, $language); + } + + // help still empty? + if ('' !== $content) { + $help->putInCache($route, $language, $content); + + return $content; + } + + return '

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

'; + } + + /** + * Get user's language. + * + * @return string + */ + protected function getLanguage(): string // get preference + { + /** @var string $language */ + $language = app('preferences')->get('language', config('firefly.default_language', 'en_US'))->data; + + return $language; + } + + /** + * @return string + */ + protected function getPageName(): string // get request info + { + return str_replace('.', '_', Route::currentRouteName()); + } + + /** + * Get the specific name of a page for intro. + * + * @return string + */ + protected function getSpecificPageName(): string // get request info + { + return null === Route::current()->parameter('what') ? '' : '_' . Route::current()->parameter('what'); + } + + /** + * Get transaction overview from journal. + * + * @param TransactionJournal $journal + * + * @return array + * @throws FireflyException + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + protected function getTransactionDataFromJournal(TransactionJournal $journal): array // convert object + { + // use collector to collect transactions. + $collector = app(JournalCollectorInterface::class); + $collector->setUser(auth()->user()); + $collector->withOpposingAccount()->withCategoryInformation()->withBudgetInformation(); + // filter on specific journals. + $collector->setJournals(new Collection([$journal])); + $set = $collector->getJournals(); + $transactions = []; + $transformer = new TransactionTransformer(new ParameterBag); + /** @var Transaction $transaction */ + foreach ($set as $transaction) { + $res = []; + if ((float)$transaction->transaction_amount > 0 && $journal->transactionType->type === TransactionType::DEPOSIT) { + $res = $transformer->transform($transaction); + } + if ((float)$transaction->transaction_amount < 0 && $journal->transactionType->type !== TransactionType::DEPOSIT) { + $res = $transformer->transform($transaction); + } + + if (\count($res) > 0) { + $res['amount'] = app('steam')->positive((string)$res['amount']); + $res['foreign_amount'] = app('steam')->positive((string)$res['foreign_amount']); + $transactions[] = $res; + } + } + + return $transactions; + } + + /** + * Get a list of triggers. + * + * @param TestRuleFormRequest $request + * + * @return array + */ + protected function getValidTriggerList(TestRuleFormRequest $request): array // process input + { + $triggers = []; + $data = $request->get('rule_triggers'); + if (\is_array($data)) { + foreach ($data as $index => $triggerInfo) { + $triggers[] = [ + 'type' => $triggerInfo['name'] ?? '', + 'value' => $triggerInfo['value'] ?? '', + 'stop_processing' => 1 === (int)($triggerInfo['stop_processing'] ?? '0'), + ]; + } + } + + return $triggers; + } + + /** + * Returns if user has seen demo. + * + * @return bool + */ + protected function hasSeenDemo(): bool // get request info + get preference + { + $page = $this->getPageName(); + $specificPage = $this->getSpecificPageName(); + + // indicator if user has seen the help for this page ( + special page): + $key = 'shown_demo_' . $page . $specificPage; + // is there an intro for this route? + $intro = config('intro.' . $page) ?? []; + $specialIntro = config('intro.' . $page . $specificPage) ?? []; + // some routes have a "what" parameter, which indicates a special page: + + $shownDemo = true; + // both must be array and either must be > 0 + if (\count($intro) > 0 || \count($specialIntro) > 0) { + $shownDemo = app('preferences')->get($key, false)->data; + Log::debug(sprintf('Check if user has already seen intro with key "%s". Result is %d', $key, $shownDemo)); + } + + return $shownDemo; + } + + /** + * Check if date is outside session range. + * + * @param Carbon $date + * + * @return bool + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + */ + protected function notInSessionRange(Carbon $date): bool // Validate a preference + { + /** @var Carbon $start */ + $start = session('start', Carbon::now()->startOfMonth()); + /** @var Carbon $end */ + $end = session('end', Carbon::now()->endOfMonth()); + $result = false; + if ($start->greaterThanOrEqualTo($date) && $end->greaterThanOrEqualTo($date)) { + $result = true; + } + // start and end in the past? use $end + if ($start->lessThanOrEqualTo($date) && $end->lessThanOrEqualTo($date)) { + $result = true; + } + + return $result; + } + + /** + * Parses attributes from URI. + * + * @param array $attributes + * + * @return array + */ + protected function parseAttributes(array $attributes): array // parse input + return result + { + $attributes['location'] = $attributes['location'] ?? ''; + $attributes['accounts'] = AccountList::routeBinder($attributes['accounts'] ?? '', new Route('get', '', [])); + try { + $attributes['startDate'] = Carbon::createFromFormat('Ymd', $attributes['startDate']); + } catch (InvalidArgumentException $e) { + Log::debug(sprintf('Not important error message: %s', $e->getMessage())); + $date = Carbon::now()->startOfMonth(); + $attributes['startDate'] = $date; + } + + try { + $attributes['endDate'] = Carbon::createFromFormat('Ymd', $attributes['endDate']); + } catch (InvalidArgumentException $e) { + Log::debug(sprintf('Not important error message: %s', $e->getMessage())); + $date = Carbon::now()->startOfMonth(); + $attributes['endDate'] = $date; + } + + return $attributes; + } + + /** + * Validate users new password. + * + * @param User $user + * @param string $current + * @param string $new + * + * @return bool + * + * @throws ValidationException + */ + protected function validatePassword(User $user, string $current, string $new): bool //get request info + { + if (!Hash::check($current, $user->password)) { + throw new ValidationException((string)trans('firefly.invalid_current_password')); + } + + if ($current === $new) { + throw new ValidationException((string)trans('firefly.should_change')); + } + + return true; + } + + /** + * Get a validator for an incoming registration request. + * + * @param array $data + * + * @return ValidatorContract + */ + protected function validator(array $data): ValidatorContract + { + return Validator::make( + $data, + [ + 'email' => 'required|string|email|max:255|unique:users', + 'password' => 'required|string|secure_password|confirmed', + ] + ); + } + +} \ No newline at end of file diff --git a/app/Support/Http/Controllers/UserNavigation.php b/app/Support/Http/Controllers/UserNavigation.php index 0425cd1db7..bbc9eb145b 100644 --- a/app/Support/Http/Controllers/UserNavigation.php +++ b/app/Support/Http/Controllers/UserNavigation.php @@ -23,9 +23,12 @@ declare(strict_types=1); namespace FireflyIII\Support\Http\Controllers; +use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; +use Illuminate\Http\RedirectResponse; +use Log; use URL; /** @@ -93,4 +96,32 @@ trait UserNavigation { session()->put($identifier, URL::previous()); } + + /** + * @param Account $account + * + * @return RedirectResponse|\Illuminate\Routing\Redirector + */ + protected function redirectToOriginalAccount(Account $account) + { + /** @var Transaction $transaction */ + $transaction = $account->transactions()->first(); + if (null === $transaction) { + app('session')->flash('error', trans('firefly.account_missing_transaction', ['name' => $account->name, 'id' => $account->id])); + Log::error(sprintf('Expected a transaction. Account #%d has none. BEEP, error.', $account->id)); + + return redirect(route('index')); + } + + $journal = $transaction->transactionJournal; + /** @var Transaction $opposingTransaction */ + $opposingTransaction = $journal->transactions()->where('transactions.id', '!=', $transaction->id)->first(); + + if (null === $opposingTransaction) { + app('session')->flash('error', trans('firefly.account_missing_transaction', ['name' => $account->name, 'id' => $account->id])); + Log::error(sprintf('Expected an opposing transaction. Account #%d has none. BEEP, error.', $account->id)); + } + + return redirect(route('accounts.show', [$opposingTransaction->account_id])); + } } \ No newline at end of file