Merge branch 'develop' into feature/test-triggers

This commit is contained in:
Robert Horlings
2016-02-17 16:14:07 +01:00
28 changed files with 454 additions and 108 deletions

View File

@@ -4,6 +4,7 @@ declare(strict_types = 1);
namespace FireflyIII\Http\Controllers\Auth; namespace FireflyIII\Http\Controllers\Auth;
use Auth; use Auth;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Controllers\Controller;
use FireflyIII\Models\Role; use FireflyIII\Models\Role;
use FireflyIII\User; use FireflyIII\User;
@@ -151,7 +152,7 @@ class AuthController extends Controller
return redirect($this->redirectPath()); return redirect($this->redirectPath());
} }
abort(500, 'Not a user!'); throw new FireflyException('The authenticated user object is invalid.');
return redirect($this->redirectPath()); return redirect($this->redirectPath());

View File

@@ -3,6 +3,7 @@
use Amount; use Amount;
use Carbon\Carbon; use Carbon\Carbon;
use Config; use Config;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Helpers\Report\ReportQueryInterface; use FireflyIII\Helpers\Report\ReportQueryInterface;
use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI; use FireflyIII\Repositories\Account\AccountRepositoryInterface as ARI;
use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface;
@@ -247,7 +248,7 @@ class JsonController extends Controller
{ {
$pref = Preferences::get('tour', true); $pref = Preferences::get('tour', true);
if (!$pref) { if (!$pref) {
abort(404); throw new FireflyException('Cannot find preference for tour. Exit.');
} }
$headers = ['main-content', 'sidebar-toggle', 'account-menu', 'budget-menu', 'report-menu', 'transaction-menu', 'option-menu', 'main-content-end']; $headers = ['main-content', 'sidebar-toggle', 'account-menu', 'budget-menu', 'report-menu', 'transaction-menu', 'option-menu', 'main-content-end'];
$steps = []; $steps = [];

View File

@@ -6,6 +6,7 @@ namespace FireflyIII\Http\Requests;
use Auth; use Auth;
use Carbon\Carbon; use Carbon\Carbon;
use Exception; use Exception;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\TransactionType; use FireflyIII\Models\TransactionType;
use Input; use Input;
@@ -32,6 +33,7 @@ class JournalFormRequest extends Request
public function getJournalData() public function getJournalData()
{ {
$tags = $this->get('tags') ?? ''; $tags = $this->get('tags') ?? '';
return [ return [
'what' => $this->get('what'), 'what' => $this->get('what'),
'description' => $this->get('description'), 'description' => $this->get('description'),
@@ -86,7 +88,7 @@ class JournalFormRequest extends Request
$rules['category'] = 'between:1,255'; $rules['category'] = 'between:1,255';
break; break;
default: default:
abort(500, 'Cannot handle ' . $what); throw new FireflyException('Cannot handle transaction type of type ' . e($what) . '.');
break; break;
} }

View File

@@ -10,6 +10,7 @@ declare(strict_types = 1);
namespace FireflyIII\Models; namespace FireflyIII\Models;
use FireflyIII\Rules\Triggers\TriggerFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
/** /**
@@ -29,6 +30,15 @@ use Illuminate\Database\Eloquent\Model;
*/ */
class RuleTrigger extends Model class RuleTrigger extends Model
{ {
/**
* Checks whether this trigger will match all transactions
* For example: amount > 0 or description starts with ''
*/
public function matchesAnything()
{
return TriggerFactory::getTrigger($this, new TransactionJournal)->matchesAnything();
}
/** /**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/ */

View File

@@ -7,6 +7,7 @@ use Auth;
use Carbon\Carbon; use Carbon\Carbon;
use Config; use Config;
use DB; use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountMeta; use FireflyIII\Models\AccountMeta;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
@@ -482,7 +483,9 @@ class AccountRepository implements AccountRepositoryInterface
$existingAccount = Account::firstOrNullEncrypted($searchData); $existingAccount = Account::firstOrNullEncrypted($searchData);
if (!$existingAccount) { if (!$existingAccount) {
Log::error('Account create error: ' . $newAccount->getErrors()->toJson()); Log::error('Account create error: ' . $newAccount->getErrors()->toJson());
abort(500); throw new FireflyException(
'Cannot create a new account. See also the log files. First error is: ' . e($newAccount->getErrors()->first()) . '.'
);
} }
$newAccount = $existingAccount; $newAccount = $existingAccount;

View File

@@ -6,6 +6,7 @@ namespace FireflyIII\Repositories\Journal;
use Auth; use Auth;
use Carbon\Carbon; use Carbon\Carbon;
use DB; use DB;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\Account; use FireflyIII\Models\Account;
use FireflyIII\Models\AccountType; use FireflyIII\Models\AccountType;
use FireflyIII\Models\Budget; use FireflyIII\Models\Budget;
@@ -349,14 +350,14 @@ class JournalRepository implements JournalRepositoryInterface
if (is_null($toAccount)) { if (is_null($toAccount)) {
Log::error('"to"-account is null, so we cannot continue!'); Log::error('"to"-account is null, so we cannot continue!');
abort(500, '"to"-account is null, so we cannot continue!'); throw new FireflyException('"to"-account is null, so we cannot continue!');
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
} }
// @codeCoverageIgnoreEnd // @codeCoverageIgnoreEnd
if (is_null($fromAccount)) { if (is_null($fromAccount)) {
Log::error('"from"-account is null, so we cannot continue!'); Log::error('"from"-account is null, so we cannot continue!');
abort(500, '"from"-account is null, so we cannot continue!'); throw new FireflyException('"from"-account is null, so we cannot continue!');
// @codeCoverageIgnoreStart // @codeCoverageIgnoreStart
} }

View File

@@ -0,0 +1,78 @@
<?php
declare(strict_types = 1);
/**
* ActionFactory.php
* Copyright (C) 2016 Robert Horlings
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Rules\Actions;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\RuleAction;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Domain;
/**
* Interface ActionInterface
*
* @package FireflyIII\Rules\Actions
*/
class ActionFactory
{
protected static $actionTypes = null;
/**
* Returns the action for the given type and journal
*
* @param RuleAction $action
* @param TransactionJournal $journal
*
* @return ActionInterface
*/
public static function getAction(RuleAction $action, TransactionJournal $journal): ActionInterface
{
$actionType = $action->action_type;
$class = self::getActionClass($actionType);
return new $class($action, $journal);
}
/**
* Returns the class name to be used for actions with the given name
*
* @param string $actionType
*
* @return ActionInterface|string
* @throws FireflyException
*/
public static function getActionClass(string $actionType): string
{
$actionTypes = self::getActionTypes();
if (!array_key_exists($actionType, $actionTypes)) {
throw new FireflyException('No such action exists ("' . e($actionType) . '").');
}
$class = $actionTypes[$actionType];
if (!class_exists($class)) {
throw new FireflyException('Could not instantiate class for rule action type "' . e($actionType) . '" (' . e($class) . ').');
}
return $class;
}
/**
* Returns a map with actiontypes, mapped to the class representing that type
*/
protected static function getActionTypes()
{
if (!self::$actionTypes) {
self::$actionTypes = Domain::getRuleActions();
}
return self::$actionTypes;
}
}

View File

@@ -15,8 +15,9 @@ use FireflyIII\Models\RuleAction;
use FireflyIII\Models\RuleTrigger; use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournal;
use FireflyIII\Rules\Actions\ActionInterface; use FireflyIII\Rules\Actions\ActionInterface;
use FireflyIII\Rules\Actions\ActionFactory;
use FireflyIII\Rules\Triggers\TriggerInterface; use FireflyIII\Rules\Triggers\TriggerInterface;
use FireflyIII\Support\Domain; use FireflyIII\Rules\Triggers\TriggerFactory;
use Log; use Log;
/** /**
@@ -30,10 +31,6 @@ class Processor
protected $journal; protected $journal;
/** @var Rule */ /** @var Rule */
protected $rule; protected $rule;
/** @var array */
private $actionTypes = [];
/** @var array */
private $triggerTypes = [];
/** /**
* Processor constructor. * Processor constructor.
@@ -45,8 +42,6 @@ class Processor
{ {
$this->rule = $rule; $this->rule = $rule;
$this->journal = $journal; $this->journal = $journal;
$this->triggerTypes = Domain::getRuleTriggers();
$this->actionTypes = Domain::getRuleActions();
} }
/** /**
@@ -118,14 +113,8 @@ class Processor
* @var RuleAction $action * @var RuleAction $action
*/ */
foreach ($this->rule->ruleActions()->orderBy('order', 'ASC')->get() as $action) { foreach ($this->rule->ruleActions()->orderBy('order', 'ASC')->get() as $action) {
$type = $action->action_type;
$class = $this->actionTypes[$type];
Log::debug('Action #' . $action->id . ' for rule #' . $action->rule_id . ' (' . $type . ')');
if (!class_exists($class)) {
abort(500, 'Could not instantiate class for rule action type "' . $type . '" (' . $class . ').');
}
/** @var ActionInterface $actionClass */ /** @var ActionInterface $actionClass */
$actionClass = new $class($action, $this->journal); $actionClass = ActionFactory::getAction($action, $this->journal);
$actionClass->act(); $actionClass->act();
if ($action->stop_processing) { if ($action->stop_processing) {
break; break;
@@ -137,8 +126,6 @@ class Processor
} }
/** /**
* Method to check whether the current transaction would be triggered
* by the given list of triggers
* @return bool * @return bool
*/ */
protected function triggeredBy($triggers) { protected function triggeredBy($triggers) {
@@ -147,19 +134,9 @@ class Processor
/** @var RuleTrigger $trigger */ /** @var RuleTrigger $trigger */
foreach ($triggers as $trigger) { foreach ($triggers as $trigger) {
$foundTriggers++; $foundTriggers++;
$type = $trigger->trigger_type;
if (!isset($this->triggerTypes[$type])) {
abort(500, 'No such trigger exists ("' . $type . '").');
}
$class = $this->triggerTypes[$type];
Log::debug('Trigger #' . $trigger->id . ' for rule #' . $trigger->rule_id . ' (' . $type . ')');
if (!class_exists($class)) {
abort(500, 'Could not instantiate class for rule trigger type "' . $type . '" (' . $class . ').');
}
/** @var TriggerInterface $triggerClass */ /** @var TriggerInterface $triggerClass */
$triggerClass = new $class($trigger, $this->journal); $triggerClass = TriggerFactory::getTrigger($trigger, $this->journal);
if ($triggerClass->triggered()) { if ($triggerClass->triggered()) {
$hitTriggers++; $hitTriggers++;
} }

View File

@@ -22,12 +22,10 @@ use Log;
*/ */
class AmountExactly implements TriggerInterface class AmountExactly implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -41,6 +39,18 @@ class AmountExactly implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return false;
}
/** /**
* @return bool * @return bool
*/ */

View File

@@ -22,12 +22,10 @@ use Log;
*/ */
class AmountLess implements TriggerInterface class AmountLess implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -41,6 +39,18 @@ class AmountLess implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return false;
}
/** /**
* @return bool * @return bool
*/ */

View File

@@ -22,12 +22,10 @@ use Log;
*/ */
class AmountMore implements TriggerInterface class AmountMore implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -41,6 +39,18 @@ class AmountMore implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return bccomp('0', $this->trigger->trigger_value) === 0;
}
/** /**
* @return bool * @return bool
*/ */

View File

@@ -22,12 +22,10 @@ use Log;
*/ */
class DescriptionContains implements TriggerInterface class DescriptionContains implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -41,6 +39,18 @@ class DescriptionContains implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class DescriptionEnds implements TriggerInterface class DescriptionEnds implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class DescriptionEnds implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -72,4 +82,5 @@ class DescriptionEnds implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class DescriptionIs implements TriggerInterface class DescriptionIs implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class DescriptionIs implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return false;
}
/** /**
* @return bool * @return bool
*/ */
@@ -58,4 +68,5 @@ class DescriptionIs implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class DescriptionStarts implements TriggerInterface class DescriptionStarts implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class DescriptionStarts implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -60,4 +70,5 @@ class DescriptionStarts implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class FromAccountContains implements TriggerInterface class FromAccountContains implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class FromAccountContains implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -62,4 +72,5 @@ class FromAccountContains implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class FromAccountEnds implements TriggerInterface class FromAccountEnds implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class FromAccountEnds implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -72,4 +82,5 @@ class FromAccountEnds implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class FromAccountIs implements TriggerInterface class FromAccountIs implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class FromAccountIs implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return false;
}
/** /**
* @return bool * @return bool
*/ */
@@ -58,4 +68,5 @@ class FromAccountIs implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class FromAccountStarts implements TriggerInterface class FromAccountStarts implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class FromAccountStarts implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -60,4 +70,5 @@ class FromAccountStarts implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class ToAccountContains implements TriggerInterface class ToAccountContains implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class ToAccountContains implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -62,4 +72,5 @@ class ToAccountContains implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class ToAccountEnds implements TriggerInterface class ToAccountEnds implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class ToAccountEnds implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class ToAccountIs implements TriggerInterface class ToAccountIs implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class ToAccountIs implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return false;
}
/** /**
* @return bool * @return bool
*/ */
@@ -58,4 +68,5 @@ class ToAccountIs implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class ToAccountStarts implements TriggerInterface class ToAccountStarts implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class ToAccountStarts implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return $this->trigger->trigger_value === "";
}
/** /**
* @return bool * @return bool
*/ */
@@ -60,4 +70,5 @@ class ToAccountStarts implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class TransactionType implements TriggerInterface class TransactionType implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -40,6 +38,18 @@ class TransactionType implements TriggerInterface
$this->journal = $journal; $this->journal = $journal;
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return false;
}
/** /**
* @return bool * @return bool
*/ */
@@ -57,4 +67,5 @@ class TransactionType implements TriggerInterface
return false; return false;
} }
} }

View File

@@ -0,0 +1,77 @@
<?php
declare(strict_types = 1);
/**
* TriggerFactory.php
* Copyright (C) 2016 Robert Horlings
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
namespace FireflyIII\Rules\Triggers;
use FireflyIII\Exceptions\FireflyException;
use FireflyIII\Models\RuleTrigger;
use FireflyIII\Models\TransactionJournal;
use FireflyIII\Support\Domain;
/**
* Interface TriggerInterface
*
* @package FireflyIII\Rules\Triggers
*/
class TriggerFactory
{
protected static $triggerTypes = null;
/**
* Returns the trigger for the given type and journal
*
* @param RuleTrigger $trigger
* @param TransactionJournal $journal
*
* @return TriggerInterface
*/
public static function getTrigger(RuleTrigger $trigger, TransactionJournal $journal): TriggerInterface
{
$triggerType = $trigger->trigger_type;
$class = self::getTriggerClass($triggerType);
return new $class($trigger, $journal);
}
/**
* Returns the class name to be used for triggers with the given name
*
* @param string $triggerType
*
* @return TriggerInterface
*/
public static function getTriggerClass(string $triggerType): string
{
$triggerTypes = self::getTriggerTypes();
if (!array_key_exists($triggerType, $triggerTypes)) {
throw new FireflyException('No such trigger exists ("' . e($triggerType) . '").');
}
$class = $triggerTypes[$triggerType];
if (!class_exists($class)) {
throw new FireflyException('Could not instantiate class for rule trigger type "' . e($triggerType) . '" (' . e($class) . ').');
}
return $class;
}
/**
* Returns a map with triggertypes, mapped to the class representing that type
*/
protected static function getTriggerTypes()
{
if (!self::$triggerTypes) {
self::$triggerTypes = Domain::getRuleTriggers();
}
return self::$triggerTypes;
}
}

View File

@@ -28,6 +28,22 @@ interface TriggerInterface
*/ */
public function __construct(RuleTrigger $trigger, TransactionJournal $journal); public function __construct(RuleTrigger $trigger, TransactionJournal $journal);
/**
* A trigger is said to "match anything", or match any given transaction,
* when the trigger value is very vague or has no restrictions. Easy examples
* are the "AmountMore"-trigger combined with an amount of 0: any given transaction
* has an amount of more than zero! Other examples are all the "Description"-triggers
* which have hard time handling empty trigger values such as "" or "*" (wild cards).
*
* If the user tries to create such a trigger, this method MUST return true so Firefly III
* can stop the storing / updating the trigger. If the trigger is in any way restrictive
* (even if it will still include 99.9% of the users transactions), this method MUST return
* false.
*
* @return bool
*/
public function matchesAnything();
/** /**
* @return bool * @return bool
*/ */

View File

@@ -21,12 +21,10 @@ use Log;
*/ */
class UserAction implements TriggerInterface class UserAction implements TriggerInterface
{ {
/** @var RuleTrigger */
protected $trigger;
/** @var TransactionJournal */ /** @var TransactionJournal */
protected $journal; protected $journal;
/** @var RuleTrigger */
protected $trigger;
/** /**
* TriggerInterface constructor. * TriggerInterface constructor.
@@ -41,6 +39,18 @@ class UserAction implements TriggerInterface
} }
/**
* @{inheritdoc}
*
* @see TriggerInterface::matchesAnything
*
* @return bool
*/
public function matchesAnything()
{
return true;
}
/** /**
* This trigger is always triggered, because the rule that it is a part of has been pre-selected on this condition. * This trigger is always triggered, because the rule that it is a part of has been pre-selected on this condition.
* *

View File

@@ -46,17 +46,16 @@
<li><a href="{{ route('rules.rule-group.edit',ruleGroup.id) }}"><i <li><a href="{{ route('rules.rule-group.edit',ruleGroup.id) }}"><i
class="fa fa-fw fa-pencil"></i> {{ 'edit'|_ }}</a></li> class="fa fa-fw fa-pencil"></i> {{ 'edit'|_ }}</a></li>
<li><a href="{{ route('rules.rule-group.delete',ruleGroup.id) }}"><i <li><a href="{{ route('rules.rule-group.delete',ruleGroup.id) }}"><i
class="fa fa-fw fa-trash"></i> {{ 'delete'|_ }}</a> class="fa fa-fw fa-trash"></i> {{ 'delete'|_ }}</a></li>
{% if ruleGroup.order > 1 %} {% if ruleGroup.order > 1 %}
<li><a href="{{ route('rules.rule-group.up',ruleGroup.id) }}"><i <li><a href="{{ route('rules.rule-group.up',ruleGroup.id) }}"><i
class="fa fa-fw fa-arrow-up"></i> {{ 'move_rule_group_up'|_ }}</a> class="fa fa-fw fa-arrow-up"></i> {{ 'move_rule_group_up'|_ }}</a></li>
{% endif %} {% endif %}
{% if ruleGroup.order < ruleGroups|length %} {% if ruleGroup.order < ruleGroups|length %}
<li><a href="{{ route('rules.rule-group.down',ruleGroup.id) }}"><i <li><a href="{{ route('rules.rule-group.down',ruleGroup.id) }}"><i
class="fa fa-fw fa-arrow-down"></i> {{ 'move_rule_group_down'|_ }} class="fa fa-fw fa-arrow-down"></i> {{ 'move_rule_group_down'|_ }}
</a> </a></li>
{% endif %} {% endif %}
</li>
</ul> </ul>
</div> </div>
</div> </div>