Merge branch 'develop' of github.com:firefly-iii/firefly-iii into develop

This commit is contained in:
James Cole 2018-09-26 20:32:38 +02:00
commit e38b64547f
61 changed files with 6322 additions and 587 deletions

View File

@ -1,6 +1,6 @@
language: php language: php
php: php:
- 7.1.18 - 7.2
cache: cache:
directories: directories:

View File

@ -98,6 +98,7 @@ class UpgradeDatabase extends Command
$this->migrateAttachmentData(); $this->migrateAttachmentData();
$this->migrateBillsToRules(); $this->migrateBillsToRules();
$this->budgetLimitCurrency(); $this->budgetLimitCurrency();
$this->removeCCLiabilities();
$this->info('Firefly III database is up to date.'); $this->info('Firefly III database is up to date.');
@ -535,6 +536,28 @@ class UpgradeDatabase extends Command
} }
} }
/**
*
*/
private function removeCCLiabilities(): void
{
$ccType = AccountType::where('type', AccountType::CREDITCARD)->first();
$debtType =AccountType::where('type', AccountType::DEBT)->first();
if(null === $ccType || null === $debtType) {
return;
}
/** @var Collection $accounts */
$accounts = Account::where('account_type_id', $ccType->id)->get();
foreach($accounts as $account) {
$account->account_type_id = $debtType->id;
$account->save();
$this->line(sprintf('Converted credit card liability account "%s" (#%d) to generic debt liability.', $account->name, $account->id));
}
if($accounts->count() > 0) {
$this->info('Credit card liability types are no longer supported and have been converted to generic debts. See: http://bit.ly/FF3-credit-cards');
}
}
/** /**
* This method makes sure that the transaction journal uses the currency given in the transaction. * This method makes sure that the transaction journal uses the currency given in the transaction.
* *

View File

@ -108,6 +108,7 @@ class TransactionFactory
{ {
Log::debug('Start of TransactionFactory::createPair()', $data); Log::debug('Start of TransactionFactory::createPair()', $data);
// all this data is the same for both transactions: // all this data is the same for both transactions:
Log::debug('Searching for currency info.');
$currency = $this->findCurrency($data['currency_id'], $data['currency_code']); $currency = $this->findCurrency($data['currency_id'], $data['currency_code']);
$description = $journal->description === $data['description'] ? null : $data['description']; $description = $journal->description === $data['description'] ? null : $data['description'];
@ -164,6 +165,7 @@ class TransactionFactory
} }
// set foreign currency // set foreign currency
Log::debug('Trying to find foreign currency information.');
$foreign = $this->findCurrency($data['foreign_currency_id'], $data['foreign_currency_code']); $foreign = $this->findCurrency($data['foreign_currency_id'], $data['foreign_currency_code']);
$this->setForeignCurrency($source, $foreign); $this->setForeignCurrency($source, $foreign);
$this->setForeignCurrency($dest, $foreign); $this->setForeignCurrency($dest, $foreign);

View File

@ -36,6 +36,11 @@ use Log;
*/ */
class TransactionJournalFactory class TransactionJournalFactory
{ {
/** @var User The user */
private $user;
use JournalServiceTrait, TransactionTypeTrait;
/** /**
* Constructor. * Constructor.
*/ */
@ -46,10 +51,6 @@ class TransactionJournalFactory
} }
} }
use JournalServiceTrait, TransactionTypeTrait;
/** @var User The user */
private $user;
/** /**
* Store a new transaction journal. * Store a new transaction journal.
* *
@ -67,13 +68,15 @@ class TransactionJournalFactory
$type = $this->findTransactionType($data['type']); $type = $this->findTransactionType($data['type']);
$defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user); $defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->user);
Log::debug(sprintf('Going to store a %s', $type->type)); Log::debug(sprintf('Going to store a %s', $type->type));
$description = app('steam')->cleanString($data['description']);
$description = str_replace(["\n", "\t", "\r"], "\x20", $description);
$journal = TransactionJournal::create( $journal = TransactionJournal::create(
[ [
'user_id' => $data['user'], 'user_id' => $data['user'],
'transaction_type_id' => $type->id, 'transaction_type_id' => $type->id,
'bill_id' => null, 'bill_id' => null,
'transaction_currency_id' => $defaultCurrency->id, 'transaction_currency_id' => $defaultCurrency->id,
'description' => $data['description'], 'description' => $description,
'date' => $data['date']->format('Y-m-d'), 'date' => $data['date']->format('Y-m-d'),
'order' => 0, 'order' => 0,
'tag_count' => 0, 'tag_count' => 0,

View File

@ -182,13 +182,17 @@ class AttachmentHelper implements AttachmentHelperInterface
/** /**
* Save attachments that get uploaded with models, through the app. * Save attachments that get uploaded with models, through the app.
* *
* @param Model $model * @param object $model
* @param array|null $files * @param array|null $files
* *
* @return bool * @return bool
* @throws \Illuminate\Contracts\Encryption\EncryptException
*/ */
public function saveAttachmentsForModel(Model $model, ?array $files): bool public function saveAttachmentsForModel(object $model, ?array $files): bool
{ {
if(!($model instanceof Model)) {
return false;
}
Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', \get_class($model))); Log::debug(sprintf('Now in saveAttachmentsForModel for model %s', \get_class($model)));
if (\is_array($files)) { if (\is_array($files)) {
Log::debug('$files is an array.'); Log::debug('$files is an array.');

View File

@ -23,7 +23,6 @@ declare(strict_types=1);
namespace FireflyIII\Helpers\Attachments; namespace FireflyIII\Helpers\Attachments;
use FireflyIII\Models\Attachment; use FireflyIII\Models\Attachment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Illuminate\Support\MessageBag; use Illuminate\Support\MessageBag;
@ -84,10 +83,10 @@ interface AttachmentHelperInterface
/** /**
* Save attachments that got uploaded. * Save attachments that got uploaded.
* *
* @param Model $model * @param object $model
* @param null|array $files * @param null|array $files
* *
* @return bool * @return bool
*/ */
public function saveAttachmentsForModel(Model $model, ?array $files): bool; public function saveAttachmentsForModel(object $model, ?array $files): bool;
} }

View File

@ -83,12 +83,10 @@ class CreateController extends Controller
$debt = $this->repository->getAccountTypeByType(AccountType::DEBT); $debt = $this->repository->getAccountTypeByType(AccountType::DEBT);
$loan = $this->repository->getAccountTypeByType(AccountType::LOAN); $loan = $this->repository->getAccountTypeByType(AccountType::LOAN);
$mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE); $mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE);
$creditCard = $this->repository->getAccountTypeByType(AccountType::CREDITCARD);
$liabilityTypes = [ $liabilityTypes = [
$debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT), $debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT),
$loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN), $loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN),
$mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE), $mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE),
$creditCard->id => (string)trans('firefly.account_type_' . AccountType::CREDITCARD),
]; ];
asort($liabilityTypes); asort($liabilityTypes);

View File

@ -90,12 +90,10 @@ class EditController extends Controller
$debt = $this->repository->getAccountTypeByType(AccountType::DEBT); $debt = $this->repository->getAccountTypeByType(AccountType::DEBT);
$loan = $this->repository->getAccountTypeByType(AccountType::LOAN); $loan = $this->repository->getAccountTypeByType(AccountType::LOAN);
$mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE); $mortgage = $this->repository->getAccountTypeByType(AccountType::MORTGAGE);
$creditCard = $this->repository->getAccountTypeByType(AccountType::CREDITCARD);
$liabilityTypes = [ $liabilityTypes = [
$debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT), $debt->id => (string)trans('firefly.account_type_' . AccountType::DEBT),
$loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN), $loan->id => (string)trans('firefly.account_type_' . AccountType::LOAN),
$mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE), $mortgage->id => (string)trans('firefly.account_type_' . AccountType::MORTGAGE),
$creditCard->id => (string)trans('firefly.account_type_' . AccountType::CREDITCARD),
]; ];
asort($liabilityTypes); asort($liabilityTypes);

View File

@ -47,6 +47,8 @@ class JobStatusController extends Controller
public function __construct() public function __construct()
{ {
parent::__construct(); parent::__construct();
// set time limit to zero to prevent timeouts.
set_time_limit(0);
$this->middleware( $this->middleware(
function ($request, $next) { function ($request, $next) {

View File

@ -36,8 +36,10 @@ use FireflyIII\Repositories\Journal\JournalRepositoryInterface;
use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use FireflyIII\Support\CacheProperties; use FireflyIII\Support\CacheProperties;
use Illuminate\Http\JsonResponse; use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
/** /**
* TODO refactor so each auto-complete thing is a function call because lots of code duplication.
* Class AutoCompleteController. * Class AutoCompleteController.
* *
* @SuppressWarnings(PHPMD.TooManyPublicMethods) * @SuppressWarnings(PHPMD.TooManyPublicMethods)
@ -49,18 +51,40 @@ class AutoCompleteController extends Controller
/** /**
* Returns a JSON list of all accounts. * Returns a JSON list of all accounts.
* *
* @param Request $request
* @param AccountRepositoryInterface $repository * @param AccountRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function allAccounts(AccountRepositoryInterface $repository): JsonResponse public function allAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
{ {
$return = array_unique( $search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-all-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = array_values(
array_unique(
$repository->getAccountsByType( $repository->getAccountsByType(
[AccountType::REVENUE, AccountType::EXPENSE, AccountType::BENEFICIARY, AccountType::DEFAULT, AccountType::ASSET] [AccountType::REVENUE, AccountType::EXPENSE, AccountType::BENEFICIARY, AccountType::DEFAULT, AccountType::ASSET]
)->pluck('name')->toArray() )->pluck('name')->toArray()
)
); );
sort($return); if ('' !== $search) {
$return = array_values(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
@ -68,15 +92,86 @@ class AutoCompleteController extends Controller
/** /**
* List of all journals. * List of all journals.
* *
* @param Request $request
* @param TransactionCollectorInterface $collector * @param TransactionCollectorInterface $collector
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function allTransactionJournals(TransactionCollectorInterface $collector): JsonResponse public function allTransactionJournals(Request $request, TransactionCollectorInterface $collector): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-all-journals');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$collector->setLimit(250)->setPage(1); $collector->setLimit(250)->setPage(1);
$return = array_unique($collector->getTransactions()->pluck('description')->toArray()); $return = array_values(array_unique($collector->getTransactions()->pluck('description')->toArray()));
sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return);
}
/**
* List of revenue accounts.
*
* @param Request $request
* @param AccountRepositoryInterface $repository
*
* @return JsonResponse
*/
public function assetAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
{
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-asset-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$set = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
$filtered = $set->filter(
function (Account $account) {
if (true === $account->active) {
return $account;
}
return false; // @codeCoverageIgnore
}
);
$return = array_values(array_unique($filtered->pluck('name')->toArray()));
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
@ -84,16 +179,37 @@ class AutoCompleteController extends Controller
/** /**
* Returns a JSON list of all bills. * Returns a JSON list of all bills.
* *
* @param Request $request
* @param BillRepositoryInterface $repository * @param BillRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function bills(BillRepositoryInterface $repository): JsonResponse public function bills(Request $request, BillRepositoryInterface $repository): JsonResponse
{ {
$return = array_unique( $search = (string)$request->get('search');
$repository->getActiveBills()->pluck('name')->toArray() $cache = new CacheProperties;
$cache->addProperty('ac-bills');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = array_unique($repository->getActiveBills()->pluck('name')->toArray());
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
); );
sort($return); }
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
@ -101,14 +217,37 @@ class AutoCompleteController extends Controller
/** /**
* List of budgets. * List of budgets.
* *
* @param Request $request
* @param BudgetRepositoryInterface $repository * @param BudgetRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function budgets(BudgetRepositoryInterface $repository): JsonResponse public function budgets(Request $request, BudgetRepositoryInterface $repository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-budgets');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = array_unique($repository->getBudgets()->pluck('name')->toArray()); $return = array_unique($repository->getBudgets()->pluck('name')->toArray());
sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
@ -116,14 +255,34 @@ class AutoCompleteController extends Controller
/** /**
* Returns a list of categories. * Returns a list of categories.
* *
* @param Request $request
* @param CategoryRepositoryInterface $repository * @param CategoryRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function categories(CategoryRepositoryInterface $repository): JsonResponse public function categories(Request $request, CategoryRepositoryInterface $repository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-categories');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = array_unique($repository->getCategories()->pluck('name')->toArray()); $return = array_unique($repository->getCategories()->pluck('name')->toArray());
sort($return); if ('' !== $search) {
$return = array_values(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
@ -131,27 +290,62 @@ class AutoCompleteController extends Controller
/** /**
* List of currency names. * List of currency names.
* *
* @param Request $request
* @param CurrencyRepositoryInterface $repository * @param CurrencyRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function currencyNames(CurrencyRepositoryInterface $repository): JsonResponse public function currencyNames(Request $request, CurrencyRepositoryInterface $repository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-currency-names');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = $repository->get()->pluck('name')->toArray(); $return = $repository->get()->pluck('name')->toArray();
sort($return); sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
/** /**
* Returns a JSON list of all beneficiaries. * Returns a JSON list of all beneficiaries.
* *
* @param Request $request
* @param AccountRepositoryInterface $repository * @param AccountRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function expenseAccounts(AccountRepositoryInterface $repository): JsonResponse public function expenseAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-expense-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$set = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]); $set = $repository->getAccountsByType([AccountType::EXPENSE, AccountType::BENEFICIARY]);
$filtered = $set->filter( $filtered = $set->filter(
function (Account $account) { function (Account $account) {
@ -166,27 +360,43 @@ class AutoCompleteController extends Controller
sort($return); sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
/** /**
* List of journals with their ID. * List of journals with their ID.
* *
* @param Request $request
* @param TransactionCollectorInterface $collector * @param TransactionCollectorInterface $collector
* @param TransactionJournal $except * @param TransactionJournal $except
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function journalsWithId(TransactionCollectorInterface $collector, TransactionJournal $except): JsonResponse public function journalsWithId(Request $request, TransactionCollectorInterface $collector, TransactionJournal $except): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties; $cache = new CacheProperties;
$cache->addProperty('recent-journals-id'); $cache->addProperty('ac-expense-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) { if ($cache->has()) {
return response()->json($cache->get()); // @codeCoverageIgnore return response()->json($cache->get());
} }
// find everything:
$collector->setLimit(400)->setPage(1); $collector->setLimit(400)->setPage(1);
$set = $collector->getTransactions()->pluck('description', 'journal_id')->toArray(); $set = $collector->getTransactions()->pluck('description', 'journal_id')->toArray();
$return = []; $return = [];
@ -200,6 +410,19 @@ class AutoCompleteController extends Controller
} }
} }
sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return); $cache->store($return);
return response()->json($return); return response()->json($return);
@ -208,12 +431,23 @@ class AutoCompleteController extends Controller
/** /**
* List of revenue accounts. * List of revenue accounts.
* *
* @param Request $request
* @param AccountRepositoryInterface $repository * @param AccountRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function revenueAccounts(AccountRepositoryInterface $repository): JsonResponse public function revenueAccounts(Request $request, AccountRepositoryInterface $repository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-revenue-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$set = $repository->getAccountsByType([AccountType::REVENUE]); $set = $repository->getAccountsByType([AccountType::REVENUE]);
$filtered = $set->filter( $filtered = $set->filter(
function (Account $account) { function (Account $account) {
@ -227,30 +461,18 @@ class AutoCompleteController extends Controller
$return = array_unique($filtered->pluck('name')->toArray()); $return = array_unique($filtered->pluck('name')->toArray());
sort($return); sort($return);
return response()->json($return); if ('' !== $search) {
} $return = array_values(
array_unique(
/** array_filter(
* List of revenue accounts. $return, function (string $value) use ($search) {
* return !(false === stripos($value, $search));
* @param AccountRepositoryInterface $repository }, ARRAY_FILTER_USE_BOTH
* )
* @return JsonResponse )
*/
public function assetAccounts(AccountRepositoryInterface $repository): JsonResponse
{
$set = $repository->getAccountsByType([AccountType::DEFAULT, AccountType::ASSET]);
$filtered = $set->filter(
function (Account $account) {
if (true === $account->active) {
return $account;
}
return false; // @codeCoverageIgnore
}
); );
$return = array_unique($filtered->pluck('name')->toArray()); }
sort($return); $cache->store($return);
return response()->json($return); return response()->json($return);
} }
@ -258,28 +480,63 @@ class AutoCompleteController extends Controller
/** /**
* Returns a JSON list of all beneficiaries. * Returns a JSON list of all beneficiaries.
* *
* @param Request $request
* @param TagRepositoryInterface $tagRepository * @param TagRepositoryInterface $tagRepository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function tags(TagRepositoryInterface $tagRepository): JsonResponse public function tags(Request $request, TagRepositoryInterface $tagRepository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-revenue-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = array_unique($tagRepository->get()->pluck('tag')->toArray()); $return = array_unique($tagRepository->get()->pluck('tag')->toArray());
sort($return); sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
/** /**
* List of journals by type. * List of journals by type.
* *
* @param Request $request
* @param TransactionCollectorInterface $collector * @param TransactionCollectorInterface $collector
* @param string $what * @param string $what
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function transactionJournals(TransactionCollectorInterface $collector, string $what): JsonResponse public function transactionJournals(Request $request, TransactionCollectorInterface $collector, string $what): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-revenue-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$type = config('firefly.transactionTypesByWhat.' . $what); $type = config('firefly.transactionTypesByWhat.' . $what);
$types = [$type]; $types = [$type];
@ -287,21 +544,60 @@ class AutoCompleteController extends Controller
$return = array_unique($collector->getTransactions()->pluck('description')->toArray()); $return = array_unique($collector->getTransactions()->pluck('description')->toArray());
sort($return); sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
/** /**
* List if transaction types. * List if transaction types.
* *
* @param Request $request
* @param JournalRepositoryInterface $repository * @param JournalRepositoryInterface $repository
* *
* @return JsonResponse * @return JsonResponse
*/ */
public function transactionTypes(JournalRepositoryInterface $repository): JsonResponse public function transactionTypes(Request $request, JournalRepositoryInterface $repository): JsonResponse
{ {
$search = (string)$request->get('search');
$cache = new CacheProperties;
$cache->addProperty('ac-revenue-accounts');
// very unlikely a user will actually search for this string.
$key = '' === $search ? 'skjf0893j89fj2398hd89dh289h2398hr7isd8900828u209ujnxs88929282u' : $search;
$cache->addProperty($key);
if ($cache->has()) {
return response()->json($cache->get());
}
// find everything:
$return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray()); $return = array_unique($repository->getTransactionTypes()->pluck('type')->toArray());
sort($return); sort($return);
if ('' !== $search) {
$return = array_values(
array_unique(
array_filter(
$return, function (string $value) use ($search) {
return !(false === stripos($value, $search));
}, ARRAY_FILTER_USE_BOTH
)
)
);
}
$cache->store($return);
return response()->json($return); return response()->json($return);
} }
} }

View File

@ -68,7 +68,7 @@ class Authenticate
*/ */
public function handle($request, Closure $next, ...$guards) public function handle($request, Closure $next, ...$guards)
{ {
$this->authenticate($guards); $this->authenticate($request, $guards);
return $next($request); return $next($request);
} }
@ -86,7 +86,7 @@ class Authenticate
* @SuppressWarnings(PHPMD.CyclomaticComplexity) * @SuppressWarnings(PHPMD.CyclomaticComplexity)
* @SuppressWarnings(PHPMD.ExcessiveMethodLength) * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/ */
protected function authenticate(array $guards) protected function authenticate($request, array $guards)
{ {
if (empty($guards)) { if (empty($guards)) {

View File

@ -57,7 +57,7 @@ class SecureHeaders
"form-action 'self'", "form-action 'self'",
"font-src 'self'", "font-src 'self'",
"connect-src 'self'", "connect-src 'self'",
"img-src 'self' data:", "img-src 'self' data: https://api.tiles.mapbox.com",
]; ];
$featurePolicies = [ $featurePolicies = [

View File

@ -92,58 +92,7 @@ class Request extends FormRequest
*/ */
public function string(string $field): string public function string(string $field): string
{ {
$string = $this->get($field) ?? ''; return app('steam')->cleanString($this->get($field) ?? '');
$search = [
"\u{0001}", // start of heading
"\u{0002}", // start of text
"\u{0003}", // end of text
"\u{0004}", // end of transmission
"\u{0005}", // enquiry
"\u{0006}", // ACK
"\u{0007}", // BEL
"\u{0008}", // backspace
"\u{000E}", // shift out
"\u{000F}", // shift in
"\u{0010}", // data link escape
"\u{0011}", // DC1
"\u{0012}", // DC2
"\u{0013}", // DC3
"\u{0014}", // DC4
"\u{0015}", // NAK
"\u{0016}", // SYN
"\u{0017}", // ETB
"\u{0018}", // CAN
"\u{0019}", // EM
"\u{001A}", // SUB
"\u{001B}", // escape
"\u{001C}", // file separator
"\u{001D}", // group separator
"\u{001E}", // record separator
"\u{001F}", // unit separator
"\u{007F}", // DEL
"\u{00A0}", // non-breaking space
"\u{1680}", // ogham space mark
"\u{180E}", // mongolian vowel separator
"\u{2000}", // en quad
"\u{2001}", // em quad
"\u{2002}", // en space
"\u{2003}", // em space
"\u{2004}", // three-per-em space
"\u{2005}", // four-per-em space
"\u{2006}", // six-per-em space
"\u{2007}", // figure space
"\u{2008}", // punctuation space
"\u{2009}", // thin space
"\u{200A}", // hair space
"\u{200B}", // zero width space
"\u{202F}", // narrow no-break space
"\u{3000}", // ideographic space
"\u{FEFF}", // zero width no -break space
];
$replace = "\x20"; // plain old normal space
$string = str_replace($search, $replace, $string);
return trim($string);
} }
/** /**

View File

@ -79,7 +79,7 @@ class ChooseAccountsHandler implements BunqJobConfigurationInterface
$config = $this->repository->getConfiguration($this->importJob); $config = $this->repository->getConfiguration($this->importJob);
$accounts = $config['accounts'] ?? []; $accounts = $config['accounts'] ?? [];
$mapping = $data['account_mapping'] ?? []; $mapping = $data['account_mapping'] ?? [];
$applyRules = 1 === (int)$data['apply_rules']; $applyRules = 1 === (int)($data['apply_rules'] ?? 0);
$final = []; $final = [];
/* /*

View File

@ -30,7 +30,6 @@ use FireflyIII\Models\Transaction;
use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Account\AccountRepositoryInterface;
use Illuminate\Contracts\Encryption\DecryptException; use Illuminate\Contracts\Encryption\DecryptException;
use Illuminate\Support\Collection; use Illuminate\Support\Collection;
use Log;
use stdClass; use stdClass;
/** /**
@ -38,6 +37,7 @@ use stdClass;
*/ */
class Steam class Steam
{ {
/** /**
* @param \FireflyIII\Models\Account $account * @param \FireflyIII\Models\Account $account
* @param \Carbon\Carbon $date * @param \Carbon\Carbon $date
@ -315,6 +315,68 @@ class Steam
return $result; return $result;
} }
/**
* Remove weird chars from strings.
*
* @param string $string
*
* @return string
*/
public function cleanString(string $string): string
{
$search = [
"\u{0001}", // start of heading
"\u{0002}", // start of text
"\u{0003}", // end of text
"\u{0004}", // end of transmission
"\u{0005}", // enquiry
"\u{0006}", // ACK
"\u{0007}", // BEL
"\u{0008}", // backspace
"\u{000E}", // shift out
"\u{000F}", // shift in
"\u{0010}", // data link escape
"\u{0011}", // DC1
"\u{0012}", // DC2
"\u{0013}", // DC3
"\u{0014}", // DC4
"\u{0015}", // NAK
"\u{0016}", // SYN
"\u{0017}", // ETB
"\u{0018}", // CAN
"\u{0019}", // EM
"\u{001A}", // SUB
"\u{001B}", // escape
"\u{001C}", // file separator
"\u{001D}", // group separator
"\u{001E}", // record separator
"\u{001F}", // unit separator
"\u{007F}", // DEL
"\u{00A0}", // non-breaking space
"\u{1680}", // ogham space mark
"\u{180E}", // mongolian vowel separator
"\u{2000}", // en quad
"\u{2001}", // em quad
"\u{2002}", // en space
"\u{2003}", // em space
"\u{2004}", // three-per-em space
"\u{2005}", // four-per-em space
"\u{2006}", // six-per-em space
"\u{2007}", // figure space
"\u{2008}", // punctuation space
"\u{2009}", // thin space
"\u{200A}", // hair space
"\u{200B}", // zero width space
"\u{202F}", // narrow no-break space
"\u{3000}", // ideographic space
"\u{FEFF}", // zero width no -break space
];
$replace = "\x20"; // plain old normal space
$string = str_replace($search, $replace, $string);
return trim($string);
}
/** /**
* @param int $isEncrypted * @param int $isEncrypted
* @param $value * @param $value

View File

@ -46,21 +46,21 @@
} }
], ],
"require": { "require": {
"php": ">=7.1.0", "php": ">=7.2.0",
"ext-bcmath": "*", "ext-bcmath": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-gd": "*", "ext-gd": "*",
"ext-intl": "*", "ext-intl": "*",
"ext-xml": "*", "ext-xml": "*",
"ext-zip": "*", "ext-zip": "*",
"bacon/bacon-qr-code": "1.*", "bacon/bacon-qr-code": "2.*",
"bunq/sdk_php": "dev-master#8c1faefc111d9b970168a1837ca165d854954941", "bunq/sdk_php": "dev-master#8c1faefc111d9b970168a1837ca165d854954941",
"davejamesmiller/laravel-breadcrumbs": "5.*", "davejamesmiller/laravel-breadcrumbs": "5.*",
"doctrine/dbal": "2.*", "doctrine/dbal": "2.*",
"fideloper/proxy": "4.*", "fideloper/proxy": "4.*",
"laravel/framework": "5.6.*", "laravel/framework": "5.7.*",
"laravel/passport": "^5.0", "laravel/passport": "^7.0",
"laravelcollective/html": "5.6.*", "laravelcollective/html": "5.7.*",
"league/commonmark": "0.*", "league/commonmark": "0.*",
"league/csv": "9.*", "league/csv": "9.*",
"league/fractal": "^0.17.0", "league/fractal": "^0.17.0",
@ -74,9 +74,9 @@
"filp/whoops": "2.*", "filp/whoops": "2.*",
"fzaninotto/faker": "1.*", "fzaninotto/faker": "1.*",
"johnkary/phpunit-speedtrap": "^3.0", "johnkary/phpunit-speedtrap": "^3.0",
"mockery/mockery": "^1.0", "mockery/mockery": "1.*",
"php-coveralls/php-coveralls": "^2.0", "php-coveralls/php-coveralls": "^2.0",
"phpunit/phpunit": "~7.0", "phpunit/phpunit": "7.*",
"roave/security-advisories": "dev-master" "roave/security-advisories": "dev-master"
}, },
"autoload": { "autoload": {
@ -112,13 +112,13 @@
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump" "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump"
], ],
"post-update-cmd": [ "post-update-cmd": [
"php artisan firefly:upgrade-database", "@php artisan firefly:upgrade-database",
"php artisan firefly:verify", "@php artisan firefly:verify",
"php artisan firefly:instructions update", "@php artisan firefly:instructions update",
"php artisan passport:install" "@php artisan passport:install"
], ],
"post-install-cmd": [ "post-install-cmd": [
"php artisan firefly:instructions install" "@php artisan firefly:instructions install"
] ]
}, },
"config": { "config": {

411
composer.lock generated
View File

@ -4,36 +4,39 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "dcaf20ad3436c4fc4cbebeee09c9de1f", "content-hash": "364135d1fab7e47564deae52ea0c12c2",
"packages": [ "packages": [
{ {
"name": "bacon/bacon-qr-code", "name": "bacon/bacon-qr-code",
"version": "1.0.3", "version": "2.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Bacon/BaconQrCode.git", "url": "https://github.com/Bacon/BaconQrCode.git",
"reference": "5a91b62b9d37cee635bbf8d553f4546057250bee" "reference": "eaac909da3ccc32b748a65b127acd8918f58d9b0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/5a91b62b9d37cee635bbf8d553f4546057250bee", "url": "https://api.github.com/repos/Bacon/BaconQrCode/zipball/eaac909da3ccc32b748a65b127acd8918f58d9b0",
"reference": "5a91b62b9d37cee635bbf8d553f4546057250bee", "reference": "eaac909da3ccc32b748a65b127acd8918f58d9b0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"dasprid/enum": "^1.0",
"ext-iconv": "*", "ext-iconv": "*",
"php": "^5.4|^7.0" "php": "^7.1"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8" "phly/keep-a-changelog": "^1.4",
"phpunit/phpunit": "^6.4",
"squizlabs/php_codesniffer": "^3.1"
}, },
"suggest": { "suggest": {
"ext-gd": "to generate QR code images" "ext-imagick": "to generate QR code images"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"BaconQrCode": "src/" "BaconQrCode\\": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -50,7 +53,7 @@
], ],
"description": "BaconQrCode is a QR code generator for PHP.", "description": "BaconQrCode is a QR code generator for PHP.",
"homepage": "https://github.com/Bacon/BaconQrCode", "homepage": "https://github.com/Bacon/BaconQrCode",
"time": "2017-10-17T09:59:25+00:00" "time": "2018-04-25T17:53:56+00:00"
}, },
{ {
"name": "bunq/sdk_php", "name": "bunq/sdk_php",
@ -117,27 +120,69 @@
"time": "2018-09-01T12:54:04+00:00" "time": "2018-09-01T12:54:04+00:00"
}, },
{ {
"name": "davejamesmiller/laravel-breadcrumbs", "name": "dasprid/enum",
"version": "5.1.0", "version": "1.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git", "url": "https://github.com/DASPRiD/Enum.git",
"reference": "2a02abfeca13acba6d528f4fcd385570452308f7" "reference": "631ef6e638e9494b0310837fa531bedd908fc22b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/2a02abfeca13acba6d528f4fcd385570452308f7", "url": "https://api.github.com/repos/DASPRiD/Enum/zipball/631ef6e638e9494b0310837fa531bedd908fc22b",
"reference": "2a02abfeca13acba6d528f4fcd385570452308f7", "reference": "631ef6e638e9494b0310837fa531bedd908fc22b",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "^6.4",
"squizlabs/php_codesniffer": "^3.1"
},
"type": "library",
"autoload": {
"psr-4": {
"DASPRiD\\Enum\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Ben Scholzen 'DASPRiD'",
"email": "mail@dasprids.de",
"homepage": "https://dasprids.de/"
}
],
"description": "PHP 7.1 enum implementation",
"keywords": [
"enum",
"map"
],
"time": "2017-10-25T22:45:27+00:00"
},
{
"name": "davejamesmiller/laravel-breadcrumbs",
"version": "5.1.2",
"source": {
"type": "git",
"url": "https://github.com/davejamesmiller/laravel-breadcrumbs.git",
"reference": "f24853b97d9f973a9b936d2692f93b11924415e2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/davejamesmiller/laravel-breadcrumbs/zipball/f24853b97d9f973a9b936d2692f93b11924415e2",
"reference": "f24853b97d9f973a9b936d2692f93b11924415e2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"illuminate/support": "5.6.*", "illuminate/support": "5.6.*|5.7.*",
"illuminate/view": "5.6.*", "illuminate/view": "5.6.*|5.7.*",
"php": ">=7.1.3" "php": ">=7.1.3"
}, },
"require-dev": { "require-dev": {
"laravel/framework": "5.6.*", "laravel/framework": "5.6.*|5.7.*",
"orchestra/testbench": "3.6.*", "orchestra/testbench": "3.6.*|3.7.*",
"php-coveralls/php-coveralls": "^1.0", "php-coveralls/php-coveralls": "^1.0",
"phpunit/phpunit": "7.*" "phpunit/phpunit": "7.*"
}, },
@ -173,7 +218,7 @@
"keywords": [ "keywords": [
"laravel" "laravel"
], ],
"time": "2018-05-05T19:30:03+00:00" "time": "2018-09-14T06:29:58+00:00"
}, },
{ {
"name": "defuse/php-encryption", "name": "defuse/php-encryption",
@ -1022,42 +1067,42 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v5.6.38", "version": "v5.7.4",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "38d838bab9434af79e8ab274ae63f52f7ed45d6e" "reference": "f6e8f6562120e0063313e81716666cfcd362569b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/38d838bab9434af79e8ab274ae63f52f7ed45d6e", "url": "https://api.github.com/repos/laravel/framework/zipball/f6e8f6562120e0063313e81716666cfcd362569b",
"reference": "38d838bab9434af79e8ab274ae63f52f7ed45d6e", "reference": "f6e8f6562120e0063313e81716666cfcd362569b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"doctrine/inflector": "~1.1", "doctrine/inflector": "^1.1",
"dragonmantank/cron-expression": "~2.0", "dragonmantank/cron-expression": "^2.0",
"erusev/parsedown": "~1.7", "erusev/parsedown": "^1.7",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-openssl": "*", "ext-openssl": "*",
"league/flysystem": "^1.0.8", "league/flysystem": "^1.0.8",
"monolog/monolog": "~1.12", "monolog/monolog": "^1.12",
"nesbot/carbon": "1.25.*", "nesbot/carbon": "^1.26.3",
"php": "^7.1.3", "php": "^7.1.3",
"psr/container": "~1.0", "psr/container": "^1.0",
"psr/simple-cache": "^1.0", "psr/simple-cache": "^1.0",
"ramsey/uuid": "^3.7", "ramsey/uuid": "^3.7",
"swiftmailer/swiftmailer": "~6.0", "swiftmailer/swiftmailer": "^6.0",
"symfony/console": "~4.0", "symfony/console": "^4.1",
"symfony/debug": "~4.0", "symfony/debug": "^4.1",
"symfony/finder": "~4.0", "symfony/finder": "^4.1",
"symfony/http-foundation": "~4.0", "symfony/http-foundation": "^4.1",
"symfony/http-kernel": "~4.0", "symfony/http-kernel": "^4.1",
"symfony/process": "~4.0", "symfony/process": "^4.1",
"symfony/routing": "~4.0", "symfony/routing": "^4.1",
"symfony/var-dumper": "~4.0", "symfony/var-dumper": "^4.1",
"tijsverkoyen/css-to-inline-styles": "^2.2.1", "tijsverkoyen/css-to-inline-styles": "^2.2.1",
"vlucas/phpdotenv": "~2.2" "vlucas/phpdotenv": "^2.2"
}, },
"conflict": { "conflict": {
"tightenco/collect": "<5.5.33" "tightenco/collect": "<5.5.33"
@ -1093,43 +1138,45 @@
"illuminate/view": "self.version" "illuminate/view": "self.version"
}, },
"require-dev": { "require-dev": {
"aws/aws-sdk-php": "~3.0", "aws/aws-sdk-php": "^3.0",
"doctrine/dbal": "~2.6", "doctrine/dbal": "^2.6",
"filp/whoops": "^2.1.4", "filp/whoops": "^2.1.4",
"league/flysystem-cached-adapter": "~1.0", "league/flysystem-cached-adapter": "^1.0",
"mockery/mockery": "~1.0", "mockery/mockery": "^1.0",
"moontoast/math": "^1.1", "moontoast/math": "^1.1",
"orchestra/testbench-core": "3.6.*", "orchestra/testbench-core": "3.7.*",
"pda/pheanstalk": "~3.0", "pda/pheanstalk": "^3.0",
"phpunit/phpunit": "~7.0", "phpunit/phpunit": "^7.0",
"predis/predis": "^1.1.1", "predis/predis": "^1.1.1",
"symfony/css-selector": "~4.0", "symfony/css-selector": "^4.1",
"symfony/dom-crawler": "~4.0" "symfony/dom-crawler": "^4.1",
"true/punycode": "^2.1"
}, },
"suggest": { "suggest": {
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).", "aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (^3.0).",
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.6).", "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).",
"ext-pcntl": "Required to use all features of the queue worker.", "ext-pcntl": "Required to use all features of the queue worker.",
"ext-posix": "Required to use all features of the queue worker.", "ext-posix": "Required to use all features of the queue worker.",
"fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).", "fzaninotto/faker": "Required to use the eloquent factory builder (^1.4).",
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).", "guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (^6.0).",
"laravel/tinker": "Required to use the tinker console command (~1.0).", "laravel/tinker": "Required to use the tinker console command (^1.0).",
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (~1.0).", "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).", "league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).",
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (~1.0).", "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).",
"nexmo/client": "Required to use the Nexmo transport (~1.0).", "moontoast/math": "Required to use ordered UUIDs (^1.1).",
"pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).", "nexmo/client": "Required to use the Nexmo transport (^1.0).",
"predis/predis": "Required to use the redis cache and queue drivers (~1.0).", "pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~3.0).", "predis/predis": "Required to use the redis cache and queue drivers (^1.0).",
"symfony/css-selector": "Required to use some of the crawler integration testing tools (~4.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0).",
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~4.0).", "symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).",
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)." "symfony/dom-crawler": "Required to use most of the crawler integration testing tools (^4.1).",
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (^1.0)."
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "5.6-dev" "dev-master": "5.7-dev"
} }
}, },
"autoload": { "autoload": {
@ -1157,20 +1204,20 @@
"framework", "framework",
"laravel" "laravel"
], ],
"time": "2018-09-04T13:15:09+00:00" "time": "2018-09-18T13:34:05+00:00"
}, },
{ {
"name": "laravel/passport", "name": "laravel/passport",
"version": "v5.0.3", "version": "v7.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/passport.git", "url": "https://github.com/laravel/passport.git",
"reference": "9dbcc3d6f8f20f1a83cbef73bbb563ce59e43ded" "reference": "90124969cdd4ff39d4cd5a608c23bbe16e772f7e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/passport/zipball/9dbcc3d6f8f20f1a83cbef73bbb563ce59e43ded", "url": "https://api.github.com/repos/laravel/passport/zipball/90124969cdd4ff39d4cd5a608c23bbe16e772f7e",
"reference": "9dbcc3d6f8f20f1a83cbef73bbb563ce59e43ded", "reference": "90124969cdd4ff39d4cd5a608c23bbe16e772f7e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1184,8 +1231,8 @@
"illuminate/encryption": "~5.6", "illuminate/encryption": "~5.6",
"illuminate/http": "~5.6", "illuminate/http": "~5.6",
"illuminate/support": "~5.6", "illuminate/support": "~5.6",
"league/oauth2-server": "^6.0", "league/oauth2-server": "^7.0",
"php": ">=7.0", "php": ">=7.1",
"phpseclib/phpseclib": "^2.0", "phpseclib/phpseclib": "^2.0",
"symfony/psr-http-message-bridge": "~1.0", "symfony/psr-http-message-bridge": "~1.0",
"zendframework/zend-diactoros": "~1.0" "zendframework/zend-diactoros": "~1.0"
@ -1226,39 +1273,39 @@
"oauth", "oauth",
"passport" "passport"
], ],
"time": "2018-03-15T12:39:02+00:00" "time": "2018-08-13T14:45:04+00:00"
}, },
{ {
"name": "laravelcollective/html", "name": "laravelcollective/html",
"version": "v5.6.10", "version": "v5.7.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/LaravelCollective/html.git", "url": "https://github.com/LaravelCollective/html.git",
"reference": "974605fcd22a7e4d19f0b2ef635a0d1d7400387d" "reference": "777b6d390811ba249255ed5750bf17a019cd88a5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/LaravelCollective/html/zipball/974605fcd22a7e4d19f0b2ef635a0d1d7400387d", "url": "https://api.github.com/repos/LaravelCollective/html/zipball/777b6d390811ba249255ed5750bf17a019cd88a5",
"reference": "974605fcd22a7e4d19f0b2ef635a0d1d7400387d", "reference": "777b6d390811ba249255ed5750bf17a019cd88a5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"illuminate/http": "5.6.*", "illuminate/http": "5.7.*",
"illuminate/routing": "5.6.*", "illuminate/routing": "5.7.*",
"illuminate/session": "5.6.*", "illuminate/session": "5.7.*",
"illuminate/support": "5.6.*", "illuminate/support": "5.7.*",
"illuminate/view": "5.6.*", "illuminate/view": "5.7.*",
"php": ">=7.1.3" "php": ">=7.1.3"
}, },
"require-dev": { "require-dev": {
"illuminate/database": "5.6.*", "illuminate/database": "5.7.*",
"mockery/mockery": "~1.0", "mockery/mockery": "~1.0",
"phpunit/phpunit": "~7.1" "phpunit/phpunit": "~7.1"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "5.6-dev" "dev-master": "5.7-dev"
}, },
"laravel": { "laravel": {
"providers": [ "providers": [
@ -1294,7 +1341,7 @@
], ],
"description": "HTML and Form Builders for the Laravel Framework", "description": "HTML and Form Builders for the Laravel Framework",
"homepage": "https://laravelcollective.com", "homepage": "https://laravelcollective.com",
"time": "2018-06-18T15:04:16+00:00" "time": "2018-09-05T18:32:53+00:00"
}, },
{ {
"name": "lcobucci/jwt", "name": "lcobucci/jwt",
@ -1356,16 +1403,16 @@
}, },
{ {
"name": "league/commonmark", "name": "league/commonmark",
"version": "0.17.5", "version": "0.18.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/commonmark.git", "url": "https://github.com/thephpleague/commonmark.git",
"reference": "82d7ab62d7f68391cb9d323f3ccce50be24a5369" "reference": "006af077d4b1b7eb1d9760964f9f984ba188632c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/82d7ab62d7f68391cb9d323f3ccce50be24a5369", "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/006af077d4b1b7eb1d9760964f9f984ba188632c",
"reference": "82d7ab62d7f68391cb9d323f3ccce50be24a5369", "reference": "006af077d4b1b7eb1d9760964f9f984ba188632c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1394,7 +1441,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "0.18-dev" "dev-master": "0.19-dev"
} }
}, },
"autoload": { "autoload": {
@ -1421,7 +1468,7 @@
"markdown", "markdown",
"parser" "parser"
], ],
"time": "2018-03-29T14:35:19+00:00" "time": "2018-09-18T13:13:55+00:00"
}, },
{ {
"name": "league/csv", "name": "league/csv",
@ -1542,26 +1589,26 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.0.46", "version": "1.0.47",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2" "reference": "a11e4a75f256bdacf99d20780ce42d3b8272975c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a11e4a75f256bdacf99d20780ce42d3b8272975c",
"reference": "f3e0d925c18b92cf3ce84ea5cc58d62a1762a2b2", "reference": "a11e4a75f256bdacf99d20780ce42d3b8272975c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-fileinfo": "*",
"php": ">=5.5.9" "php": ">=5.5.9"
}, },
"conflict": { "conflict": {
"league/flysystem-sftp": "<1.0.6" "league/flysystem-sftp": "<1.0.6"
}, },
"require-dev": { "require-dev": {
"ext-fileinfo": "*",
"phpspec/phpspec": "^3.4", "phpspec/phpspec": "^3.4",
"phpunit/phpunit": "^5.7.10" "phpunit/phpunit": "^5.7.10"
}, },
@ -1622,7 +1669,7 @@
"sftp", "sftp",
"storage" "storage"
], ],
"time": "2018-08-22T07:45:22+00:00" "time": "2018-09-14T15:30:29+00:00"
}, },
{ {
"name": "league/fractal", "name": "league/fractal",
@ -1690,34 +1737,36 @@
}, },
{ {
"name": "league/oauth2-server", "name": "league/oauth2-server",
"version": "6.1.1", "version": "7.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/oauth2-server.git", "url": "https://github.com/thephpleague/oauth2-server.git",
"reference": "a0cabb573c7cd5ee01803daec992d6ee3677c4ae" "reference": "8184f771d43ea7305ddbb893d0daf6f0352ec5fd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/a0cabb573c7cd5ee01803daec992d6ee3677c4ae", "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/8184f771d43ea7305ddbb893d0daf6f0352ec5fd",
"reference": "a0cabb573c7cd5ee01803daec992d6ee3677c4ae", "reference": "8184f771d43ea7305ddbb893d0daf6f0352ec5fd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"defuse/php-encryption": "^2.1", "defuse/php-encryption": "^2.1",
"ext-openssl": "*", "ext-openssl": "*",
"lcobucci/jwt": "^3.1", "lcobucci/jwt": "^3.2.2",
"league/event": "^2.1", "league/event": "^2.1",
"paragonie/random_compat": "^2.0", "php": ">=7.0.0",
"php": ">=5.6.0", "psr/http-message": "^1.0.1"
"psr/http-message": "^1.0"
}, },
"replace": { "replace": {
"league/oauth2server": "*", "league/oauth2server": "*",
"lncd/oauth2": "*" "lncd/oauth2": "*"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8.38 || ^5.7.21", "phpstan/phpstan": "^0.9.2",
"zendframework/zend-diactoros": "^1.0" "phpstan/phpstan-phpunit": "^0.9.4",
"phpstan/phpstan-strict-rules": "^0.9.0",
"phpunit/phpunit": "^6.3 || ^7.0",
"zendframework/zend-diactoros": "^1.3.2"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -1754,7 +1803,7 @@
"secure", "secure",
"server" "server"
], ],
"time": "2017-12-23T23:33:42+00:00" "time": "2018-06-23T16:57:59+00:00"
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
@ -1836,16 +1885,16 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "1.25.0", "version": "1.33.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4" "reference": "55667c1007a99e82030874b1bb14d24d07108413"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/55667c1007a99e82030874b1bb14d24d07108413",
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4", "reference": "55667c1007a99e82030874b1bb14d24d07108413",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1858,13 +1907,15 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "laravel": {
"dev-master": "1.23-dev" "providers": [
"Carbon\\Laravel\\ServiceProvider"
]
} }
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"Carbon\\": "src/Carbon/" "": "src/"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -1885,7 +1936,7 @@
"datetime", "datetime",
"time" "time"
], ],
"time": "2018-03-19T15:50:49+00:00" "time": "2018-08-07T08:39:47+00:00"
}, },
{ {
"name": "paragonie/constant_time_encoding", "name": "paragonie/constant_time_encoding",
@ -1951,33 +2002,29 @@
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
"version": "v2.0.17", "version": "v9.99.99",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/paragonie/random_compat.git", "url": "https://github.com/paragonie/random_compat.git",
"reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d" "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/29af24f25bab834fcbb38ad2a69fa93b867e070d", "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
"reference": "29af24f25bab834fcbb38ad2a69fa93b867e070d", "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.2.0" "php": "^7"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "4.*|5.*" "phpunit/phpunit": "4.*|5.*",
"vimeo/psalm": "^1"
}, },
"suggest": { "suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
}, },
"type": "library", "type": "library",
"autoload": {
"files": [
"lib/random.php"
]
},
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
"license": [ "license": [
"MIT" "MIT"
@ -1996,7 +2043,7 @@
"pseudorandom", "pseudorandom",
"random" "random"
], ],
"time": "2018-07-04T16:31:37+00:00" "time": "2018-07-02T15:55:56+00:00"
}, },
{ {
"name": "phpseclib/phpseclib", "name": "phpseclib/phpseclib",
@ -2500,22 +2547,22 @@
}, },
{ {
"name": "rcrowe/twigbridge", "name": "rcrowe/twigbridge",
"version": "v0.9.6", "version": "v0.9.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/rcrowe/TwigBridge.git", "url": "https://github.com/rcrowe/TwigBridge.git",
"reference": "c3579440a3ca47ca45bfb0ed854bc0ff9b086bf5" "reference": "d0c998ae6d39f154c4e2d01ef914e49d0b7d5d68"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/c3579440a3ca47ca45bfb0ed854bc0ff9b086bf5", "url": "https://api.github.com/repos/rcrowe/TwigBridge/zipball/d0c998ae6d39f154c4e2d01ef914e49d0b7d5d68",
"reference": "c3579440a3ca47ca45bfb0ed854bc0ff9b086bf5", "reference": "d0c998ae6d39f154c4e2d01ef914e49d0b7d5d68",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"illuminate/support": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*", "illuminate/support": "5.5.*|5.6.*|5.7.*",
"illuminate/view": "5.0.*|5.1.*|5.2.*|5.3.*|5.4.*|5.5.*|5.6.*", "illuminate/view": "5.5.*|5.6.*|5.7.*",
"php": ">=5.4.0", "php": ">=7",
"twig/twig": "~1.30" "twig/twig": "~1.30"
}, },
"require-dev": { "require-dev": {
@ -2568,20 +2615,20 @@
"laravel", "laravel",
"twig" "twig"
], ],
"time": "2018-02-08T15:59:23+00:00" "time": "2018-08-31T13:30:10+00:00"
}, },
{ {
"name": "swiftmailer/swiftmailer", "name": "swiftmailer/swiftmailer",
"version": "v6.1.2", "version": "v6.1.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/swiftmailer/swiftmailer.git", "url": "https://github.com/swiftmailer/swiftmailer.git",
"reference": "7d760881d266d63c5e7a1155cbcf2ac656a31ca8" "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/7d760881d266d63c5e7a1155cbcf2ac656a31ca8", "url": "https://api.github.com/repos/swiftmailer/swiftmailer/zipball/8ddcb66ac10c392d3beb54829eef8ac1438595f4",
"reference": "7d760881d266d63c5e7a1155cbcf2ac656a31ca8", "reference": "8ddcb66ac10c392d3beb54829eef8ac1438595f4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2627,7 +2674,7 @@
"mail", "mail",
"mailer" "mailer"
], ],
"time": "2018-07-13T07:04:35+00:00" "time": "2018-09-11T07:12:52+00:00"
}, },
{ {
"name": "symfony/console", "name": "symfony/console",
@ -3835,16 +3882,16 @@
}, },
{ {
"name": "zendframework/zend-diactoros", "name": "zendframework/zend-diactoros",
"version": "1.8.5", "version": "1.8.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/zendframework/zend-diactoros.git", "url": "https://github.com/zendframework/zend-diactoros.git",
"reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87" "reference": "20da13beba0dde8fb648be3cc19765732790f46e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/3e4edb822c942f37ade0d09579cfbab11e2fee87", "url": "https://api.github.com/repos/zendframework/zend-diactoros/zipball/20da13beba0dde8fb648be3cc19765732790f46e",
"reference": "3e4edb822c942f37ade0d09579cfbab11e2fee87", "reference": "20da13beba0dde8fb648be3cc19765732790f46e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3857,6 +3904,7 @@
"require-dev": { "require-dev": {
"ext-dom": "*", "ext-dom": "*",
"ext-libxml": "*", "ext-libxml": "*",
"php-http/psr7-integration-tests": "dev-master",
"phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7", "phpunit/phpunit": "^5.7.16 || ^6.0.8 || ^7.2.7",
"zendframework/zend-coding-standard": "~1.0" "zendframework/zend-coding-standard": "~1.0"
}, },
@ -3894,22 +3942,22 @@
"psr", "psr",
"psr-7" "psr-7"
], ],
"time": "2018-08-10T14:16:32+00:00" "time": "2018-09-05T19:29:37+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [
{ {
"name": "barryvdh/laravel-ide-helper", "name": "barryvdh/laravel-ide-helper",
"version": "v2.5.0", "version": "v2.5.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git", "url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "09db8c9a76711e98c61af0795934fb15955223fb" "reference": "7db1843473e1562d8e0490b51db847d3a1415140"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/09db8c9a76711e98c61af0795934fb15955223fb", "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/7db1843473e1562d8e0490b51db847d3a1415140",
"reference": "09db8c9a76711e98c61af0795934fb15955223fb", "reference": "7db1843473e1562d8e0490b51db847d3a1415140",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3970,7 +4018,7 @@
"phpstorm", "phpstorm",
"sublime" "sublime"
], ],
"time": "2018-08-31T13:28:09+00:00" "time": "2018-09-06T18:41:09+00:00"
}, },
{ {
"name": "barryvdh/reflection-docblock", "name": "barryvdh/reflection-docblock",
@ -4380,16 +4428,16 @@
}, },
{ {
"name": "filp/whoops", "name": "filp/whoops",
"version": "2.2.0", "version": "2.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/filp/whoops.git", "url": "https://github.com/filp/whoops.git",
"reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a" "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/181c4502d8f34db7aed7bfe88d4f87875b8e947a", "url": "https://api.github.com/repos/filp/whoops/zipball/e79cd403fb77fc8963a99ecc30e80ddd885b3311",
"reference": "181c4502d8f34db7aed7bfe88d4f87875b8e947a", "reference": "e79cd403fb77fc8963a99ecc30e80ddd885b3311",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4408,7 +4456,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "2.1-dev" "dev-master": "2.2-dev"
} }
}, },
"autoload": { "autoload": {
@ -4437,7 +4485,7 @@
"throwable", "throwable",
"whoops" "whoops"
], ],
"time": "2018-03-03T17:56:25+00:00" "time": "2018-06-30T13:14:06+00:00"
}, },
{ {
"name": "fzaninotto/faker", "name": "fzaninotto/faker",
@ -5230,21 +5278,24 @@
}, },
{ {
"name": "phpunit/php-file-iterator", "name": "phpunit/php-file-iterator",
"version": "2.0.1", "version": "2.0.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" "reference": "050bedf145a257b1ff02746c31894800e5122946"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
"reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", "reference": "050bedf145a257b1ff02746c31894800e5122946",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.1" "php": "^7.1"
}, },
"require-dev": {
"phpunit/phpunit": "^7.1"
},
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -5273,7 +5324,7 @@
"filesystem", "filesystem",
"iterator" "iterator"
], ],
"time": "2018-06-11T11:44:00+00:00" "time": "2018-09-13T20:33:42+00:00"
}, },
{ {
"name": "phpunit/php-text-template", "name": "phpunit/php-text-template",
@ -5416,16 +5467,16 @@
}, },
{ {
"name": "phpunit/phpunit", "name": "phpunit/phpunit",
"version": "7.3.3", "version": "7.3.5",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git", "url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "1bd5629cccfb2c0a9ef5474b4ff772349e1ec898" "reference": "7b331efabbb628c518c408fdfcaf571156775de2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1bd5629cccfb2c0a9ef5474b4ff772349e1ec898", "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b331efabbb628c518c408fdfcaf571156775de2",
"reference": "1bd5629cccfb2c0a9ef5474b4ff772349e1ec898", "reference": "7b331efabbb628c518c408fdfcaf571156775de2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -5496,7 +5547,7 @@
"testing", "testing",
"xunit" "xunit"
], ],
"time": "2018-09-01T15:49:55+00:00" "time": "2018-09-08T15:14:29+00:00"
}, },
{ {
"name": "roave/security-advisories", "name": "roave/security-advisories",
@ -5508,6 +5559,7 @@
"amphp/http": "<1.0.1", "amphp/http": "<1.0.1",
"asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99",
"aws/aws-sdk-php": ">=3,<3.2.1", "aws/aws-sdk-php": ">=3,<3.2.1",
"brightlocal/phpwhois": "<=4.2.5",
"bugsnag/bugsnag-laravel": ">=2,<2.0.2", "bugsnag/bugsnag-laravel": ">=2,<2.0.2",
"cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4|>=3.4,<3.4.14|>=3.5,<3.5.17|>=3.6,<3.6.4", "cakephp/cakephp": ">=1.3,<1.3.18|>=2,<2.4.99|>=2.5,<2.5.99|>=2.6,<2.6.12|>=2.7,<2.7.6|>=3,<3.0.15|>=3.1,<3.1.4|>=3.4,<3.4.14|>=3.5,<3.5.17|>=3.6,<3.6.4",
"cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4",
@ -5519,6 +5571,7 @@
"contao/core-bundle": ">=4,<4.4.18|>=4.5,<4.5.8", "contao/core-bundle": ">=4,<4.4.18|>=4.5,<4.5.8",
"contao/listing-bundle": ">=4,<4.4.8", "contao/listing-bundle": ">=4,<4.4.8",
"contao/newsletter-bundle": ">=4,<4.1", "contao/newsletter-bundle": ">=4,<4.1",
"david-garcia/phpwhois": "<=4.3.1",
"doctrine/annotations": ">=1,<1.2.7", "doctrine/annotations": ">=1,<1.2.7",
"doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2",
"doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1", "doctrine/common": ">=2,<2.4.3|>=2.5,<2.5.1",
@ -5533,6 +5586,7 @@
"drupal/drupal": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3", "drupal/drupal": ">=7,<7.59|>=8,<8.4.8|>=8.5,<8.5.3",
"erusev/parsedown": "<1.7", "erusev/parsedown": "<1.7",
"ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1", "ezsystems/ezpublish-legacy": ">=5.3,<5.3.12.3|>=5.4,<5.4.11.3|>=2017.8,<2017.8.1.1|>=2017.12,<2017.12.2.1",
"ezyang/htmlpurifier": "<4.1.1",
"firebase/php-jwt": "<2", "firebase/php-jwt": "<2",
"friendsofsymfony/rest-bundle": ">=1.2,<1.2.2", "friendsofsymfony/rest-bundle": ">=1.2,<1.2.2",
"friendsofsymfony/user-bundle": ">=1.2,<1.3.5", "friendsofsymfony/user-bundle": ">=1.2,<1.3.5",
@ -5544,7 +5598,11 @@
"illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
"illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29", "illuminate/database": ">=4,<4.0.99|>=4.1,<4.1.29",
"illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15",
"ivankristianto/phpwhois": "<=4.3",
"james-heinrich/getid3": "<1.9.9",
"joomla/session": "<1.3.1", "joomla/session": "<1.3.1",
"jsmitty12/phpwhois": "<5.1",
"kazist/phpwhois": "<=4.2.6",
"kreait/firebase-php": ">=3.2,<3.8.1", "kreait/firebase-php": ">=3.2,<3.8.1",
"laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30", "laravel/framework": ">=4,<4.0.99|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.42|>=5.6,<5.6.30",
"laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10", "laravel/socialite": ">=1,<1.0.99|>=2,<2.0.10",
@ -5554,6 +5612,7 @@
"monolog/monolog": ">=1.8,<1.12", "monolog/monolog": ">=1.8,<1.12",
"namshi/jose": "<2.2", "namshi/jose": "<2.2",
"onelogin/php-saml": "<2.10.4", "onelogin/php-saml": "<2.10.4",
"openid/php-openid": "<2.3",
"oro/crm": ">=1.7,<1.7.4", "oro/crm": ">=1.7,<1.7.4",
"oro/platform": ">=1.7,<1.7.4", "oro/platform": ">=1.7,<1.7.4",
"padraic/humbug_get_contents": "<1.1.2", "padraic/humbug_get_contents": "<1.1.2",
@ -5562,21 +5621,25 @@
"paypal/merchant-sdk-php": "<3.12", "paypal/merchant-sdk-php": "<3.12",
"phpmailer/phpmailer": ">=5,<5.2.24", "phpmailer/phpmailer": ">=5,<5.2.24",
"phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3",
"phpwhois/phpwhois": "<=4.2.5",
"phpxmlrpc/extras": "<0.6.1", "phpxmlrpc/extras": "<0.6.1",
"propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7", "propel/propel": ">=2.0.0-alpha1,<=2.0.0-alpha7",
"propel/propel1": ">=1,<=1.7.1", "propel/propel1": ">=1,<=1.7.1",
"pusher/pusher-php-server": "<2.2.1", "pusher/pusher-php-server": "<2.2.1",
"sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9", "sabre/dav": ">=1.6,<1.6.99|>=1.7,<1.7.11|>=1.8,<1.8.9",
"sensiolabs/connect": "<4.2.3", "sensiolabs/connect": "<4.2.3",
"serluck/phpwhois": "<=4.2.6",
"shopware/shopware": "<5.3.7", "shopware/shopware": "<5.3.7",
"silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11", "silverstripe/cms": ">=3,<=3.0.11|>=3.1,<3.1.11",
"silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3",
"silverstripe/framework": ">=3,<3.3", "silverstripe/framework": ">=3,<3.3",
"silverstripe/userforms": "<3", "silverstripe/userforms": "<3",
"simple-updates/phpwhois": "<=1",
"simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4", "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4",
"simplesamlphp/simplesamlphp": "<1.15.2", "simplesamlphp/simplesamlphp": "<1.15.2",
"simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1",
"slim/slim": "<2.6", "slim/slim": "<2.6",
"smarty/smarty": "<3.1.33",
"socalnick/scn-social-auth": "<1.15.2", "socalnick/scn-social-auth": "<1.15.2",
"squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1",
"stormpath/sdk": ">=0,<9.9.99", "stormpath/sdk": ">=0,<9.9.99",
@ -5603,8 +5666,10 @@
"symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4",
"symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7", "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7",
"thelia/backoffice-default-template": ">=2.1,<2.1.2", "thelia/backoffice-default-template": ">=2.1,<2.1.2",
"thelia/thelia": ">=2.1,<2.1.2|>=2.1.0-beta1,<2.1.3", "thelia/thelia": ">=2.1.0-beta1,<2.1.3|>=2.1,<2.1.2",
"theonedemon/phpwhois": "<=4.2.5",
"titon/framework": ">=0,<9.9.99", "titon/framework": ">=0,<9.9.99",
"truckersmp/phpwhois": "<=4.3.1",
"twig/twig": "<1.20", "twig/twig": "<1.20",
"typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.30|>=8,<8.7.17|>=9,<9.3.2", "typo3/cms": ">=6.2,<6.2.30|>=7,<7.6.30|>=8,<8.7.17|>=9,<9.3.2",
"typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2", "typo3/cms-core": ">=8,<8.7.17|>=9,<9.3.2",
@ -5657,7 +5722,7 @@
} }
], ],
"description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it", "description": "Prevents installation of composer packages with known security vulnerabilities: no API, simply require it",
"time": "2018-08-14T15:39:17+00:00" "time": "2018-09-17T20:20:31+00:00"
}, },
{ {
"name": "sebastian/code-unit-reverse-lookup", "name": "sebastian/code-unit-reverse-lookup",
@ -6636,7 +6701,7 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=7.1.0", "php": ">=7.2.0",
"ext-bcmath": "*", "ext-bcmath": "*",
"ext-curl": "*", "ext-curl": "*",
"ext-gd": "*", "ext-gd": "*",

View File

@ -31,6 +31,7 @@ return [
'4.7.3' => 'This version of Firefly III handles bills differently. See http://bit.ly/FF3-new-bills for more information.', '4.7.3' => 'This version of Firefly III handles bills differently. See http://bit.ly/FF3-new-bills for more information.',
'4.7.4' => 'This version of Firefly III has a new import routine. See http://bit.ly/FF3-new-import for more information.', '4.7.4' => 'This version of Firefly III has a new import routine. See http://bit.ly/FF3-new-import for more information.',
'4.7.6' => 'This will be the last version to require PHP7.1. Future versions will require PHP7.2 minimum.', '4.7.6' => 'This will be the last version to require PHP7.1. Future versions will require PHP7.2 minimum.',
'4.7.7' => 'This version of Firefly III requires PHP7.2.',
], ],
'install' => 'install' =>
[ [
@ -40,6 +41,7 @@ return [
'4.7.3' => 'This version of Firefly III handles bills differently. See http://bit.ly/FF3-new-bills for more information.', '4.7.3' => 'This version of Firefly III handles bills differently. See http://bit.ly/FF3-new-bills for more information.',
'4.7.4' => 'This version of Firefly III has a new import routine. See http://bit.ly/FF3-new-import for more information.', '4.7.4' => 'This version of Firefly III has a new import routine. See http://bit.ly/FF3-new-import for more information.',
'4.7.6' => 'This will be the last version to require PHP7.1. Future versions will require PHP7.2 minimum.', '4.7.6' => 'This will be the last version to require PHP7.1. Future versions will require PHP7.2 minimum.',
'4.7.7' => 'This version of Firefly III requires PHP7.2.',
], ],
], ],
]; ];

View File

@ -28,7 +28,7 @@ use Illuminate\Database\Seeder;
*/ */
class AccountTypeSeeder extends Seeder class AccountTypeSeeder extends Seeder
{ {
public function run() public function run(): void
{ {
$types = [ $types = [
AccountType::DEFAULT, AccountType::DEFAULT,
@ -42,8 +42,7 @@ class AccountTypeSeeder extends Seeder
AccountType::LOAN, AccountType::LOAN,
AccountType::RECONCILIATION, AccountType::RECONCILIATION,
AccountType::DEBT, AccountType::DEBT,
AccountType::MORTGAGE, AccountType::MORTGAGE
AccountType::CREDITCARD,
]; ];
foreach ($types as $type) { foreach ($types as $type) {
try { try {

View File

@ -65,6 +65,9 @@ class TransactionCurrencySeeder extends Seeder
$currencies[] = ['code' => 'BCH', 'name' => 'Bitcoin cash', 'symbol' => '₿C', 'decimal_places' => 8]; $currencies[] = ['code' => 'BCH', 'name' => 'Bitcoin cash', 'symbol' => '₿C', 'decimal_places' => 8];
$currencies[] = ['code' => 'ETH', 'name' => 'Ethereum', 'symbol' => 'Ξ', 'decimal_places' => 12]; $currencies[] = ['code' => 'ETH', 'name' => 'Ethereum', 'symbol' => 'Ξ', 'decimal_places' => 12];
// PLEASE ADD NEW CURRENCIES BELOW THIS LINE
$currencies[] = ['code' => 'ILS', 'name' => 'Israeli new shekel', 'symbol' => '₪', 'decimal_places' => 2];
foreach ($currencies as $currency) { foreach ($currencies as $currency) {
try { try {
TransactionCurrency::create($currency); TransactionCurrency::create($currency);

View File

@ -1,5 +1,5 @@
/* /*
* bootstrap-tagsinput v0.8.0 * bootstrap-tagsinput v0.9.1
* *
*/ */
@ -16,7 +16,6 @@
line-height: 22px; line-height: 22px;
cursor: text; cursor: text;
} }
.bootstrap-tagsinput input { .bootstrap-tagsinput input {
border: none; border: none;
box-shadow: none; box-shadow: none;
@ -27,44 +26,35 @@
width: auto; width: auto;
max-width: inherit; max-width: inherit;
} }
.bootstrap-tagsinput.form-control input::-moz-placeholder { .bootstrap-tagsinput.form-control input::-moz-placeholder {
color: #777; color: #777;
opacity: 1; opacity: 1;
} }
.bootstrap-tagsinput.form-control input:-ms-input-placeholder { .bootstrap-tagsinput.form-control input:-ms-input-placeholder {
color: #777; color: #777;
} }
.bootstrap-tagsinput.form-control input::-webkit-input-placeholder { .bootstrap-tagsinput.form-control input::-webkit-input-placeholder {
color: #777; color: #777;
} }
.bootstrap-tagsinput input:focus { .bootstrap-tagsinput input:focus {
border: none; border: none;
box-shadow: none; box-shadow: none;
} }
.bootstrap-tagsinput .tag { .bootstrap-tagsinput .tag {
margin-right: 2px; margin-right: 2px;
color: white; color: white;
} }
.bootstrap-tagsinput .tag [data-role="remove"] { .bootstrap-tagsinput .tag [data-role="remove"] {
margin-left: 8px; margin-left: 8px;
cursor: pointer; cursor: pointer;
} }
.bootstrap-tagsinput .tag [data-role="remove"]:after { .bootstrap-tagsinput .tag [data-role="remove"]:after {
content: "x"; content: "x";
padding: 0px 2px; padding: 0px 2px;
} }
.bootstrap-tagsinput .tag [data-role="remove"]:hover { .bootstrap-tagsinput .tag [data-role="remove"]:hover {
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
} }
.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { .bootstrap-tagsinput .tag [data-role="remove"]:hover:active {
box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
} }

View File

@ -170,3 +170,77 @@ span.info-box-text a:hover, span.info-box-number a:hover {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
} }
.bootstrap-tagsinput {
width: 100%;
}
.accordion {
margin-bottom:-3px;
}
.accordion-group {
border: none;
}
.twitter-typeahead {
width:100%;
}
span.twitter-typeahead {
display: inline !important;width:100%;
}
.tt-input {
background-color:#fff !important;
}
.twitter-typeahead .tt-query,
.twitter-typeahead .tt-hint {
margin-bottom: 0;
}
.twitter-typeahead .tt-hint
{
display: none;
}
.tt-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
list-style: none;
font-size: 14px;
background-color: #ffffff;
border: 1px solid #cccccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
cursor: pointer;
}
.tt-suggestion {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.428571429;
color: #333333;
white-space: nowrap;
}
.tt-suggestion:hover,
.tt-suggestion:focus {
color: #ffffff;
text-decoration: none;
outline: 0;
background-color: #428bca;
}

View File

@ -18,8 +18,6 @@
* along with Firefly III. If not, see <http://www.gnu.org/licenses/>. * along with Firefly III. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** global: what, Modernizr, selectsForeignCurrency, convertForeignToNative, validateCurrencyForTransfer, convertSourceToDestination, journalData, journal, accountInfo, exchangeRateInstructions, currencyInfo */
$(document).ready(function () { $(document).ready(function () {
"use strict"; "use strict";
setAutocompletes(); setAutocompletes();
@ -30,24 +28,7 @@ $(document).ready(function () {
* Set the auto-complete JSON things. * Set the auto-complete JSON things.
*/ */
function setAutocompletes() { function setAutocompletes() {
initCategoryAC();
$.getJSON('json/categories').done(function (data) { initTagsAC();
$('input[name="category"]').typeahead({source: data, autoSelect: false});
});
$.getJSON('json/tags').done(function (data) {
var opt = {
typeahead: {
source: data,
afterSelect: function () {
this.$element.val("");
},
autoSelect: false,
}
};
$('input[name="tags"]').tagsinput(
opt
);
});
} }

165
public/js/ff/common/autocomplete.js vendored Normal file
View File

@ -0,0 +1,165 @@
/*
* autocomplete.js
* 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/>.
*/
/**
* Do tags auto complete.
*/
function initTagsAC() {
console.log('initTagsAC()');
var tagTags = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/tags',
filter: function (list) {
return $.map(list, function (tagTag) {
return {name: tagTag};
});
}
},
remote: {
url: 'json/tags?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
tagTags.initialize();
$('input[name="tags"]').tagsinput({
typeaheadjs: {
hint: true,
highlight: true,
name: 'tags',
displayKey: 'name',
valueKey: 'name',
source: tagTags.ttAdapter()
}
});
}
/**
* Do destination name (expense accounts) auto complete.
*/
function initExpenseAC() {
initExpenseACField('destination_name');
}
/**
* Do destination name (expense accounts) auto complete.
*/
function initExpenseACField(fieldName) {
console.log('initExpenseACField("' + fieldName + '")');
if ($('input[name="' + fieldName + '"]').length > 0) {
var destNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/expense-accounts',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: 'json/expense-accounts?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
destNames.initialize();
$('input[name="' + fieldName + '"]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
}
}
/**
* Do source name (revenue accounts) auto complete.
*/
function initRevenueAC() {
initRevenueACField('source_name');
}
/**
* Do source name (revenue accounts) auto complete.
*/
function initRevenueACField(fieldName) {
console.log('initRevenueACField("' + fieldName + '")');
if ($('input[name="' + fieldName + '"]').length > 0) {
var sourceNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/revenue-accounts',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: 'json/revenue-accounts?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
sourceNames.initialize();
$('input[name="' + fieldName + '"]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
}
}
/**
* Do categories auto complete.
*/
function initCategoryAC() {
var categories = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/categories',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: 'json/categories?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
categories.initialize();
$('input[name="category"]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
}

View File

@ -137,39 +137,10 @@ function parseRepetitionSuggestions(data) {
} }
function initializeAutoComplete() { function initializeAutoComplete() {
// auto complete things: initTagsAC();
$.getJSON('json/tags').done(function (data) { initExpenseAC();
var opt = { initRevenueAC();
typeahead: { initCategoryAC();
source: data,
afterSelect: function () {
this.$element.val("");
},
autoSelect: false,
},
autoSelect: false,
};
$('input[name="tags"]').tagsinput(
opt
);
});
if ($('input[name="destination_name"]').length > 0) {
$.getJSON('json/expense-accounts').done(function (data) {
$('input[name="destination_name"]').typeahead({source: data, autoSelect: false});
});
}
if ($('input[name="source_name"]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="source_name"]').typeahead({source: data, autoSelect: false});
});
}
$.getJSON('json/categories').done(function (data) {
$('input[name="category"]').typeahead({source: data, autoSelect: false});
});
} }
/** /**

View File

@ -138,39 +138,10 @@ function parseRepetitionSuggestions(data) {
} }
function initializeAutoComplete() { function initializeAutoComplete() {
// auto complete things: initTagsAC();
$.getJSON('json/tags').done(function (data) { initExpenseAC();
var opt = { initRevenueAC();
typeahead: { initCategoryAC();
source: data,
afterSelect: function () {
this.$element.val("");
},
autoSelect: false,
},
autoSelect: false,
};
$('input[name="tags"]').tagsinput(
opt
);
});
if ($('input[name="destination_name"]').length > 0) {
$.getJSON('json/expense-accounts').done(function (data) {
$('input[name="destination_name"]').typeahead({source: data, autoSelect: false});
});
}
if ($('input[name="source_name"]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="source_name"]').typeahead({source: data, autoSelect: false});
});
}
$.getJSON('json/categories').done(function (data) {
$('input[name="category"]').typeahead({source: data, autoSelect: false});
});
} }
/** /**

View File

@ -360,15 +360,32 @@ function updateTriggerInput(selectList) {
* @param URI * @param URI
*/ */
function createAutoComplete(input, URI) { function createAutoComplete(input, URI) {
console.log('Now in createAutoComplete().') console.log('Now in createAutoComplete("' + URI + '").');
input.typeahead('destroy'); input.typeahead('destroy');
$.getJSON(URI).done(function (data) {
console.log('Input now has auto complete from URI ' + URI);
input.typeahead({source: data, autoSelect: false});
}).fail(function () {
console.log('Could not grab URI ' + URI + ' so autocomplete will not work');
});
var source = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: URI,
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: URI + '?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
source.initialize();
input.typeahead({hint: true, highlight: true,}, {source: source, displayKey: 'name', autoSelect: false});
} }
function testRuleTriggers() { function testRuleTriggers() {

34
public/js/ff/transactions/convert.js vendored Normal file
View File

@ -0,0 +1,34 @@
/*
* convert.js
* 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/>.
*/
$(document).ready(function () {
"use strict";
setAutocompletes();
});
/**
* Set the auto-complete JSON things.
*/
function setAutocompletes() {
initRevenueACField('source_account_revenue');
initExpenseACField('destination_account_expense');
}

View File

@ -67,7 +67,7 @@ function goToMassEdit() {
baseHref = bases[0].href; baseHref = bases[0].href;
} }
window.location.href = baseHref + '/transactions/mass/edit/' + checkedArray; window.location.href = baseHref + 'transactions/mass/edit/' + checkedArray;
return false; return false;
} }
@ -87,7 +87,7 @@ function goToBulkEdit() {
baseHref = bases[0].href; baseHref = bases[0].href;
} }
window.location.href = baseHref + '/transactions/bulk/edit/' + checkedArray; window.location.href = baseHref + 'transactions/bulk/edit/' + checkedArray;
return false; return false;
} }
@ -106,7 +106,7 @@ function goToMassDelete() {
if (bases.length > 0) { if (bases.length > 0) {
baseHref = bases[0].href; baseHref = bases[0].href;
} }
window.location.href = baseHref + '/transactions/mass/delete/' + checkedArray; window.location.href = baseHref + 'transactions/mass/delete/' + checkedArray;
return false; return false;
} }

View File

@ -22,21 +22,6 @@
$(document).ready(function () { $(document).ready(function () {
"use strict"; "use strict";
initTagsAC();
$.getJSON('json/categories').done(function (data) { initCategoryAC();
$('input[name="category"]').typeahead({source: data, autoSelect: false});
});
$.getJSON('json/tags').done(function (data) {
var opt = {
source: data,
afterSelect: function () {
this.$element.val("");
},
autoSelect: false
};
$('input[name="tags"]').tagsinput(
opt
);
});
}); });

View File

@ -25,19 +25,83 @@ $(document).ready(function () {
// destination account names: // destination account names:
if ($('input[name^="destination_name["]').length > 0) { if ($('input[name^="destination_name["]').length > 0) {
$.getJSON('json/expense-accounts').done(function (data) { var destNames = new Bloodhound({
$('input[name^="destination_name["]').typeahead({source: data, autoSelect: false}); datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/expense-accounts',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
} }
},
remote: {
url: 'json/expense-accounts?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
destNames.initialize();
$('input[name^="destination_name["]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
}
// source account name // source account name
if ($('input[name^="source_name["]').length > 0) { if ($('input[name^="source_name["]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name^="source_name["]').typeahead({source: data, autoSelect: false}); var sourceNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/revenue-accounts',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
} }
},
remote: {
url: 'json/revenue-accounts?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
sourceNames.initialize();
$.getJSON('json/categories').done(function (data) { $('input[name^="source_name["]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
$('input[name^="category["]').typeahead({source: data, autoSelect: false}); }
var categories = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/categories',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
}
},
remote: {
url: 'json/categories?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
categories.initialize();
$('input[name^="category["]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
}); });

View File

@ -22,19 +22,37 @@
$(function () { $(function () {
"use strict"; "use strict";
var transactions = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
$.getJSON(autoCompleteUri).done(function (data) { queryTokenizer: Bloodhound.tokenizers.whitespace,
var $input = $("#link_other"); prefetch: {
$input.typeahead({ url: autoCompleteUri,
source: data, filter: function (list) {
autoSelect: true return $.map(list, function (name) {
return {name: name};
}); });
$input.change(function () { }
var current = $input.typeahead("getActive"); },
remote: {
url: autoCompleteUri + '?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
transactions.initialize();
var input=$("#link_other");
input.typeahead({hint: true, highlight: true,}, {source: transactions, displayKey: 'name', autoSelect: false});
input.change(function () {
var current = input.typeahead("getActive");
if (current) { if (current) {
// Some item from your model is active! // Some item from your model is active!
if (current.name.toLowerCase() === $input.val().toLowerCase()) { if (current.name.toLowerCase() ===
input.val().toLowerCase()) {
// This means the exact match is found. Use toLowerCase() if you want case insensitive match. // This means the exact match is found. Use toLowerCase() if you want case insensitive match.
$('input[name="link_journal_id"]').val(current.id); $('input[name="link_journal_id"]').val(current.id);
} else { } else {
@ -45,6 +63,3 @@ $(function () {
} }
}); });
}); });
});

View File

@ -47,39 +47,17 @@ function runModernizer() {
*/ */
function setCommonAutocomplete() { function setCommonAutocomplete() {
console.log('In setCommonAutoComplete()'); console.log('In setCommonAutoComplete()');
$.getJSON('json/tags').done(function (data) {
var opt = {
typeahead: {
source: data,
afterSelect: function () {
this.$element.val("");
},
autoSelect: false,
},
autoSelect: false,
};
$('input[name="tags"]').tagsinput( // do tags auto complete:
opt initTagsAC();
); // do destination name (expense accounts):
}); initExpenseAC();
// do source name (revenue accounts):
initRevenueAC();
if ($('input[name="destination_name"]').length > 0) { // do categories auto complete:
$.getJSON('json/expense-accounts').done(function (data) { initCategoryAC();
$('input[name="destination_name"]').typeahead({source: data, autoSelect: false});
});
}
if ($('input[name="source_name"]').length > 0) {
$.getJSON('json/revenue-accounts').done(function (data) {
$('input[name="source_name"]').typeahead({source: data, autoSelect: false});
});
}
$.getJSON('json/categories').done(function (data) {
$('input[name="category"]').typeahead({source: data, autoSelect: false});
});
} }
/** /**

View File

@ -136,9 +136,31 @@ function getExchangeInstructions() {
* *
*/ */
function updateDescription() { function updateDescription() {
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="description"]').typeahead('destroy').typeahead({source: data, autoSelect: false}); // do description auto complete:
var journalNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/transaction-journals/' + what,
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
}
},
remote: {
url: 'json/transaction-journals/' + what + '?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
journalNames.initialize();
$('input[name="description"]').typeahead('destroy').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
$('#ffInput_description').focus(); $('#ffInput_description').focus();
} }

View File

@ -148,10 +148,32 @@ function getAccountId() {
* Set the auto-complete JSON things. * Set the auto-complete JSON things.
*/ */
function setAutocompletes() { function setAutocompletes() {
$.getJSON('json/transaction-journals/' + what).done(function (data) {
$('input[name="description"]').typeahead({source: data, autoSelect: false}); // do description auto complete:
var journalNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/transaction-journals/' + what,
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
} }
},
remote: {
url: 'json/transaction-journals/' + what + '?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
journalNames.initialize();
$('input[name="description"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
}
/** /**
* This function generates a small helper text to explain the user * This function generates a small helper text to explain the user

View File

@ -21,53 +21,152 @@
/** global: originalSum,originalForeignSum, accounting, what, Modernizr, currencySymbol, foreignCurrencySymbol */ /** global: originalSum,originalForeignSum, accounting, what, Modernizr, currencySymbol, foreignCurrencySymbol */
var destAccounts = {}; var destNames;
var srcAccounts = {}; var sourceNames;
var categories = {}; var categories;
var descriptions = {}; var journalNames;
$(document).ready(function () { $(document).ready(function () {
"use strict"; "use strict";
$('.btn-do-split').click(cloneDivRow); $('.btn-do-split').click(cloneDivRow);
$('.remove-current-split').click(removeDivRow); $('.remove-current-split').click(removeDivRow);
$.getJSON('json/expense-accounts').done(function (data) { // auto complete destination name (expense accounts):
destAccounts = data; destNames = new Bloodhound({
$('input[name$="destination_name]"]').typeahead({source: destAccounts, autoSelect: false}); datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/expense-accounts',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
$.getJSON('json/revenue-accounts').done(function (data) {
srcAccounts = data;
$('input[name$="source_name]"]').typeahead({source: srcAccounts, autoSelect: false});
});
$.getJSON('json/categories').done(function (data) {
categories = data;
$('input[name$="category_name]"]').typeahead({source: categories, autoSelect: false});
});
$.getJSON('json/transaction-journals/' + what).done(function (data) {
descriptions = data;
$('input[name="journal_description"]').typeahead({source: descriptions, autoSelect: false});
$('input[name$="transaction_description]"]').typeahead({source: descriptions, autoSelect: false});
});
$.getJSON('json/tags').done(function (data) {
var opt = {
typeahead: {
source: data,
afterSelect: function () {
this.$element.val("");
},
autoSelect: false
} }
}; },
$('input[name="tags"]').tagsinput( remote: {
opt url: 'json/expense-accounts?search=%QUERY',
); wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
}); });
}
}
});
destNames.initialize();
$('input[name$="destination_name]"]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
// auto complete source name (revenue accounts):
sourceNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/revenue-accounts',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: 'json/revenue-accounts?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
sourceNames.initialize();
$('input[name$="source_name]"]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
// auto complete category fields:
categories = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/categories',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: 'json/categories?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
categories.initialize();
$('input[name$="category_name]"]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
// get transaction journal name things:
journalNames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/transaction-journals/' + what,
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
},
remote: {
url: 'json/transaction-journals/' + what + '?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
journalNames.initialize();
$('input[name="journal_description"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
$('input[name$="transaction_description]"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
// get tags:
console.log('initTagsAC()');
var tagTags = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
prefetch: {
url: 'json/tags',
filter: function (list) {
return $.map(list, function (tagTag) {
return {name: tagTag};
});
}
},
remote: {
url: 'json/tags?search=%QUERY',
wildcard: '%QUERY',
filter: function (list) {
return $.map(list, function (name) {
return {name: name};
});
}
}
});
tagTags.initialize();
$('input[name="tags"]').tagsinput({
typeaheadjs: {
hint: true,
highlight: true,
name: 'tags',
displayKey: 'name',
valueKey: 'name',
source: tagTags.ttAdapter()
}
});
$('input[name$="][amount]"]').on('change', calculateBothSums); $('input[name$="][amount]"]').on('change', calculateBothSums);
$('input[name$="][foreign_amount]"]').on('change', calculateBothSums); $('input[name$="][foreign_amount]"]').on('change', calculateBothSums);
@ -128,18 +227,18 @@ function cloneDivRow() {
source.find('input[name$="][amount]"]').val("").on('change', calculateBothSums); source.find('input[name$="][amount]"]').val("").on('change', calculateBothSums);
source.find('input[name$="][foreign_amount]"]').val("").on('change', calculateBothSums); source.find('input[name$="][foreign_amount]"]').val("").on('change', calculateBothSums);
if (destAccounts.length > 0) { if (destNames) {
source.find('input[name$="destination_name]"]').typeahead({source: destAccounts, autoSelect: false}); source.find('input[name$="destination_name]"]').typeahead({hint: true, highlight: true,}, {source: destNames, displayKey: 'name', autoSelect: false});
} }
if (srcAccounts.length > 0) { if (sourceNames) {
source.find('input[name$="source_name]"]').typeahead({source: srcAccounts, autoSelect: false}); source.find('input[name$="source_name]"]').typeahead({hint: true, highlight: true,}, {source: sourceNames, displayKey: 'name', autoSelect: false});
} }
if (categories.length > 0) { if (categories) {
source.find('input[name$="category_name]"]').typeahead({source: categories, autoSelect: false}); source.find('input[name$="category_name]"]').typeahead({hint: true, highlight: true,}, {source: categories, displayKey: 'name', autoSelect: false});
} }
if (descriptions.length > 0) { if (journalNames) {
source.find('input[name$="transaction_description]"]').typeahead({source: descriptions, autoSelect: false}); source.find('input[name$="transaction_description]"]').typeahead({hint: true, highlight: true,}, {source: journalNames, displayKey: 'name', autoSelect: false});
} }
$('div.split_row_holder').append(source); $('div.split_row_holder').append(source);

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
Options -Indexes

918
public/js/lib/typeahead/bloodhound.js vendored Normal file
View File

@ -0,0 +1,918 @@
/*!
* typeahead.js 0.11.1
* https://github.com/twitter/typeahead.js
* Copyright 2013-2015 Twitter, Inc. and other contributors; Licensed MIT
*/
(function(root, factory) {
if (typeof define === "function" && define.amd) {
define("bloodhound", [ "jquery" ], function(a0) {
return root["Bloodhound"] = factory(a0);
});
} else if (typeof exports === "object") {
module.exports = factory(require("jquery"));
} else {
root["Bloodhound"] = factory(jQuery);
}
})(this, function($) {
var _ = function() {
"use strict";
return {
isMsie: function() {
return /(msie|trident)/i.test(navigator.userAgent) ? navigator.userAgent.match(/(msie |rv:)(\d+(.\d+)?)/i)[2] : false;
},
isBlankString: function(str) {
return !str || /^\s*$/.test(str);
},
escapeRegExChars: function(str) {
return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
},
isString: function(obj) {
return typeof obj === "string";
},
isNumber: function(obj) {
return typeof obj === "number";
},
isArray: $.isArray,
isFunction: $.isFunction,
isObject: $.isPlainObject,
isUndefined: function(obj) {
return typeof obj === "undefined";
},
isElement: function(obj) {
return !!(obj && obj.nodeType === 1);
},
isJQuery: function(obj) {
return obj instanceof $;
},
toStr: function toStr(s) {
return _.isUndefined(s) || s === null ? "" : s + "";
},
bind: $.proxy,
each: function(collection, cb) {
$.each(collection, reverseArgs);
function reverseArgs(index, value) {
return cb(value, index);
}
},
map: $.map,
filter: $.grep,
every: function(obj, test) {
var result = true;
if (!obj) {
return result;
}
$.each(obj, function(key, val) {
if (!(result = test.call(null, val, key, obj))) {
return false;
}
});
return !!result;
},
some: function(obj, test) {
var result = false;
if (!obj) {
return result;
}
$.each(obj, function(key, val) {
if (result = test.call(null, val, key, obj)) {
return false;
}
});
return !!result;
},
mixin: $.extend,
identity: function(x) {
return x;
},
clone: function(obj) {
return $.extend(true, {}, obj);
},
getIdGenerator: function() {
var counter = 0;
return function() {
return counter++;
};
},
templatify: function templatify(obj) {
return $.isFunction(obj) ? obj : template;
function template() {
return String(obj);
}
},
defer: function(fn) {
setTimeout(fn, 0);
},
debounce: function(func, wait, immediate) {
var timeout, result;
return function() {
var context = this, args = arguments, later, callNow;
later = function() {
timeout = null;
if (!immediate) {
result = func.apply(context, args);
}
};
callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
result = func.apply(context, args);
}
return result;
};
},
throttle: function(func, wait) {
var context, args, timeout, result, previous, later;
previous = 0;
later = function() {
previous = new Date();
timeout = null;
result = func.apply(context, args);
};
return function() {
var now = new Date(), remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0) {
clearTimeout(timeout);
timeout = null;
previous = now;
result = func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(later, remaining);
}
return result;
};
},
stringify: function(val) {
return _.isString(val) ? val : JSON.stringify(val);
},
noop: function() {}
};
}();
var VERSION = "0.11.1";
var tokenizers = function() {
"use strict";
return {
nonword: nonword,
whitespace: whitespace,
obj: {
nonword: getObjTokenizer(nonword),
whitespace: getObjTokenizer(whitespace)
}
};
function whitespace(str) {
str = _.toStr(str);
return str ? str.split(/\s+/) : [];
}
function nonword(str) {
str = _.toStr(str);
return str ? str.split(/\W+/) : [];
}
function getObjTokenizer(tokenizer) {
return function setKey(keys) {
keys = _.isArray(keys) ? keys : [].slice.call(arguments, 0);
return function tokenize(o) {
var tokens = [];
_.each(keys, function(k) {
tokens = tokens.concat(tokenizer(_.toStr(o[k])));
});
return tokens;
};
};
}
}();
var LruCache = function() {
"use strict";
function LruCache(maxSize) {
this.maxSize = _.isNumber(maxSize) ? maxSize : 100;
this.reset();
if (this.maxSize <= 0) {
this.set = this.get = $.noop;
}
}
_.mixin(LruCache.prototype, {
set: function set(key, val) {
var tailItem = this.list.tail, node;
if (this.size >= this.maxSize) {
this.list.remove(tailItem);
delete this.hash[tailItem.key];
this.size--;
}
if (node = this.hash[key]) {
node.val = val;
this.list.moveToFront(node);
} else {
node = new Node(key, val);
this.list.add(node);
this.hash[key] = node;
this.size++;
}
},
get: function get(key) {
var node = this.hash[key];
if (node) {
this.list.moveToFront(node);
return node.val;
}
},
reset: function reset() {
this.size = 0;
this.hash = {};
this.list = new List();
}
});
function List() {
this.head = this.tail = null;
}
_.mixin(List.prototype, {
add: function add(node) {
if (this.head) {
node.next = this.head;
this.head.prev = node;
}
this.head = node;
this.tail = this.tail || node;
},
remove: function remove(node) {
node.prev ? node.prev.next = node.next : this.head = node.next;
node.next ? node.next.prev = node.prev : this.tail = node.prev;
},
moveToFront: function(node) {
this.remove(node);
this.add(node);
}
});
function Node(key, val) {
this.key = key;
this.val = val;
this.prev = this.next = null;
}
return LruCache;
}();
var PersistentStorage = function() {
"use strict";
var LOCAL_STORAGE;
try {
LOCAL_STORAGE = window.localStorage;
LOCAL_STORAGE.setItem("~~~", "!");
LOCAL_STORAGE.removeItem("~~~");
} catch (err) {
LOCAL_STORAGE = null;
}
function PersistentStorage(namespace, override) {
this.prefix = [ "__", namespace, "__" ].join("");
this.ttlKey = "__ttl__";
this.keyMatcher = new RegExp("^" + _.escapeRegExChars(this.prefix));
this.ls = override || LOCAL_STORAGE;
!this.ls && this._noop();
}
_.mixin(PersistentStorage.prototype, {
_prefix: function(key) {
return this.prefix + key;
},
_ttlKey: function(key) {
return this._prefix(key) + this.ttlKey;
},
_noop: function() {
this.get = this.set = this.remove = this.clear = this.isExpired = _.noop;
},
_safeSet: function(key, val) {
try {
this.ls.setItem(key, val);
} catch (err) {
if (err.name === "QuotaExceededError") {
this.clear();
this._noop();
}
}
},
get: function(key) {
if (this.isExpired(key)) {
this.remove(key);
}
return decode(this.ls.getItem(this._prefix(key)));
},
set: function(key, val, ttl) {
if (_.isNumber(ttl)) {
this._safeSet(this._ttlKey(key), encode(now() + ttl));
} else {
this.ls.removeItem(this._ttlKey(key));
}
return this._safeSet(this._prefix(key), encode(val));
},
remove: function(key) {
this.ls.removeItem(this._ttlKey(key));
this.ls.removeItem(this._prefix(key));
return this;
},
clear: function() {
var i, keys = gatherMatchingKeys(this.keyMatcher);
for (i = keys.length; i--; ) {
this.remove(keys[i]);
}
return this;
},
isExpired: function(key) {
var ttl = decode(this.ls.getItem(this._ttlKey(key)));
return _.isNumber(ttl) && now() > ttl ? true : false;
}
});
return PersistentStorage;
function now() {
return new Date().getTime();
}
function encode(val) {
return JSON.stringify(_.isUndefined(val) ? null : val);
}
function decode(val) {
return $.parseJSON(val);
}
function gatherMatchingKeys(keyMatcher) {
var i, key, keys = [], len = LOCAL_STORAGE.length;
for (i = 0; i < len; i++) {
if ((key = LOCAL_STORAGE.key(i)).match(keyMatcher)) {
keys.push(key.replace(keyMatcher, ""));
}
}
return keys;
}
}();
var Transport = function() {
"use strict";
var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests = 6, sharedCache = new LruCache(10);
function Transport(o) {
o = o || {};
this.cancelled = false;
this.lastReq = null;
this._send = o.transport;
this._get = o.limiter ? o.limiter(this._get) : this._get;
this._cache = o.cache === false ? new LruCache(0) : sharedCache;
}
Transport.setMaxPendingRequests = function setMaxPendingRequests(num) {
maxPendingRequests = num;
};
Transport.resetCache = function resetCache() {
sharedCache.reset();
};
_.mixin(Transport.prototype, {
_fingerprint: function fingerprint(o) {
o = o || {};
return o.url + o.type + $.param(o.data || {});
},
_get: function(o, cb) {
var that = this, fingerprint, jqXhr;
fingerprint = this._fingerprint(o);
if (this.cancelled || fingerprint !== this.lastReq) {
return;
}
if (jqXhr = pendingRequests[fingerprint]) {
jqXhr.done(done).fail(fail);
} else if (pendingRequestsCount < maxPendingRequests) {
pendingRequestsCount++;
pendingRequests[fingerprint] = this._send(o).done(done).fail(fail).always(always);
} else {
this.onDeckRequestArgs = [].slice.call(arguments, 0);
}
function done(resp) {
cb(null, resp);
that._cache.set(fingerprint, resp);
}
function fail() {
cb(true);
}
function always() {
pendingRequestsCount--;
delete pendingRequests[fingerprint];
if (that.onDeckRequestArgs) {
that._get.apply(that, that.onDeckRequestArgs);
that.onDeckRequestArgs = null;
}
}
},
get: function(o, cb) {
var resp, fingerprint;
cb = cb || $.noop;
o = _.isString(o) ? {
url: o
} : o || {};
fingerprint = this._fingerprint(o);
this.cancelled = false;
this.lastReq = fingerprint;
if (resp = this._cache.get(fingerprint)) {
cb(null, resp);
} else {
this._get(o, cb);
}
},
cancel: function() {
this.cancelled = true;
}
});
return Transport;
}();
var SearchIndex = window.SearchIndex = function() {
"use strict";
var CHILDREN = "c", IDS = "i";
function SearchIndex(o) {
o = o || {};
if (!o.datumTokenizer || !o.queryTokenizer) {
$.error("datumTokenizer and queryTokenizer are both required");
}
this.identify = o.identify || _.stringify;
this.datumTokenizer = o.datumTokenizer;
this.queryTokenizer = o.queryTokenizer;
this.reset();
}
_.mixin(SearchIndex.prototype, {
bootstrap: function bootstrap(o) {
this.datums = o.datums;
this.trie = o.trie;
},
add: function(data) {
var that = this;
data = _.isArray(data) ? data : [ data ];
_.each(data, function(datum) {
var id, tokens;
that.datums[id = that.identify(datum)] = datum;
tokens = normalizeTokens(that.datumTokenizer(datum));
_.each(tokens, function(token) {
var node, chars, ch;
node = that.trie;
chars = token.split("");
while (ch = chars.shift()) {
node = node[CHILDREN][ch] || (node[CHILDREN][ch] = newNode());
node[IDS].push(id);
}
});
});
},
get: function get(ids) {
var that = this;
return _.map(ids, function(id) {
return that.datums[id];
});
},
search: function search(query) {
var that = this, tokens, matches;
tokens = normalizeTokens(this.queryTokenizer(query));
_.each(tokens, function(token) {
var node, chars, ch, ids;
if (matches && matches.length === 0) {
return false;
}
node = that.trie;
chars = token.split("");
while (node && (ch = chars.shift())) {
node = node[CHILDREN][ch];
}
if (node && chars.length === 0) {
ids = node[IDS].slice(0);
matches = matches ? getIntersection(matches, ids) : ids;
} else {
matches = [];
return false;
}
});
return matches ? _.map(unique(matches), function(id) {
return that.datums[id];
}) : [];
},
all: function all() {
var values = [];
for (var key in this.datums) {
values.push(this.datums[key]);
}
return values;
},
reset: function reset() {
this.datums = {};
this.trie = newNode();
},
serialize: function serialize() {
return {
datums: this.datums,
trie: this.trie
};
}
});
return SearchIndex;
function normalizeTokens(tokens) {
tokens = _.filter(tokens, function(token) {
return !!token;
});
tokens = _.map(tokens, function(token) {
return token.toLowerCase();
});
return tokens;
}
function newNode() {
var node = {};
node[IDS] = [];
node[CHILDREN] = {};
return node;
}
function unique(array) {
var seen = {}, uniques = [];
for (var i = 0, len = array.length; i < len; i++) {
if (!seen[array[i]]) {
seen[array[i]] = true;
uniques.push(array[i]);
}
}
return uniques;
}
function getIntersection(arrayA, arrayB) {
var ai = 0, bi = 0, intersection = [];
arrayA = arrayA.sort();
arrayB = arrayB.sort();
var lenArrayA = arrayA.length, lenArrayB = arrayB.length;
while (ai < lenArrayA && bi < lenArrayB) {
if (arrayA[ai] < arrayB[bi]) {
ai++;
} else if (arrayA[ai] > arrayB[bi]) {
bi++;
} else {
intersection.push(arrayA[ai]);
ai++;
bi++;
}
}
return intersection;
}
}();
var Prefetch = function() {
"use strict";
var keys;
keys = {
data: "data",
protocol: "protocol",
thumbprint: "thumbprint"
};
function Prefetch(o) {
this.url = o.url;
this.ttl = o.ttl;
this.cache = o.cache;
this.prepare = o.prepare;
this.transform = o.transform;
this.transport = o.transport;
this.thumbprint = o.thumbprint;
this.storage = new PersistentStorage(o.cacheKey);
}
_.mixin(Prefetch.prototype, {
_settings: function settings() {
return {
url: this.url,
type: "GET",
dataType: "json"
};
},
store: function store(data) {
if (!this.cache) {
return;
}
this.storage.set(keys.data, data, this.ttl);
this.storage.set(keys.protocol, location.protocol, this.ttl);
this.storage.set(keys.thumbprint, this.thumbprint, this.ttl);
},
fromCache: function fromCache() {
var stored = {}, isExpired;
if (!this.cache) {
return null;
}
stored.data = this.storage.get(keys.data);
stored.protocol = this.storage.get(keys.protocol);
stored.thumbprint = this.storage.get(keys.thumbprint);
isExpired = stored.thumbprint !== this.thumbprint || stored.protocol !== location.protocol;
return stored.data && !isExpired ? stored.data : null;
},
fromNetwork: function(cb) {
var that = this, settings;
if (!cb) {
return;
}
settings = this.prepare(this._settings());
this.transport(settings).fail(onError).done(onResponse);
function onError() {
cb(true);
}
function onResponse(resp) {
cb(null, that.transform(resp));
}
},
clear: function clear() {
this.storage.clear();
return this;
}
});
return Prefetch;
}();
var Remote = function() {
"use strict";
function Remote(o) {
this.url = o.url;
this.prepare = o.prepare;
this.transform = o.transform;
this.transport = new Transport({
cache: o.cache,
limiter: o.limiter,
transport: o.transport
});
}
_.mixin(Remote.prototype, {
_settings: function settings() {
return {
url: this.url,
type: "GET",
dataType: "json"
};
},
get: function get(query, cb) {
var that = this, settings;
if (!cb) {
return;
}
query = query || "";
settings = this.prepare(query, this._settings());
return this.transport.get(settings, onResponse);
function onResponse(err, resp) {
err ? cb([]) : cb(that.transform(resp));
}
},
cancelLastRequest: function cancelLastRequest() {
this.transport.cancel();
}
});
return Remote;
}();
var oParser = function() {
"use strict";
return function parse(o) {
var defaults, sorter;
defaults = {
initialize: true,
identify: _.stringify,
datumTokenizer: null,
queryTokenizer: null,
sufficient: 5,
sorter: null,
local: [],
prefetch: null,
remote: null
};
o = _.mixin(defaults, o || {});
!o.datumTokenizer && $.error("datumTokenizer is required");
!o.queryTokenizer && $.error("queryTokenizer is required");
sorter = o.sorter;
o.sorter = sorter ? function(x) {
return x.sort(sorter);
} : _.identity;
o.local = _.isFunction(o.local) ? o.local() : o.local;
o.prefetch = parsePrefetch(o.prefetch);
o.remote = parseRemote(o.remote);
return o;
};
function parsePrefetch(o) {
var defaults;
if (!o) {
return null;
}
defaults = {
url: null,
ttl: 24 * 60 * 60 * 1e3,
cache: true,
cacheKey: null,
thumbprint: "",
prepare: _.identity,
transform: _.identity,
transport: null
};
o = _.isString(o) ? {
url: o
} : o;
o = _.mixin(defaults, o);
!o.url && $.error("prefetch requires url to be set");
o.transform = o.filter || o.transform;
o.cacheKey = o.cacheKey || o.url;
o.thumbprint = VERSION + o.thumbprint;
o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
return o;
}
function parseRemote(o) {
var defaults;
if (!o) {
return;
}
defaults = {
url: null,
cache: true,
prepare: null,
replace: null,
wildcard: null,
limiter: null,
rateLimitBy: "debounce",
rateLimitWait: 300,
transform: _.identity,
transport: null
};
o = _.isString(o) ? {
url: o
} : o;
o = _.mixin(defaults, o);
!o.url && $.error("remote requires url to be set");
o.transform = o.filter || o.transform;
o.prepare = toRemotePrepare(o);
o.limiter = toLimiter(o);
o.transport = o.transport ? callbackToDeferred(o.transport) : $.ajax;
delete o.replace;
delete o.wildcard;
delete o.rateLimitBy;
delete o.rateLimitWait;
return o;
}
function toRemotePrepare(o) {
var prepare, replace, wildcard;
prepare = o.prepare;
replace = o.replace;
wildcard = o.wildcard;
if (prepare) {
return prepare;
}
if (replace) {
prepare = prepareByReplace;
} else if (o.wildcard) {
prepare = prepareByWildcard;
} else {
prepare = idenityPrepare;
}
return prepare;
function prepareByReplace(query, settings) {
settings.url = replace(settings.url, query);
return settings;
}
function prepareByWildcard(query, settings) {
settings.url = settings.url.replace(wildcard, encodeURIComponent(query));
return settings;
}
function idenityPrepare(query, settings) {
return settings;
}
}
function toLimiter(o) {
var limiter, method, wait;
limiter = o.limiter;
method = o.rateLimitBy;
wait = o.rateLimitWait;
if (!limiter) {
limiter = /^throttle$/i.test(method) ? throttle(wait) : debounce(wait);
}
return limiter;
function debounce(wait) {
return function debounce(fn) {
return _.debounce(fn, wait);
};
}
function throttle(wait) {
return function throttle(fn) {
return _.throttle(fn, wait);
};
}
}
function callbackToDeferred(fn) {
return function wrapper(o) {
var deferred = $.Deferred();
fn(o, onSuccess, onError);
return deferred;
function onSuccess(resp) {
_.defer(function() {
deferred.resolve(resp);
});
}
function onError(err) {
_.defer(function() {
deferred.reject(err);
});
}
};
}
}();
var Bloodhound = function() {
"use strict";
var old;
old = window && window.Bloodhound;
function Bloodhound(o) {
o = oParser(o);
this.sorter = o.sorter;
this.identify = o.identify;
this.sufficient = o.sufficient;
this.local = o.local;
this.remote = o.remote ? new Remote(o.remote) : null;
this.prefetch = o.prefetch ? new Prefetch(o.prefetch) : null;
this.index = new SearchIndex({
identify: this.identify,
datumTokenizer: o.datumTokenizer,
queryTokenizer: o.queryTokenizer
});
o.initialize !== false && this.initialize();
}
Bloodhound.noConflict = function noConflict() {
window && (window.Bloodhound = old);
return Bloodhound;
};
Bloodhound.tokenizers = tokenizers;
_.mixin(Bloodhound.prototype, {
__ttAdapter: function ttAdapter() {
var that = this;
return this.remote ? withAsync : withoutAsync;
function withAsync(query, sync, async) {
return that.search(query, sync, async);
}
function withoutAsync(query, sync) {
return that.search(query, sync);
}
},
_loadPrefetch: function loadPrefetch() {
var that = this, deferred, serialized;
deferred = $.Deferred();
if (!this.prefetch) {
deferred.resolve();
} else if (serialized = this.prefetch.fromCache()) {
this.index.bootstrap(serialized);
deferred.resolve();
} else {
this.prefetch.fromNetwork(done);
}
return deferred.promise();
function done(err, data) {
if (err) {
return deferred.reject();
}
that.add(data);
that.prefetch.store(that.index.serialize());
deferred.resolve();
}
},
_initialize: function initialize() {
var that = this, deferred;
this.clear();
(this.initPromise = this._loadPrefetch()).done(addLocalToIndex);
return this.initPromise;
function addLocalToIndex() {
that.add(that.local);
}
},
initialize: function initialize(force) {
return !this.initPromise || force ? this._initialize() : this.initPromise;
},
add: function add(data) {
this.index.add(data);
return this;
},
get: function get(ids) {
ids = _.isArray(ids) ? ids : [].slice.call(arguments);
return this.index.get(ids);
},
search: function search(query, sync, async) {
var that = this, local;
local = this.sorter(this.index.search(query));
sync(this.remote ? local.slice() : local);
if (this.remote && local.length < this.sufficient) {
this.remote.get(query, processRemote);
} else if (this.remote) {
this.remote.cancelLastRequest();
}
return this;
function processRemote(remote) {
var nonDuplicates = [];
_.each(remote, function(r) {
!_.some(local, function(l) {
return that.identify(r) === that.identify(l);
}) && nonDuplicates.push(r);
});
async && async(nonDuplicates);
}
},
all: function all() {
return this.index.all();
},
clear: function clear() {
this.index.reset();
return this;
},
clearPrefetchCache: function clearPrefetchCache() {
this.prefetch && this.prefetch.clear();
return this;
},
clearRemoteCache: function clearRemoteCache() {
Transport.resetCache();
return this;
},
ttAdapter: function ttAdapter() {
return this.__ttAdapter();
}
});
return Bloodhound;
}();
return Bloodhound;
});

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -96,7 +96,8 @@
<script type="text/javascript"> <script type="text/javascript">
var what = "{{ what }}"; var what = "{{ what }}";
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>

View File

@ -7,9 +7,18 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'> <meta content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no' name='viewport'>
<base href="{{ route('index') }}/"> <base href="{{ route('index') }}/">
<link rel="stylesheet" href="css/app.css?v={{ FF_VERSION }}" type="text/css" media="all"/>
{# libraries #}
<link href="lib/bs/css/bootstrap.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
<link href="lib/fa/css/font-awesome.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
{# the theme #}
<link href="lib/adminlte/css/AdminLTE.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/> <link href="lib/adminlte/css/AdminLTE.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
<link href="lib/adminlte/css/skins/skin-blue-light.min.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
{# Firefly III customisations #}
<link href="css/firefly.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/> <link href="css/firefly.css?v={{ FF_VERSION }}" rel="stylesheet" type="text/css"/>
{% include('partials.favicons') %} {% include('partials.favicons') %}
</head> </head>
<body class="ff-error-page"> <body class="ff-error-page">

View File

@ -194,7 +194,8 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="lib/fc/fullcalendar.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="lib/fc/fullcalendar.min.js?v={{ FF_VERSION }}"></script>

View File

@ -215,7 +215,8 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="lib/fc/fullcalendar.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="lib/fc/fullcalendar.min.js?v={{ FF_VERSION }}"></script>

View File

@ -145,7 +145,7 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript"> <script type="text/javascript">
var triggerCount = {{ triggerCount }}; var triggerCount = {{ triggerCount }};
var actionCount = {{ actionCount }}; var actionCount = {{ actionCount }};

View File

@ -128,7 +128,7 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript"> <script type="text/javascript">
var triggerCount = {{ triggerCount }}; var triggerCount = {{ triggerCount }};
var actionCount = {{ actionCount }}; var actionCount = {{ actionCount }};

View File

@ -128,7 +128,8 @@
<script type="text/javascript"> <script type="text/javascript">
var what = ""; var what = "";
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/transactions/mass/edit-bulk.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/ff/transactions/mass/edit-bulk.js?v={{ FF_VERSION }}"></script>
{% endblock %} {% endblock %}

View File

@ -215,10 +215,7 @@
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
{% endblock %} <script type="text/javascript" src="js/ff/transactions/convert.js?v={{ FF_VERSION }}"></script>
{% block styles %}
<link href="css/bootstrap-tagsinput.css?v={{ FF_VERSION }}" type="text/css" rel="stylesheet" media="all">
{% endblock %} {% endblock %}

View File

@ -136,6 +136,7 @@
<script type="text/javascript"> <script type="text/javascript">
var what = ""; var what = "";
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/transactions/mass/edit.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/ff/transactions/mass/edit.js?v={{ FF_VERSION }}"></script>
{% endblock %} {% endblock %}

View File

@ -463,6 +463,6 @@
<script type="text/javascript"> <script type="text/javascript">
var autoCompleteUri = "{{ route('json.journals-with-id',[journal.id]) }}"; var autoCompleteUri = "{{ route('json.journals-with-id',[journal.id]) }}";
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/transactions/show.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/ff/transactions/show.js?v={{ FF_VERSION }}"></script>
{% endblock %} {% endblock %}

View File

@ -240,8 +240,11 @@
var overruleCurrency = {{ preFilled.amount_currency_id_amount|default(0) }}; var overruleCurrency = {{ preFilled.amount_currency_id_amount|default(0) }};
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="jscript/accounts?ext=.js&amp;v={{ FF_VERSION }}"></script> <script type="text/javascript" src="jscript/accounts?ext=.js&amp;v={{ FF_VERSION }}"></script>

View File

@ -248,7 +248,8 @@
<script type="text/javascript"> <script type="text/javascript">
var what = "{{ what }}"; var what = "{{ what }}";
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>

View File

@ -328,7 +328,8 @@
var originalForeignSum = {{ preFilled.journal_foreign_amount }}; var originalForeignSum = {{ preFilled.journal_foreign_amount }};
var what = "{{ preFilled.what }}"; var what = "{{ preFilled.what }}";
</script> </script>
<script type="text/javascript" src="js/lib/bootstrap3-typeahead.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/typeahead/typeahead.bundle.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/ff/common/autocomplete.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/bootstrap-tagsinput.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/jquery-ui.min.js?v={{ FF_VERSION }}"></script>
<script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script> <script type="text/javascript" src="js/lib/modernizr-custom.js?v={{ FF_VERSION }}"></script>

View File

@ -75,7 +75,7 @@
<div class="buttons"> <div class="buttons">
<!-- Authorize Button --> <!-- Authorize Button -->
<form method="post" action="/oauth/authorize"> <form method="post" action="{{ route('index') }}/oauth/authorize">
{{ csrf_field() }} {{ csrf_field() }}
<input type="hidden" name="state" value="{{ request.state }}"> <input type="hidden" name="state" value="{{ request.state }}">
@ -84,7 +84,7 @@
</form> </form>
<!-- Cancel Button --> <!-- Cancel Button -->
<form method="post" action="/oauth/authorize"> <form method="post" action="{{ route('index') }}/oauth/authorize">
{{ csrf_field() }} {{ csrf_field() }}
{{ method_field('DELETE') }} {{ method_field('DELETE') }}

View File

@ -73,7 +73,6 @@ class CreateControllerTest extends TestCase
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
$this->be($this->user()); $this->be($this->user());
$response = $this->get(route('accounts.create', ['asset'])); $response = $this->get(route('accounts.create', ['asset']));

View File

@ -86,7 +86,6 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
$this->be($this->user()); $this->be($this->user());
@ -131,7 +130,6 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
$this->be($this->user()); $this->be($this->user());
@ -178,7 +176,6 @@ class EditControllerTest extends TestCase
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Debt'])->andReturn(AccountType::find(11))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Loan'])->andReturn(AccountType::find(9))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once(); $accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Mortgage'])->andReturn(AccountType::find(12))->once();
$accountRepos->shouldReceive('getAccountTypeByType')->withArgs(['Credit card'])->andReturn(AccountType::find(13))->once();
$this->be($this->user()); $this->be($this->user());
$account = $this->user()->accounts()->where('account_type_id', 3)->whereNull('deleted_at')->first(); $account = $this->user()->accounts()->where('account_type_id', 3)->whereNull('deleted_at')->first();

View File

@ -81,7 +81,7 @@ class UserEventHandlerTest extends TestCase
{ {
$repository = $this->mock(UserRepositoryInterface::class); $repository = $this->mock(UserRepositoryInterface::class);
$user = $this->user(); $user = $this->user();
$event = new Login($user, true); $event = new Login(null, $user, true);
$listener = new UserEventHandler(); $listener = new UserEventHandler();
// mock stuff // mock stuff
@ -99,7 +99,7 @@ class UserEventHandlerTest extends TestCase
{ {
$repository = $this->mock(UserRepositoryInterface::class); $repository = $this->mock(UserRepositoryInterface::class);
$user = $this->emptyUser(); $user = $this->emptyUser();
$event = new Login($user, true); $event = new Login(null, $user, true);
$listener = new UserEventHandler(); $listener = new UserEventHandler();
// mock stuff // mock stuff
@ -121,7 +121,7 @@ class UserEventHandlerTest extends TestCase
{ {
$repository = $this->mock(UserRepositoryInterface::class); $repository = $this->mock(UserRepositoryInterface::class);
$user = $this->emptyUser(); $user = $this->emptyUser();
$event = new Login($user, true); $event = new Login(null, $user, true);
$listener = new UserEventHandler(); $listener = new UserEventHandler();
// mock stuff // mock stuff
@ -141,7 +141,7 @@ class UserEventHandlerTest extends TestCase
{ {
$repository = $this->mock(UserRepositoryInterface::class); $repository = $this->mock(UserRepositoryInterface::class);
$user = $this->user(); $user = $this->user();
$event = new Login($user, true); $event = new Login(null, $user, true);
$listener = new UserEventHandler(); $listener = new UserEventHandler();
// mock stuff // mock stuff
@ -159,7 +159,7 @@ class UserEventHandlerTest extends TestCase
{ {
$repository = $this->mock(UserRepositoryInterface::class); $repository = $this->mock(UserRepositoryInterface::class);
$user = $this->emptyUser(); $user = $this->emptyUser();
$event = new Login($user, true); $event = new Login(null, $user, true);
$listener = new UserEventHandler(); $listener = new UserEventHandler();
// mock stuff // mock stuff