diff --git a/app/Http/Controllers/BlogArticleController.php b/app/Http/Controllers/BlogArticleController.php index b4c42e4..9423546 100644 --- a/app/Http/Controllers/BlogArticleController.php +++ b/app/Http/Controllers/BlogArticleController.php @@ -2,11 +2,20 @@ namespace App\Http\Controllers; +use App\Http\Requests\BlogArticleRequest; +use App\Http\Services\AuthService; use App\Models\BlogArticle; use Illuminate\Http\Request; class BlogArticleController extends Controller { + private $authService; + + public function __construct(AuthService $authService) + { + $this->authService = $authService; + } + /** * Display a listing of the resource. * @@ -14,7 +23,15 @@ class BlogArticleController extends Controller */ public function index() { - return response()->json([]); + $query = BlogArticle::orderBy('date', 'desc'); + + if (!$this->authService->isAuthenticated()) { + $query = $query->where('published', true); + } + + $data = $query->paginate(25); + + return response()->json($data); } /** @@ -24,7 +41,13 @@ class BlogArticleController extends Controller */ public function recent() { - $data = BlogArticle::orderBy('date', 'desc')->limit(5)->get(); + $query = BlogArticle::orderBy('date', 'desc'); + + if (!$this->authService->isAuthenticated()) { + $query = $query->where('published', true); + } + + $data = $query->limit(5)->get(); return response()->json($data); } @@ -36,18 +59,26 @@ class BlogArticleController extends Controller */ public function popular() { - return response()->json([]); + $query = BlogArticle::orderBy('views', 'desc')->orderBY('date', 'desc'); + + if (!$this->authService->isAuthenticated()) { + $query = $query->where('published', true); + } + + $data = $query->limit(5)->get(); + return response()->json($data); } /** * Store a newly created resource in storage. * - * @param \Illuminate\Http\Request $request + * @param \App\Http\Requests\BlogArticleRequest $request * @return \Illuminate\Http\JsonResponse */ - public function store(Request $request) + public function store(BlogArticleRequest $request) { - return response()->json([]); + $article = BlogArticle::create($request->all()); + return response()->json($article, 201); } /** @@ -58,29 +89,42 @@ class BlogArticleController extends Controller */ public function show(BlogArticle $blogArticle) { - return response()->json([]); + if (!$this->authService->isAuthenticated() && !$blogArticle->published) { + abort(404); + } + + $blogArticle->views += 1; + $blogArticle->save(); + + return response()->json($blogArticle); } /** * Update the specified resource in storage. * - * @param \Illuminate\Http\Request $request + * @param \App\Http\Requests\BlogArticleRequest $request * @param \App\Models\BlogArticle $blogArticle - * @return \Illuminate\Http\JsonResponse + * @return \Illuminate\Http\Response */ - public function update(Request $request, BlogArticle $blogArticle) + public function update(BlogArticleRequest $request, BlogArticle $blogArticle) { - return response()->json([]); + $blogArticle->update($request->all()); + return response(null, 204); } /** * Remove the specified resource from storage. * * @param \App\Models\BlogArticle $blogArticle - * @return \Illuminate\Http\JsonResponse + * @return \Illuminate\Http\Response */ public function destroy(BlogArticle $blogArticle) { - return response()->json([]); + if (!$this->authService->isAuthenticated()) { + abort(401); + } + + $blogArticle->delete(); + return response(null, 204); } } diff --git a/app/Http/Requests/BlogArticleRequest.php b/app/Http/Requests/BlogArticleRequest.php new file mode 100644 index 0000000..094ecd4 --- /dev/null +++ b/app/Http/Requests/BlogArticleRequest.php @@ -0,0 +1,77 @@ +authService = $authService; + } + + /** + * Determine if the user is authorized to make this request. + * + * @return bool + */ + public function authorize() + { + return $this->authService->isAuthenticated(); + } + + /** + * Run before validating data + */ + protected function prepareForValidation() + { + if (!$this->exists('slug')) { + $this->merge([ + 'slug' => Str::slug($this->get('title')), + ]); + } + + if (!$this->exists('date')) { + $this->merge([ + 'date' => Carbon::now()->toDateTime(), + ]); + } + + if (!$this->exists('summary')) { + $content = $this->get('content'); + $pos = -1; + if (strlen($content) > 200) { + $pos = strpos($content, ' ', 200); + } + $summary = substr($content, 0, $pos); + + $this->merge([ + 'summary' => $summary, + ]); + } + } + + /** + * Get the validation rules that apply to the request. + * + * @return array + */ + public function rules() + { + return [ + 'title' => 'required|string|max:255', + 'slug' => 'required|string|max:255', + 'date' => 'required|date', + 'summary' => 'required|string|max:1023', + 'content' => 'required|string', + ]; + } +} diff --git a/app/Http/Services/AuthService.php b/app/Http/Services/AuthService.php new file mode 100644 index 0000000..52ca0ac --- /dev/null +++ b/app/Http/Services/AuthService.php @@ -0,0 +1,26 @@ +put('auth', true); + } + + public function logout() + { + session()->remove('auth'); + } +} diff --git a/app/Models/BlogArticle.php b/app/Models/BlogArticle.php index abd64e0..c7a8acd 100644 --- a/app/Models/BlogArticle.php +++ b/app/Models/BlogArticle.php @@ -14,12 +14,17 @@ class BlogArticle extends Model 'slug', 'date', 'summary', - 'content' + 'content', + 'views', + 'published' ]; protected $casts = [ + 'id' => 'integer', 'created_at' => 'datetime', 'updated_at' => 'datetime', 'date' => 'datetime', + 'views' => 'integer', + 'published' => 'boolean', ]; } diff --git a/database/factories/BlogArticleFactory.php b/database/factories/BlogArticleFactory.php index 56bfe65..01dee9e 100644 --- a/database/factories/BlogArticleFactory.php +++ b/database/factories/BlogArticleFactory.php @@ -27,6 +27,8 @@ class BlogArticleFactory extends Factory 'date' => $this->faker->dateTimeBetween('100d'), 'summary' => $this->faker->text(200), 'content' => $this->faker->text(1000), + 'views' => $this->faker->numberBetween(0, 50), + 'published' => $this->faker->boolean(80), ]; } } diff --git a/database/migrations/2021_09_01_201822_create_blog_articles_table.php b/database/migrations/2021_09_01_201822_create_blog_articles_table.php index 2e52854..6e22ede 100644 --- a/database/migrations/2021_09_01_201822_create_blog_articles_table.php +++ b/database/migrations/2021_09_01_201822_create_blog_articles_table.php @@ -17,11 +17,13 @@ class CreateBlogArticlesTable extends Migration $table->id(); $table->timestamps(); - $table->string('title'); - $table->string('slug'); + $table->string('title', 255); + $table->string('slug', 255); $table->dateTime('date'); - $table->string('summary'); + $table->string('summary', 1023); $table->text('content'); + $table->integer('views')->default(0); + $table->boolean('published'); }); } diff --git a/routes/api.php b/routes/api.php index 707fc28..ab553f8 100644 --- a/routes/api.php +++ b/routes/api.php @@ -23,14 +23,3 @@ Route::get('/blog/recent', [\App\Http\Controllers\BlogArticleController::class, Route::get('/blog/popular', [\App\Http\Controllers\BlogArticleController::class, 'popular']); Route::resource('/blog', \App\Http\Controllers\BlogArticleController::class)->except(['create', 'edit']); -Route::get('/blog/popular', function() { - return [ - ['title' => 'Lorem, ipsum dolor sit amet consectetur adipisicing.', 'id' => 1], - ['title' => 'Lorem, ipsum dolor sit amet consectetur adipisicing.', 'id' => 2], - ['title' => 'Lorem, ipsum dolor sit amet consectetur adipisicing.', 'id' => 3], - ['title' => 'Lorem, ipsum dolor sit.', 'id' => 4], - ['title' => 'Lorem, ipsum dolor sit amet consectetur adipisicing.', 'id' => 5], - ['title' => 'Lorem, ipsum dolor sit amet consectetur adipisicing.', 'id' => 6], - ['title' => 'Lorem, ipsum dolor sit amet consectetur adipisicing.', 'id' => 7], - ]; -});