Lots of new code for importer and some preferences.

This commit is contained in:
James Cole 2016-07-24 18:47:55 +02:00
parent 87c0f1d86e
commit 1392275b81
41 changed files with 1562 additions and 369 deletions

View File

@ -14,8 +14,11 @@ namespace FireflyIII\Http\Controllers\Admin;
use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Repositories\User\UserRepositoryInterface;
use FireflyIII\Support\Facades\FireflyConfig;
use FireflyIII\User;
use Illuminate\Http\Request;
use Preferences;
use Session;
/**
* Class UserController
@ -24,8 +27,29 @@ use Preferences;
*/
class UserController extends Controller
{
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function domains()
{
$title = strval(trans('firefly.administration'));
$mainTitleIcon = 'fa-hand-spock-o';
$subTitle = strval(trans('firefly.blocked_domains'));
$subTitleIcon = 'fa-users';
$domains = FireflyConfig::get('blocked-domains', [])->data;
// known domains
$knownDomains = $this->getKnownDomains();
return view('admin.users.domains', compact('title', 'mainTitleIcon', 'knownDomains', 'subTitle', 'subTitleIcon', 'domains'));
}
/**
* @param UserRepositoryInterface $repository
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index(UserRepositoryInterface $repository)
{
@ -61,4 +85,92 @@ class UserController extends Controller
}
/**
* @param Request $request
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function manual(Request $request)
{
if (strlen($request->get('domain')) === 0) {
Session::flash('error', trans('firefly.no_domain_filled_in'));
return redirect(route('admin.users.domains'));
}
$domain = $request->get('domain');
$blocked = FireflyConfig::get('blocked-domains', [])->data;
if (in_array($domain, $blocked)) {
Session::flash('error', trans('firefly.domain_already_blocked', ['domain' => $domain]));
return redirect(route('admin.users.domains'));
}
$blocked[] = $domain;
FireflyConfig::set('blocked-domains', $blocked);
Session::flash('success', trans('firefly.domain_is_now_blocked', ['domain' => $domain]));
return redirect(route('admin.users.domains'));
}
/**
* @param string $domain
*
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
*/
public function toggleDomain(string $domain)
{
$blocked = FireflyConfig::get('blocked-domains', [])->data;
if (in_array($domain, $blocked)) {
$key = array_search($domain, $blocked);
unset($blocked[$key]);
sort($blocked);
FireflyConfig::set('blocked-domains', $blocked);
Session::flash('message', trans('firefly.domain_now_unblocked', ['domain' => $domain]));
return redirect(route('admin.users.domains'));
}
$blocked[] = $domain;
FireflyConfig::set('blocked-domains', $blocked);
Session::flash('message', trans('firefly.domain_now_blocked', ['domain' => $domain]));
return redirect(route('admin.users.domains'));
}
/**
* @return array
*/
private function getKnownDomains(): array
{
$users = User::get();
$set = [];
$filtered = [];
/** @var User $user */
foreach ($users as $user) {
$email = $user->email;
$parts = explode('@', $email);
$domain = $parts[1];
$set[] = $domain;
}
$set = array_unique($set);
// filter for already banned domains:
$blocked = FireflyConfig::get('blocked-domains', [])->data;
foreach ($set as $domain) {
// in the block array? ignore it.
if (!in_array($domain, $blocked)) {
$filtered[] = $domain;
}
}
asort($filtered);
return $filtered;
}
}

View File

@ -96,6 +96,23 @@ Breadcrumbs::register(
}
);
/**
* ADMIN
*/
Breadcrumbs::register(
'admin.index', function (BreadCrumbGenerator $breadcrumbs) {
$breadcrumbs->parent('home');
$breadcrumbs->push(trans('firefly.administration'), route('admin.index'));
}
);
Breadcrumbs::register(
'admin.users', function (BreadCrumbGenerator $breadcrumbs) {
$breadcrumbs->parent('admin.index');
$breadcrumbs->push(trans('firefly.list_all_users'), route('admin.users'));
}
);
/**
* ATTACHMENTS
*/

View File

@ -424,6 +424,10 @@ Route::group(
// user manager
Route::get('/admin/users', ['uses' => 'Admin\UserController@index', 'as' => 'admin.users']);
Route::get('/admin/users/domains', ['uses' => 'Admin\UserController@domains', 'as' => 'admin.users.domains']);
Route::get('/admin/users/domains/toggle/{domain}', ['uses' => 'Admin\UserController@toggleDomain', 'as' => 'admin.users.domains.block-toggle']);
Route::post('/admin/users/domains/manual', ['uses' => 'Admin\UserController@manual', 'as' => 'admin.users.domains.manual']);
}
);

View File

@ -1,6 +1,6 @@
<?php
/**
* AssetAccountId.php
* AccountId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
@ -16,11 +16,11 @@ use FireflyIII\Models\Account;
use Log;
/**
* Class AssetAccountId
* Class AccountId
*
* @package FireflyIII\Import\Converter
*/
class AssetAccountId extends BasicConverter implements ConverterInterface
class AccountId extends BasicConverter implements ConverterInterface
{
/**

View File

@ -21,6 +21,8 @@ use FireflyIII\User;
*/
class BasicConverter
{
/** @var int */
public $certainty = 50;
/** @var array */
public $config;
/** @var bool */
@ -30,6 +32,14 @@ class BasicConverter
/** @var User */
public $user;
/**
* @return int
*/
public function getCertainty():int
{
return $this->certainty;
}
/**
* @param array $config
*/

View File

@ -12,6 +12,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Log;
/**
* Class BudgetId
@ -24,11 +27,40 @@ class BudgetId extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Budget
*/
public function convert($value)
{
throw new FireflyException('Importer with name BudgetId has not yet been configured.');
$value = intval(trim($value));
Log::debug('Going to convert using BudgetId', ['value' => $value]);
if ($value === 0) {
return new Budget;
}
/** @var BudgetRepositoryInterface $repository */
$repository = app(BudgetRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found budget in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$budget = $repository->find(intval($this->mapping[$value]));
if (!is_null($budget->id)) {
Log::debug('Found budget by ID', ['id' => $budget->id]);
return $budget;
}
}
// not mapped? Still try to find it first:
$budget = $repository->find($value);
if (!is_null($budget->id)) {
Log::debug('Found budget by ID ', ['id' => $budget->id]);
return $budget;
}
// should not really happen. If the ID does not match FF, what is FF supposed to do?
return new Budget;
}
}

View File

@ -12,6 +12,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Budget;
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
use Log;
/**
* Class BudgetName
@ -24,11 +27,47 @@ class BudgetName extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Budget
*/
public function convert($value)
{
throw new FireflyException('Importer with name BudgetName has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using BudgetName', ['value' => $value]);
if (strlen($value) === 0) {
return new Budget;
}
/** @var BudgetRepositoryInterface $repository */
$repository = app(BudgetRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found budget in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$budget = $repository->find(intval($this->mapping[$value]));
if (!is_null($budget->id)) {
Log::debug('Found budget by ID', ['id' => $budget->id]);
return $budget;
}
}
// not mapped? Still try to find it first:
$budget = $repository->findByName($value);
if (!is_null($budget->id)) {
Log::debug('Found budget by name ', ['id' => $budget->id]);
return $budget;
}
// create new budget. Use a lot of made up values.
$budget = $repository->store(
[
'name' => $value,
'user_id' => $this->user->id,
]
);
return $budget;
}
}

View File

@ -12,6 +12,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use Log;
/**
* Class CategoryId
@ -24,11 +27,40 @@ class CategoryId extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Category
*/
public function convert($value)
{
throw new FireflyException('Importer with name CategoryId has not yet been configured.');
$value = intval(trim($value));
Log::debug('Going to convert using CategoryId', ['value' => $value]);
if ($value === 0) {
return new Category;
}
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found category in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$category = $repository->find(intval($this->mapping[$value]));
if (!is_null($category->id)) {
Log::debug('Found category by ID', ['id' => $category->id]);
return $category;
}
}
// not mapped? Still try to find it first:
$category = $repository->find($value);
if (!is_null($category->id)) {
Log::debug('Found category by ID ', ['id' => $category->id]);
return $category;
}
// should not really happen. If the ID does not match FF, what is FF supposed to do?
return new Category;
}
}

View File

@ -12,6 +12,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Category;
use FireflyIII\Repositories\Category\CategoryRepositoryInterface;
use Log;
/**
* Class CategoryName
@ -24,11 +27,47 @@ class CategoryName extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Category
*/
public function convert($value)
{
throw new FireflyException('Importer with name CategoryName has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using CategoryName', ['value' => $value]);
if (strlen($value) === 0) {
return new Category;
}
/** @var CategoryRepositoryInterface $repository */
$repository = app(CategoryRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found category in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$category = $repository->find(intval($this->mapping[$value]));
if (!is_null($category->id)) {
Log::debug('Found category by ID', ['id' => $category->id]);
return $category;
}
}
// not mapped? Still try to find it first:
$category = $repository->findByName($value);
if (!is_null($category->id)) {
Log::debug('Found category by name ', ['id' => $category->id]);
return $category;
}
// create new category. Use a lot of made up values.
$category = $repository->store(
[
'name' => $value,
'user_id' => $this->user->id,
]
);
return $category;
}
}

View File

@ -31,6 +31,11 @@ interface ConverterInterface
*/
public function setConfig(array $config);
/**
* @return int
*/
public function getCertainty(): int;
/**
* @param bool $doMap
*/

View File

@ -12,6 +12,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Log;
/**
* Class CurrencyId
@ -24,11 +27,40 @@ class CurrencyId extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return TransactionCurrency
*/
public function convert($value)
{
throw new FireflyException('Importer with name CurrencyId has not yet been configured.');
$value = intval(trim($value));
Log::debug('Going to convert using CurrencyId', ['value' => $value]);
if ($value === 0) {
return new TransactionCurrency;
}
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$currency = $repository->find(intval($this->mapping[$value]));
if (!is_null($currency->id)) {
Log::debug('Found currency by ID', ['id' => $currency->id]);
return $currency;
}
}
// not mapped? Still try to find it first:
$currency = $repository->find($value);
if (!is_null($currency->id)) {
Log::debug('Found currency by ID ', ['id' => $currency->id]);
return $currency;
}
// should not really happen. If the ID does not match FF, what is FF supposed to do?
return new TransactionCurrency;
}
}

View File

@ -11,7 +11,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Log;
/**
* Class CurrencyName
@ -24,11 +26,48 @@ class CurrencyName extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return TransactionCurrency
*/
public function convert($value)
{
throw new FireflyException('Importer with name CurrencyName has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using CurrencyName', ['value' => $value]);
if ($value === 0) {
return new TransactionCurrency;
}
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$currency = $repository->find(intval($this->mapping[$value]));
if (!is_null($currency->id)) {
Log::debug('Found currency by ID', ['id' => $currency->id]);
return $currency;
}
}
// not mapped? Still try to find it first:
$currency = $repository->findByName($value);
if (!is_null($currency->id)) {
Log::debug('Found currency by name ', ['id' => $currency->id]);
return $currency;
}
// create new currency
$currency = $repository->store(
[
'name' => $value,
'code' => strtoupper(substr($value, 0, 3)),
'symbol' => strtoupper(substr($value, 0, 1)),
]
);
return $currency;
}
}

View File

@ -11,7 +11,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionCurrency;
use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface;
use Log;
/**
* Class CurrencySymbol
@ -24,11 +26,48 @@ class CurrencySymbol extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return TransactionCurrency
*/
public function convert($value)
{
throw new FireflyException('Importer with name CurrencySymbol has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using CurrencySymbol', ['value' => $value]);
if ($value === 0) {
return new TransactionCurrency;
}
/** @var CurrencyRepositoryInterface $repository */
$repository = app(CurrencyRepositoryInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found currency in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$currency = $repository->find(intval($this->mapping[$value]));
if (!is_null($currency->id)) {
Log::debug('Found currency by ID', ['id' => $currency->id]);
return $currency;
}
}
// not mapped? Still try to find it first:
$currency = $repository->findBySymbol($value);
if (!is_null($currency->id)) {
Log::debug('Found currency by symbol ', ['id' => $currency->id]);
return $currency;
}
// create new currency
$currency = $repository->store(
[
'name' => 'Currency ' . $value,
'code' => $value,
'symbol' => $value,
]
);
return $currency;
}
}

View File

@ -12,6 +12,7 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use Log;
/**
* Class INGDebetCredit
@ -24,11 +25,19 @@ class INGDebetCredit extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return int
*/
public function convert($value)
{
throw new FireflyException('Importer with name INGDebetCredit has not yet been configured.');
Log::debug('Going to convert ', ['value' => $value]);
if ($value === 'Af') {
Log::debug('Return -1');
return -1;
}
Log::debug('Return 1');
return 1;
}
}

View File

@ -1,34 +0,0 @@
<?php
/**
* OpposingAccountId.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
/**
* Class OpposingAccountId
*
* @package FireflyIII\Import\Converter
*/
class OpposingAccountId extends BasicConverter implements ConverterInterface
{
/**
* @param $value
*
* @throws FireflyException
*/
public function convert($value)
{
throw new FireflyException('Importer with name OpposingAccountId has not yet been configured.');
}
}

View File

@ -11,7 +11,10 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Crud\Account\AccountCrudInterface;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use Log;
/**
* Class OpposingAccountNumber
@ -24,11 +27,46 @@ class OpposingAccountNumber extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Account
*/
public function convert($value)
{
throw new FireflyException('Importer with name OpposingAccountNumber has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using OpposingAccountNumber', ['value' => $value]);
if (strlen($value) === 0) {
return new Account;
}
/** @var AccountCrudInterface $repository */
$repository = app(AccountCrudInterface::class, [$this->user]);
if (isset($this->mapping[$value])) {
Log::debug('Found account in mapping. Should exist.', ['value' => $value, 'map' => $this->mapping[$value]]);
$account = $repository->find(intval($this->mapping[$value]));
if (!is_null($account->id)) {
Log::debug('Found account by ID', ['id' => $account->id]);
return $account;
}
}
// not mapped? Still try to find it first:
$account = $repository->findByAccountNumber($value, []);
if (!is_null($account->id)) {
Log::debug('Found account by name', ['id' => $account->id]);
return $account;
}
$account = $repository->store(
['name' => 'Account with number ' . $value, 'openingBalance' => 0, 'iban' => null, 'user' => $this->user->id, 'accountType' => 'asset',
'virtualBalance' => 0, 'active' => true]
);
return $account;
}
}

View File

@ -31,9 +31,13 @@ class RabobankDebetCredit extends BasicConverter implements ConverterInterface
Log::debug('Going to convert ', ['value' => $value]);
if ($value === 'D') {
Log::debug('Return -1');
return -1;
}
Log::debug('Return 1');
return 1;
}
}

View File

@ -11,7 +11,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Support\Collection;
use Log;
/**
* Class TagsComma
@ -24,11 +26,59 @@ class TagsComma extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Collection
*/
public function convert($value)
{
throw new FireflyException('Importer with name TagsComma has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using TagsComma', ['value' => $value]);
if (strlen($value) === 0) {
return new Collection;
}
$parts = array_unique(explode(',', $value));
$set = new Collection;
Log::debug('Exploded parts.', $parts);
/** @var TagRepositoryInterface $repository */
$repository = app(TagRepositoryInterface::class, [$this->user]);
/** @var string $part */
foreach ($parts as $part) {
if (isset($this->mapping[$part])) {
Log::debug('Found tag in mapping. Should exist.', ['value' => $part, 'map' => $this->mapping[$part]]);
$tag = $repository->find(intval($this->mapping[$part]));
if (!is_null($tag->id)) {
Log::debug('Found tag by ID', ['id' => $tag->id]);
$set->push($tag);
continue;
}
}
// not mapped? Still try to find it first:
$tag = $repository->findByTag($part);
if (!is_null($tag->id)) {
Log::debug('Found tag by name ', ['id' => $tag->id]);
$set->push($tag);
continue;
}
// create new tag
$tag = $repository->store(
[
'tag' => $part,
'date' => null,
'description' => $part,
'latitude' => null,
'longitude' => null,
'zoomLevel' => null,
'tagMode' => 'nothing',
]
);
Log::debug('Created new tag', ['name' => $part, 'id' => $tag->id]);
$set->push($tag);
}
return $set;
}
}

View File

@ -11,7 +11,9 @@ declare(strict_types = 1);
namespace FireflyIII\Import\Converter;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Repositories\Tag\TagRepositoryInterface;
use Illuminate\Support\Collection;
use Log;
/**
* Class TagsSpace
@ -24,11 +26,61 @@ class TagsSpace extends BasicConverter implements ConverterInterface
/**
* @param $value
*
* @throws FireflyException
* @return Collection
*/
public function convert($value)
{
throw new FireflyException('Importer with name TagsSpace has not yet been configured.');
$value = trim($value);
Log::debug('Going to convert using TagsSpace', ['value' => $value]);
if (strlen($value) === 0) {
return new Collection;
}
$parts = array_unique(explode(' ', $value));
$set = new Collection;
Log::debug('Exploded parts.', $parts);
/** @var TagRepositoryInterface $repository */
$repository = app(TagRepositoryInterface::class, [$this->user]);
/** @var string $part */
foreach ($parts as $part) {
if (isset($this->mapping[$part])) {
Log::debug('Found tag in mapping. Should exist.', ['value' => $part, 'map' => $this->mapping[$part]]);
$tag = $repository->find(intval($this->mapping[$part]));
if (!is_null($tag->id)) {
Log::debug('Found tag by ID', ['id' => $tag->id]);
$set->push($tag);
continue;
}
}
// not mapped? Still try to find it first:
$tag = $repository->findByTag($part);
if (!is_null($tag->id)) {
Log::debug('Found tag by name ', ['id' => $tag->id]);
$set->push($tag);
continue;
}
// create new tag
$tag = $repository->store(
[
'tag' => $part,
'date' => null,
'description' => $part,
'latitude' => null,
'longitude' => null,
'zoomLevel' => null,
'tagMode' => 'nothing',
]
);
Log::debug('Created new tag', ['name' => $part, 'id' => $tag->id]);
$set->push($tag);
}
return $set;
}
}

View File

@ -12,7 +12,7 @@ declare(strict_types = 1);
namespace FireflyIII\Import;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account;
use Log;
/**
* Class ImportEntry
@ -21,21 +21,39 @@ use FireflyIII\Models\Account;
*/
class ImportEntry
{
/** @var Account */
public $assetAccount;
public $amount;
/**
* @param $role
* @param $value
* @param string $role
* @param string $value
* @param int $certainty
* @param $convertedValue
*
* @throws FireflyException
*/
public function fromRawValue($role, $value)
public function importValue(string $role, string $value, int $certainty, $convertedValue)
{
switch ($role) {
default:
throw new FireflyException('Cannot handle role of type "' . $role . '".');
Log::error('Import entry cannot handle object.', ['role' => $role]);
throw new FireflyException('Import entry cannot handle object of type "' . $role . '".');
break;
case 'amount':
$this->setAmount($convertedValue);
return;
case 'account-id':
break;
}
}
/**
* @param float $amount
*/
private function setAmount(float $amount)
{
$this->amount = $amount;
}
}

View File

@ -485,11 +485,13 @@ class CsvImporter implements ImporterInterface
// run the converter for this value:
$convertedValue = $converter->convert($value);
$certainty = $converter->getCertainty();
// log it.
Log::debug('Value ', ['index' => $index, 'value' => $value, 'role' => $role]);
// store in import entry:
$object->importValue($role, $value, $certainty, $convertedValue);
// $object->fromRawValue($role, $value);

View File

@ -0,0 +1,62 @@
<?php
/**
* Configuration.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* FireflyIII\Models\Configuration
*
* @mixin \Eloquent
* @property integer $id
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property \Carbon\Carbon $deleted_at
* @property string $name
* @property string $data
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Configuration whereId($value)
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Configuration whereCreatedAt($value)
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Configuration whereUpdatedAt($value)
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Configuration whereDeletedAt($value)
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Configuration whereName($value)
* @method static \Illuminate\Database\Query\Builder|\FireflyIII\Models\Configuration whereData($value)
*/
class Configuration extends Model
{
use SoftDeletes;
protected $table = 'configuration';
protected $dates = ['created_at', 'updated_at', 'deleted_at'];
/**
* @param $value
*
* @return mixed
*/
public function getDataAttribute($value)
{
return json_decode($value);
}
/**
* @param $value
*/
public function setDataAttribute($value)
{
$this->attributes['data'] = json_encode($value);
}
}

View File

@ -47,6 +47,7 @@ class Preference extends Model
* @param $value
*
* @return mixed
* @throws FireflyException
*/
public function getDataAttribute($value)
{

View File

@ -13,6 +13,7 @@ namespace FireflyIII\Providers;
use FireflyIII\Support\Amount;
use FireflyIII\Support\ExpandedForm;
use FireflyIII\Support\FireflyConfig;
use FireflyIII\Support\Navigation;
use FireflyIII\Support\Preferences;
use FireflyIII\Support\Steam;
@ -62,6 +63,12 @@ class FireflyServiceProvider extends ServiceProvider
return new Preferences;
}
);
$this->app->bind(
'fireflyconfig', function () {
return new FireflyConfig;
}
);
$this->app->bind(
'navigation', function () {
return new Navigation;

View File

@ -23,7 +23,6 @@ use FireflyIII\User;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Query\JoinClause;
use Illuminate\Support\Collection;
use Log;
/**
* Class BudgetRepository
@ -86,6 +85,26 @@ class BudgetRepository implements BudgetRepositoryInterface
return $budget;
}
/**
* Find a budget.
*
* @param string $name
*
* @return Budget
*/
public function findByName(string $name): Budget
{
$budgets = $this->user->budgets()->get();
/** @var Budget $budget */
foreach ($budgets as $budget) {
if ($budget->name === $name) {
return $budget;
}
}
return new Budget;
}
/**
* This method returns the oldest journal or transaction date known to this budget.
* Will cache result.
@ -499,5 +518,4 @@ class BudgetRepository implements BudgetRepositoryInterface
return $limit;
}
}

View File

@ -24,6 +24,11 @@ use Illuminate\Support\Collection;
interface BudgetRepositoryInterface
{
/**
* @return bool
*/
public function cleanupBudgets(): bool;
/**
* @param Budget $budget
*
@ -40,6 +45,15 @@ interface BudgetRepositoryInterface
*/
public function find(int $budgetId): Budget;
/**
* Find a budget.
*
* @param string $name
*
* @return Budget
*/
public function findByName(string $name): Budget;
/**
* This method returns the oldest journal or transaction date known to this budget.
* Will cache result.
@ -92,15 +106,6 @@ interface BudgetRepositoryInterface
*/
public function journalsInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): Collection;
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): string;
/**
* @param Collection $budgets
* @param Collection $accounts
@ -112,9 +117,13 @@ interface BudgetRepositoryInterface
public function spentInPeriod(Collection $budgets, Collection $accounts, Carbon $start, Carbon $end) : string;
/**
* @return bool
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function cleanupBudgets(): bool;
public function spentInPeriodWithoutBudget(Collection $accounts, Carbon $start, Carbon $end): string;
/**
* @param array $data

View File

@ -101,6 +101,25 @@ class CategoryRepository implements CategoryRepositoryInterface
return $category;
}
/**
* Find a category
*
* @param string $name
*
* @return Category
*/
public function findByName(string $name) : Category
{
$categories = $this->user->categories()->get();
foreach ($categories as $category) {
if ($category->name === $name) {
return $category;
}
}
return new Category;
}
/**
* @param Category $category
* @param Collection $accounts
@ -554,4 +573,5 @@ class CategoryRepository implements CategoryRepositoryInterface
return $sum;
}
}

View File

@ -59,6 +59,15 @@ interface CategoryRepositoryInterface
*/
public function find(int $categoryId) : Category;
/**
* Find a category
*
* @param string $name
*
* @return Category
*/
public function findByName(string $name) : Category;
/**
* @param Category $category
* @param Collection $accounts
@ -94,15 +103,6 @@ interface CategoryRepositoryInterface
*/
public function journalsInPeriod(Collection $categories, Collection $accounts, array $types, Carbon $start, Carbon $end): Collection;
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriodWithoutCategory(Collection $accounts, Carbon $start, Carbon $end) : string;
/**
* @param Collection $accounts
* @param array $types
@ -133,6 +133,15 @@ interface CategoryRepositoryInterface
*/
public function spentInPeriod(Collection $categories, Collection $accounts, Carbon $start, Carbon $end): string;
/**
* @param Collection $accounts
* @param Carbon $start
* @param Carbon $end
*
* @return string
*/
public function spentInPeriodWithoutCategory(Collection $accounts, Carbon $start, Carbon $end) : string;
/**
* @param array $data
*

View File

@ -82,6 +82,39 @@ class TagRepository implements TagRepositoryInterface
return true;
}
/**
* @param int $tagId
*
* @return Tag
*/
public function find(int $tagId) : Tag
{
$tag = $this->user->tags()->find($tagId);
if (is_null($tag)) {
$tag = new Tag;
}
return $tag;
}
/**
* @param string $tag
*
* @return Tag
*/
public function findByTag(string $tag) : Tag
{
$tags = $this->user->tags()->get();
/** @var Tag $tag */
foreach ($tags as $tag) {
if ($tag->tag === $tag) {
return $tag;
}
}
return new Tag;
}
/**
* @return Collection
*/

View File

@ -42,6 +42,20 @@ interface TagRepositoryInterface
*/
public function destroy(Tag $tag): bool;
/**
* @param string $tag
*
* @return Tag
*/
public function findByTag(string $tag) : Tag;
/**
* @param int $tagId
*
* @return Tag
*/
public function find(int $tagId) : Tag;
/**
* This method returns all the user's tags.
*

View File

@ -0,0 +1,33 @@
<?php
/**
* FireflyConfig.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Support\Facades;
use Illuminate\Support\Facades\Facade;
/**
* Class FireflyConfig
*
* @package FireflyIII\Support\Facades
*/
class FireflyConfig extends Facade
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor(): string
{
return 'fireflyconfig';
}
}

View File

@ -0,0 +1,91 @@
<?php
/**
* FireflyConfig.php
* Copyright (C) 2016 thegrumpydictator@gmail.com
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
declare(strict_types = 1);
namespace FireflyIII\Support;
use Auth;
use Cache;
use FireflyIII\Models\Configuration;
use FireflyIII\Models\Preference;
/**
* Class FireflyConfig
*
* @package FireflyIII\Support
*/
class FireflyConfig
{
/**
* @param $name
*
* @return bool
* @throws \Exception
*/
public function delete($name): bool
{
$fullName = 'preference' . Auth::user()->id . $name;
if (Cache::has($fullName)) {
Cache::forget($fullName);
}
Preference::where('user_id', Auth::user()->id)->where('name', $name)->delete();
return true;
}
/**
* @param $name
* @param null $default
*
* @return Configuration|null
*/
public function get($name, $default = null)
{
$fullName = 'ff-config-' . $name;
if (Cache::has($fullName)) {
return Cache::get($fullName);
}
$config = Configuration::where('name', $name)->first(['id', 'name', 'data']);
if ($config) {
Cache::forever($fullName, $config);
return $config;
}
// no preference found and default is null:
if (is_null($default)) {
// return NULL
return null;
}
return $this->set($name, $default);
}
/**
* @param $name
* @param string $value
*
* @return Configuration
*/
public function set($name, $value): Configuration
{
$item = $this->get($name, $value);
$item->data = $value;
$item->save();
Cache::forget('ff-config-' . $name);
return $item;
}
}

554
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -152,8 +152,6 @@ return [
Collective\Html\HtmlServiceProvider::class,
/*
* Application Service Providers...
*/
@ -165,8 +163,8 @@ return [
// own stuff:
// Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
// Barryvdh\Debugbar\ServiceProvider::class,
Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
Barryvdh\Debugbar\ServiceProvider::class,
'DaveJamesMiller\Breadcrumbs\ServiceProvider',
'TwigBridge\ServiceProvider',
'PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider',
@ -204,48 +202,49 @@ return [
'aliases' => [
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Twig' => 'TwigBridge\Facade\Twig',
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade',
'Preferences' => 'FireflyIII\Support\Facades\Preferences',
'Navigation' => 'FireflyIII\Support\Facades\Navigation',
'Amount' => 'FireflyIII\Support\Facades\Amount',
'Steam' => 'FireflyIII\Support\Facades\Steam',
'ExpandedForm' => 'FireflyIII\Support\Facades\ExpandedForm',
'Entrust' => 'Zizaco\Entrust\EntrustFacade',
'Input' => 'Illuminate\Support\Facades\Input',
'Google2FA' => 'PragmaRX\Google2FA\Vendor\Laravel\Facade',
'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class,
'Blade' => Illuminate\Support\Facades\Blade::class,
'Cache' => Illuminate\Support\Facades\Cache::class,
'Config' => Illuminate\Support\Facades\Config::class,
'Cookie' => Illuminate\Support\Facades\Cookie::class,
'Crypt' => Illuminate\Support\Facades\Crypt::class,
'DB' => Illuminate\Support\Facades\DB::class,
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
'Event' => Illuminate\Support\Facades\Event::class,
'File' => Illuminate\Support\Facades\File::class,
'Gate' => Illuminate\Support\Facades\Gate::class,
'Hash' => Illuminate\Support\Facades\Hash::class,
'Lang' => Illuminate\Support\Facades\Lang::class,
'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class,
'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class,
'Redis' => Illuminate\Support\Facades\Redis::class,
'Request' => Illuminate\Support\Facades\Request::class,
'Response' => Illuminate\Support\Facades\Response::class,
'Route' => Illuminate\Support\Facades\Route::class,
'Schema' => Illuminate\Support\Facades\Schema::class,
'Session' => Illuminate\Support\Facades\Session::class,
'Storage' => Illuminate\Support\Facades\Storage::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'Twig' => 'TwigBridge\Facade\Twig',
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
'Breadcrumbs' => 'DaveJamesMiller\Breadcrumbs\Facade',
'Preferences' => 'FireflyIII\Support\Facades\Preferences',
'FireflyConfig' => 'FireflyIII\Support\Facades\FireflyConfig',
'Navigation' => 'FireflyIII\Support\Facades\Navigation',
'Amount' => 'FireflyIII\Support\Facades\Amount',
'Steam' => 'FireflyIII\Support\Facades\Steam',
'ExpandedForm' => 'FireflyIII\Support\Facades\ExpandedForm',
'Entrust' => 'Zizaco\Entrust\EntrustFacade',
'Input' => 'Illuminate\Support\Facades\Input',
'Google2FA' => 'PragmaRX\Google2FA\Vendor\Laravel\Facade',
],

View File

@ -60,7 +60,7 @@ return [
],
'bill-id' => [
'mappable' => false,
'mappable' => true,
'pre-process-map' => false,
'field' => 'bill',
'converter' => 'BillId',
@ -179,7 +179,7 @@ return [
'mappable' => true,
'pre-process-map' => false,
'field' => 'asset-account-id',
'converter' => 'AssetAccountId',
'converter' => 'AccountId',
'mapper' => 'AssetAccounts',
],
'account-name' => [
@ -208,7 +208,7 @@ return [
'mappable' => true,
'pre-process-map' => false,
'field' => 'opposing-account-id',
'converter' => 'OpposingAccountId',
'converter' => 'AccountId',
'mapper' => 'OpposingAccounts',
],
'opposing-name' => [

View File

@ -25,6 +25,7 @@ class CreateSupportTables extends Migration
Schema::drop('permissions');
Schema::drop('roles');
Schema::drop('sessions');
Schema::drop('configuration');
}
@ -79,6 +80,8 @@ class CreateSupportTables extends Migration
*/
$this->createSessionsTable();
$this->createConfigurationTable();
}
/**
@ -123,6 +126,23 @@ class CreateSupportTables extends Migration
}
}
private function createConfigurationTable()
{
if (!Schema::hasTable('configuration')) {
Schema::create(
'configuration', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->softDeletes();
$table->string('name', 50);
$table->text('data');
$table->unique(['name']);
}
);
}
}
/**
*
*/
@ -176,7 +196,7 @@ class CreateSupportTables extends Migration
'permission_role', function (Blueprint $table) {
$table->integer('permission_id')->unsigned();
$table->integer('role_id')->unsigned();
$table->foreign('permission_id')->references('id')->on('permissions')->onUpdate('cascade')->onDelete('cascade');
$table->foreign('role_id')->references('id')->on('roles')->onUpdate('cascade')->onDelete('cascade');

View File

@ -718,6 +718,18 @@ return [
'user_administration' => 'User administration',
'list_all_users' => 'All users',
'all_users' => 'All users',
'all_blocked_domains' => 'All blocked domains',
'blocked_domains' => 'Blocked domains',
'no_domains_banned' => 'No domains blocked',
'all_user_domains' => 'All user email address domains',
'all_domains_is_filtered' => 'This list does not include already blocked domains.',
'domain_now_blocked' => 'Domain :domain is now blocked',
'domain_now_unblocked' => 'Domain :domain is now unblocked',
'manual_block_domain' => 'Block a domain by hand',
'block_domain' => 'Block domain',
'no_domain_filled_in' => 'No domain filled in',
'domain_already_blocked' => 'Domain :domain is already blocked',
'domain_is_now_blocked' => 'Domain :domain is now blocked',
// split a transaction:
'transaction_meta_data' => 'Transaction meta-data',

View File

@ -131,6 +131,9 @@ return [
'category_keep_transactions' => 'The only transaction connected to this category will not be deleted.|All :count transactions connected to this category will spared deletion.',
'tag_keep_transactions' => 'The only transaction connected to this tag will not be deleted.|All :count transactions connected to this tag will spared deletion.',
// admin
'domain' => 'Domain',
// import
'import_file' => 'Import file',
'configuration_file' => 'Configuration file',

View File

@ -8,54 +8,56 @@
*/
return [
'buttons' => 'Buttons',
'icon' => 'Icon',
'create_date' => 'Created at',
'update_date' => 'Updated at',
'balance_before' => 'Balance before',
'balance_after' => 'Balance after',
'name' => 'Name',
'role' => 'Role',
'currentBalance' => 'Current balance',
'active' => 'Is active?',
'lastActivity' => 'Last activity',
'balanceDiff' => 'Balance difference between :start and :end',
'matchedOn' => 'Matched on',
'matchesOn' => 'Matched on',
'account_type' => 'Account type',
'new_balance' => 'New balance',
'account' => 'Account',
'matchingAmount' => 'Amount',
'lastMatch' => 'Last match',
'split_number' => 'Split #',
'destination' => 'Destination',
'expectedMatch' => 'Expected match',
'automatch' => 'Auto match?',
'repeat_freq' => 'Repeats',
'description' => 'Description',
'amount' => 'Amount',
'date' => 'Date',
'interest_date' => 'Interest date',
'book_date' => 'Book date',
'process_date' => 'Processing date',
'from' => 'From',
'piggy_bank' => 'Piggy bank',
'to' => 'To',
'budget' => 'Budget',
'category' => 'Category',
'bill' => 'Bill',
'withdrawal' => 'Withdrawal',
'deposit' => 'Deposit',
'transfer' => 'Transfer',
'type' => 'Type',
'completed' => 'Completed',
'iban' => 'IBAN',
'paid_current_period' => 'Paid this period',
'email' => 'Email',
'registered_at' => 'Registered at',
'is_activated' => 'Is activated',
'is_blocked' => 'Is blocked',
'is_admin' => 'Is admin',
'has_two_factor' => 'Has 2FA',
'blocked_code' => 'Block code',
'buttons' => 'Buttons',
'icon' => 'Icon',
'create_date' => 'Created at',
'update_date' => 'Updated at',
'balance_before' => 'Balance before',
'balance_after' => 'Balance after',
'name' => 'Name',
'role' => 'Role',
'currentBalance' => 'Current balance',
'active' => 'Is active?',
'lastActivity' => 'Last activity',
'balanceDiff' => 'Balance difference between :start and :end',
'matchedOn' => 'Matched on',
'matchesOn' => 'Matched on',
'account_type' => 'Account type',
'new_balance' => 'New balance',
'account' => 'Account',
'matchingAmount' => 'Amount',
'lastMatch' => 'Last match',
'split_number' => 'Split #',
'destination' => 'Destination',
'expectedMatch' => 'Expected match',
'automatch' => 'Auto match?',
'repeat_freq' => 'Repeats',
'description' => 'Description',
'amount' => 'Amount',
'date' => 'Date',
'interest_date' => 'Interest date',
'book_date' => 'Book date',
'process_date' => 'Processing date',
'from' => 'From',
'piggy_bank' => 'Piggy bank',
'to' => 'To',
'budget' => 'Budget',
'category' => 'Category',
'bill' => 'Bill',
'withdrawal' => 'Withdrawal',
'deposit' => 'Deposit',
'transfer' => 'Transfer',
'type' => 'Type',
'completed' => 'Completed',
'iban' => 'IBAN',
'paid_current_period' => 'Paid this period',
'email' => 'Email',
'registered_at' => 'Registered at',
'is_activated' => 'Is activated',
'is_blocked' => 'Is blocked',
'is_admin' => 'Is admin',
'has_two_factor' => 'Has 2FA',
'blocked_code' => 'Block code',
'domain' => 'Domain',
'registration_attempts' => 'Registration attempts',
];

View File

@ -13,6 +13,7 @@
<div class="box-body">
<ul>
<li><a href="{{ route('admin.users') }}">{{ 'list_all_users'|_ }}</a></li>
<li><a href="{{ route('admin.users.domains') }}">{{ 'blocked_domains'|_ }}</a></li>
<!-- <li><a href="#">{{ 'user_related_settings'|_ }}</a></li> -->
</ul>
</div>

View File

@ -0,0 +1,120 @@
{% extends "./layout/default.twig" %}
{% block breadcrumbs %}
{{ Breadcrumbs.renderIfExists }}
{% endblock %}
{% block content %}
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'all_blocked_domains'|_ }}</h3>
</div>
<div class="box-body table-responsive">
{% if domains|length > 0 %}
<table class="table table-condensed table-sortable">
<thead>
<tr>
<th style="width:20%;">&nbsp;</th>
<th>{{ trans('list.domain') }}</th>
<th>{{ trans('list.is_blocked') }}</th>
</tr>
</thead>
<tbody>
{% for domain in domains %}
<tr>
<td>
<a href="{{ route('admin.users.domains.block-toggle', [domain]) }}" class="btn btn-sm btn-success"><i
class="fa fa-fw fa-times"></i> unblock</a>
</td>
<td>{{ domain }}</td>
<td>
<small class="text-success"><i class="fa fa-fw fa-check"></i></small>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>
<em>{{ 'no_domains_banned'|_ }}</em>
</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- domains found in users (not in top list) -->
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'all_user_domains'|_ }}</h3>
</div>
<div class="box-body table-responsive">
{% if knownDomains|length > 0 %}
<p>
{{ 'all_domains_is_filtered'|_ }}
</p>
<table class="table table-condensed table-sortable">
<thead>
<tr>
<th style="width:20%;">&nbsp;</th>
<th>{{ trans('list.domain') }}</th>
</tr>
</thead>
<tbody>
{% for domain in knownDomains %}
<tr>
<td><a href="{{ route('admin.users.domains.block-toggle', [domain]) }}" class="btn btn-sm btn-danger"><i
class="fa fa-fw fa-check"></i> block</a></td>
<td>{{ domain }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p class="well">
<em>{{ 'no_domains_banned'|_ }}</em>
</p>
{% endif %}
</div>
</div>
</div>
</div>
<!-- block domain by hand -->
<div class="row">
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="box box-primary">
<div class="box-header with-border">
<h3 class="box-title">{{ 'manual_block_domain'|_ }}</h3>
</div>
<div class="box-body">
<div class="row">
<div class="col-lg-6">
<form action="{{ route('admin.users.domains.manual') }}" method="post" id="store" class="form-horizontal">
<input type="hidden" name="_token" value="{{ csrf_token() }}"/>
<input type="hidden" name="what" value="{{ what }}"/>
{{ ExpandedForm.text('domain') }}
<input type="submit" name="submit" class="btn btn-success" value="{{ ('block_domain')|_ }}"/>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}