diff --git a/app/Api/V1/Controllers/User/PreferencesController.php b/app/Api/V1/Controllers/User/PreferencesController.php new file mode 100644 index 0000000000..255e993979 --- /dev/null +++ b/app/Api/V1/Controllers/User/PreferencesController.php @@ -0,0 +1,136 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers\User; + +use FireflyIII\Api\V1\Controllers\Controller; +use FireflyIII\Api\V1\Requests\User\PreferenceStoreRequest; +use FireflyIII\Api\V1\Requests\User\PreferenceUpdateRequest; +use FireflyIII\Models\Preference; +use FireflyIII\Transformers\PreferenceTransformer; +use Illuminate\Http\JsonResponse; +use Illuminate\Pagination\LengthAwarePaginator; +use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use League\Fractal\Resource\Collection as FractalCollection; +use League\Fractal\Resource\Item; + +/** + * Class PreferencesController + */ +class PreferencesController extends Controller +{ + public const DATE_FORMAT = 'Y-m-d'; + public const RESOURCE_KEY = 'preferences'; + + /** + * List all of them. + * + * @return JsonResponse + * @codeCoverageIgnore + */ + public function index(): JsonResponse + { + // TODO via repository. + $collection = auth()->user()->preferences()->get(); + $manager = $this->getManager(); + $count = $collection->count(); + $pageSize = (int)app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + $preferences = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + + // make paginator: + $paginator = new LengthAwarePaginator($preferences, $count, $pageSize, $this->parameters->get('page')); + $paginator->setPath(route('api.v1.preferences.index') . $this->buildParams()); + + /** @var PreferenceTransformer $transformer */ + $transformer = app(PreferenceTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new FractalCollection($preferences, $transformer, self::RESOURCE_KEY); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + + } + + /** + * @param PreferenceStoreRequest $request + * + * @return JsonResponse + */ + public function store(PreferenceStoreRequest $request): JsonResponse + { + $manager = $this->getManager(); + $data = $request->getAll(); + $pref = app('preferences')->set($data['name'], $data['data']); + + /** @var PreferenceTransformer $transformer */ + $transformer = app(PreferenceTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new Item($pref, $transformer, 'preferences'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } + + /** + * @param PreferenceUpdateRequest $request + * + * @return JsonResponse + */ + public function update(PreferenceUpdateRequest $request, Preference $preference): JsonResponse + { + $manager = $this->getManager(); + $data = $request->getAll(); + $pref = app('preferences')->set($preference->name, $data['data']); + + /** @var PreferenceTransformer $transformer */ + $transformer = app(PreferenceTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new Item($pref, $transformer, 'preferences'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } + + /** + * Return a single preference by name. + * + * @param Preference $preference + * + * @return JsonResponse + * @codeCoverageIgnore + */ + public function show(Preference $preference): JsonResponse + { + $manager = $this->getManager(); + /** @var PreferenceTransformer $transformer */ + $transformer = app(PreferenceTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new Item($preference, $transformer, 'preferences'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); + } + +} diff --git a/app/Api/V1/Controllers/todo-Preferences/IndexController.php b/app/Api/V1/Controllers/todo-Preferences/IndexController.php deleted file mode 100644 index 0562e4b382..0000000000 --- a/app/Api/V1/Controllers/todo-Preferences/IndexController.php +++ /dev/null @@ -1,103 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Api\V1\Controllers\Preferences; - -use Carbon\Carbon; -use FireflyIII\Api\V1\Controllers\Controller; -use FireflyIII\Repositories\Journal\JournalRepositoryInterface; -use FireflyIII\Support\Facades\Navigation; -use Illuminate\Http\JsonResponse; - -/** - * Class IndexController - */ -class IndexController extends Controller -{ - public const DATE_FORMAT = 'Y-m-d'; - - /** - * Return users preferred date range settings, the current period - * and some previous / next periods. - * - * TODO unused and undocumented. - * - * @return JsonResponse - */ - public function dateRanges(): JsonResponse - { - $range = app('preferences')->get('viewRange', '1M')->data; - $return = [ - 'range' => $range, - 'ranges' => [], - 'default' => null, - ]; - $today = Carbon::today(config('app.timezone')); - $start = Navigation::startOfPeriod($today, $range); - $todayStr = $today->format(self::DATE_FORMAT); - // optional date ranges. Maybe to be configured later - // current $period - $title = (string)Navigation::periodShow($start, $range); - $return['default'] = $title; - $return['ranges'][$title] = [$start->format(self::DATE_FORMAT), - Navigation::endOfPeriod($start, $range)->format(self::DATE_FORMAT)]; - // previous $period - $previousStart = Navigation::subtractPeriod($start, $range); - $title = (string)Navigation::periodShow($previousStart, $range); - $return['ranges'][$title] = [$previousStart->format(self::DATE_FORMAT), - Navigation::endOfPeriod($previousStart, $range)->format(self::DATE_FORMAT)]; - // next $period - $nextStart = Navigation::addPeriod($start, $range, 0); - $title = (string)Navigation::periodShow($nextStart, $range); - $return['ranges'][$title] = [$nextStart->format(self::DATE_FORMAT), - Navigation::endOfPeriod($nextStart, $range)->format(self::DATE_FORMAT)]; - // -- - // last seven days: - $seven = Carbon::today()->subDays(7); - $title = (string)trans('firefly.last_seven_days'); - $return['ranges'][$title] = [$seven->format(self::DATE_FORMAT), $todayStr]; - // last 30 days: - $thirty = Carbon::today()->subDays(30); - $title = (string)trans('firefly.last_thirty_days'); - $return['ranges'][$title] = [$thirty->format(self::DATE_FORMAT), $todayStr]; - // last 180 days - $long = Carbon::today()->subDays(180); - $title = (string)trans('firefly.last_180_days'); - $return['ranges'][$title] = [$long->format(self::DATE_FORMAT), $todayStr]; - // YTD - $YTD = Carbon::today()->startOfYear(); - $title = (string)trans('firefly.YTD'); - $return['ranges'][$title] = [$YTD->format(self::DATE_FORMAT), $todayStr]; - // --- - // everything - $repository = app(JournalRepositoryInterface::class); - $journal = $repository->firstNull(); - $first = null === $journal ? clone $YTD : clone $journal->date; - $title = (string)trans('firefly.everything'); - $return['ranges'][$title] = [$first->format(self::DATE_FORMAT), $todayStr]; - - return response()->json($return); - } - -} diff --git a/app/Api/V1/Controllers/todo-System/DynamicConfigController.php b/app/Api/V1/Controllers/todo-System/DynamicConfigController.php deleted file mode 100644 index a4ad055ce0..0000000000 --- a/app/Api/V1/Controllers/todo-System/DynamicConfigController.php +++ /dev/null @@ -1,124 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Api\V1\Controllers\System; - -use FireflyIII\Api\V1\Controllers\Controller; -use FireflyIII\Api\V1\Requests\ConfigurationRequest; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Configuration; -use FireflyIII\Repositories\User\UserRepositoryInterface; -use Illuminate\Http\JsonResponse; - -/** - * Class DynamicConfigController. - * - * @codeCoverageIgnore - */ -class DynamicConfigController extends Controller -{ - private UserRepositoryInterface $repository; - - /** - * ConfigurationController constructor. - */ - public function __construct() - { - parent::__construct(); - $this->middleware( - function ($request, $next) { - $this->repository = app(UserRepositoryInterface::class); - - return $next($request); - } - ); - } - - /** - * Show all configuration. - * - * @return JsonResponse - */ - public function index(): JsonResponse - { - $configData = $this->getConfigData(); - - return response()->json(['data' => $configData])->header('Content-Type', self::CONTENT_TYPE); - } - /** - * Show all configuration. - * - * @param string $value - * @return JsonResponse - */ - public function show(string $value): JsonResponse - { - $configData = $this->getConfigData(); - - return response()->json([$value => $configData[$value]])->header('Content-Type', self::CONTENT_TYPE); - } - - /** - * Get all config values. - * - * @return array - */ - private function getConfigData(): array - { - /** @var Configuration $isDemoSite */ - $isDemoSite = app('fireflyconfig')->get('is_demo_site'); - /** @var Configuration $updateCheck */ - $updateCheck = app('fireflyconfig')->get('permission_update_check'); - /** @var Configuration $lastCheck */ - $lastCheck = app('fireflyconfig')->get('last_update_check'); - /** @var Configuration $singleUser */ - $singleUser = app('fireflyconfig')->get('single_user_mode'); - - return [ - 'is_demo_site' => null === $isDemoSite ? null : $isDemoSite->data, - 'permission_update_check' => null === $updateCheck ? null : (int)$updateCheck->data, - 'last_update_check' => null === $lastCheck ? null : (int)$lastCheck->data, - 'single_user_mode' => null === $singleUser ? null : $singleUser->data, - ]; - } - - /** - * Update the configuration. - * - * @param ConfigurationRequest $request - * @param string $name - * - * @return JsonResponse - */ - public function update(ConfigurationRequest $request, string $name): JsonResponse - { - if (!$this->repository->hasRole(auth()->user(), 'owner')) { - throw new FireflyException('200005: You need the "owner" role to do this.'); // @codeCoverageIgnore - } - $data = $request->getAll(); - app('fireflyconfig')->set($name, $data['value']); - $configData = $this->getConfigData(); - - return response()->json(['data' => $configData])->header('Content-Type', self::CONTENT_TYPE); - } -} diff --git a/app/Api/V1/Controllers/todo-System/StaticConfigController.php b/app/Api/V1/Controllers/todo-System/StaticConfigController.php deleted file mode 100644 index 7361697e8f..0000000000 --- a/app/Api/V1/Controllers/todo-System/StaticConfigController.php +++ /dev/null @@ -1,74 +0,0 @@ -. - */ - -namespace FireflyIII\Api\V1\Controllers\System; - - -use FireflyIII\Api\V1\Controllers\Controller; -use FireflyIII\Support\Binder\StaticConfigKey; -use Illuminate\Http\JsonResponse; - -/** - * Class StaticConfigController - * - * Show specific Firefly III configuration and/or ENV vars. - */ -class StaticConfigController extends Controller -{ - private array $list; - - /** - * EnvController constructor. - */ - public function __construct() - { - parent::__construct(); - $this->list = StaticConfigKey::$accepted; - } - - /** - * Show all available env variables. - * - * @return JsonResponse - */ - public function index(): JsonResponse - { - $vars = []; - // show all Firefly III config vars. - foreach ($this->list as $key) { - $vars[$key] = config($key); - } - - return response()->json($vars); - } - - /** - * @param string $staticKey - * - * @return JsonResponse - */ - public function show(string $staticKey): JsonResponse - { - $response = [$staticKey => config($staticKey)]; - - return response()->json($response); - } -} diff --git a/app/Api/V1/Controllers/todo/PreferenceController.php b/app/Api/V1/Controllers/todo/PreferenceController.php index 754c8cbeb7..4451d5465b 100644 --- a/app/Api/V1/Controllers/todo/PreferenceController.php +++ b/app/Api/V1/Controllers/todo/PreferenceController.php @@ -1,7 +1,7 @@ getManager(); - /** @var PreferenceTransformer $transformer */ - $transformer = app(PreferenceTransformer::class); - $transformer->setParameters($this->parameters); - $resource = new Item($preference, $transformer, 'preferences'); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', self::CONTENT_TYPE); - } /** * Update a preference. diff --git a/app/Api/V1/Requests/User/PreferenceStoreRequest.php b/app/Api/V1/Requests/User/PreferenceStoreRequest.php new file mode 100644 index 0000000000..38f4eca932 --- /dev/null +++ b/app/Api/V1/Requests/User/PreferenceStoreRequest.php @@ -0,0 +1,66 @@ +. + */ + +namespace FireflyIII\Api\V1\Requests\User; + + +use FireflyIII\Support\Request\ChecksLogin; +use FireflyIII\Support\Request\ConvertsDataTypes; +use Illuminate\Foundation\Http\FormRequest; + +class PreferenceStoreRequest extends FormRequest +{ + use ChecksLogin, ConvertsDataTypes; + + /** + * @return array + */ + public function getAll(): array + { + $array = [ + 'name' => $this->string('name'), + 'data' => $this->get('data'), + ]; + if ('true' === $array['data']) { + $array['data'] = true; + } + if ('false' === $array['data']) { + $array['data'] = false; + } + if(is_numeric($array['data'])) { + $array['data'] = (float)$array['data']; + } + + return $array; + } + + /** + * @return string[] + */ + public function rules(): array + { + return [ + 'name' => 'required', + 'data' => 'required', + ]; + } + +} \ No newline at end of file diff --git a/app/Api/V1/Requests/User/PreferenceUpdateRequest.php b/app/Api/V1/Requests/User/PreferenceUpdateRequest.php new file mode 100644 index 0000000000..2dcf0f1f86 --- /dev/null +++ b/app/Api/V1/Requests/User/PreferenceUpdateRequest.php @@ -0,0 +1,65 @@ +. + */ + +namespace FireflyIII\Api\V1\Requests\User; + + +use FireflyIII\Support\Request\ChecksLogin; +use FireflyIII\Support\Request\ConvertsDataTypes; +use Illuminate\Foundation\Http\FormRequest; + +class PreferenceUpdateRequest extends FormRequest +{ + use ChecksLogin, ConvertsDataTypes; + + /** + * @return array + */ + public function getAll(): array + { + $array = [ + 'name' => $this->string('name'), + 'data' => $this->get('data'), + ]; + if ('true' === $array['data']) { + $array['data'] = true; + } + if ('false' === $array['data']) { + $array['data'] = false; + } + if(is_numeric($array['data'])) { + $array['data'] = (float)$array['data']; + } + + return $array; + } + + /** + * @return string[] + */ + public function rules(): array + { + return [ + 'data' => 'required', + ]; + } + +} \ No newline at end of file diff --git a/app/Transformers/PreferenceTransformer.php b/app/Transformers/PreferenceTransformer.php index 04d11310b3..89c6db70e8 100644 --- a/app/Transformers/PreferenceTransformer.php +++ b/app/Transformers/PreferenceTransformer.php @@ -32,19 +32,6 @@ use Log; */ class PreferenceTransformer extends AbstractTransformer { - - /** - * PreferenceTransformer constructor. - * - * @codeCoverageIgnore - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - /** * Transform the preference * diff --git a/routes/api.php b/routes/api.php index 0e1b4ac06f..50a3629461 100644 --- a/routes/api.php +++ b/routes/api.php @@ -521,6 +521,20 @@ Route::group( } ); +// Preference API routes: +Route::group( + ['namespace' => 'FireflyIII\Api\V1\Controllers\User', 'prefix' => 'preferences', + 'as' => 'api.v1.preferences.',], + static function () { + Route::get('', ['uses' => 'PreferencesController@index', 'as' => 'index']); + Route::post('', ['uses' => 'PreferencesController@store', 'as' => 'store']); + Route::get('{preference}', ['uses' => 'PreferencesController@show', 'as' => 'show']); + Route::put('{preference}', ['uses' => 'PreferencesController@update', 'as' => 'update']); + } +); + + + @@ -604,20 +618,7 @@ Route::group( -// -// -//// TODO VERIFY API DOCS -//Route::group( -// ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'preferences', -// 'as' => 'api.v1.preferences.',], -// static function () { -// -// // Preference API routes: -// Route::get('', ['uses' => 'PreferenceController@index', 'as' => 'index']); -// Route::get('date-ranges', ['uses' => 'Preferences\IndexController@dateRanges', 'as' => 'date-ranges']); -// Route::get('{preference}', ['uses' => 'PreferenceController@show', 'as' => 'show']); -// Route::put('{preference}', ['uses' => 'PreferenceController@update', 'as' => 'update']); -// } + //);