diff --git a/app/Rules/BelongsUser.php b/app/Rules/BelongsUser.php new file mode 100644 index 0000000000..4892627cdb --- /dev/null +++ b/app/Rules/BelongsUser.php @@ -0,0 +1,148 @@ +parseAttribute($attribute); + if (!auth()->check()) { + return true; + } + $attribute = strval($attribute); + switch ($attribute) { + case 'piggy_bank_id': + $count = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') + ->where('piggy_banks.id', '=', intval($value)) + ->where('accounts.user_id', '=', auth()->user()->id)->count(); + + return $count === 1; + break; + case 'piggy_bank_name': + $count = $this->countField(PiggyBank::class, 'name', $value); + + return $count === 1; + break; + case 'bill_id': + $count = Bill::where('id', '=', intval($value))->where('user_id', '=', auth()->user()->id)->count(); + + return $count === 1; + case 'budget_id': + $count = Budget::where('id', '=', intval($value))->where('user_id', '=', auth()->user()->id)->count(); + + return $count === 1; + break; + case 'category_id': + $count = Category::where('id', '=', intval($value))->where('user_id', '=', auth()->user()->id)->count(); + + return $count === 1; + break; + case 'budget_name': + $count = $this->countField(Budget::class, 'name', $value); + + return $count === 1; + break; + case 'source_account_id': + case 'destination_account_id': + $count = Account::where('id', '=', intval($value))->where('user_id', '=', auth()->user()->id)->count(); + + return $count === 1; + break; + case 'bill_name': + $count = $this->countField(Bill::class, 'name', $value); + + return $count === 1; + break; + default: + throw new FireflyException(sprintf('Rule BelongUser cannot handle "%s"', $attribute)); + } + } + + /** + * @param string $class + * @param string $field + * @param string $value + * + * @return int + */ + protected function countField(string $class, string $field, string $value): int + { + // get all objects belonging to user: + switch ($class) { + case PiggyBank::class: + $objects = PiggyBank::leftJoin('accounts', 'accounts.id', '=', 'piggy_banks.account_id') + ->where('accounts.user_id', '=', auth()->user()->id)->get(['piggy_banks.*']); + break; + default: + $objects = $class::where('user_id', '=', auth()->user()->id)->get(); + break; + } + $count = 0; + foreach ($objects as $object) { + if (trim(strval($object->$field)) === trim($value)) { + $count++; + } + } + + return $count; + } + + /** + * @param string $attribute + * + * @return string + */ + private function parseAttribute(string $attribute): string + { + $parts = explode('.', $attribute); + if (count($parts) === 1) { + return $attribute; + } + if (count($parts) === 3) { + return $parts[2]; + } + + return $attribute; + } +}