创建控制器(创建完成之后生成的文件在 app/Http/Controllers/ 下)
>php artisan make:controller AuthController
>php artisan make:controller RecipeController
添加路由 (路径:routes/api.php)
<?php
Route::post('/register', 'AuthController@register');
Route::post('/login', 'AuthController@login');
Route::post('/logout', 'AuthController@logout');
Route::resource('recipes', 'RecipeController');
修改 AuthController.php 控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
use Hash;
class AuthController extends Controller
{
public function __construct()
{
$this->middleware('auth:api')->only('logout');
}
public function register(Request $request){
$this->validate($request, [
'name' => 'required|max:255',
'email' => 'required|email|unique:users',
'password' => 'required|between:6,25|confirmed'
]);
$user = new User($request->all());
$user->password = bcrypt($request->password);
$user->save();
return response()->json([
'registered' => true
]);
}
public function login(Request $request){
$this->validate($request, [
'email' => 'required|email',
'password' => 'required|between:6,25'
]);
$user = User::where('email', $request->email)->first();
if($user && Hash::check($request->password, $user->password)){
$user->api_token = str_random(60);
$user->save();
return response()->json([
'authenticated' => true,
'api_token' => $user->api_token,
'user_id' => $user->id
]);
}
return response()->json([
'email' => '提供的电子邮件和密码不匹配!'
], 422);
}
public function logout(Request $request){
$user = $request->user();
$user->api_token = null;
$user->save();
return response()->json(['logged_out' => true]);
}
}
修改RecipeController.php 控制器
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Recipe;
use App\RecipeIngredient;
use App\RecipeDirection;
use File;
class RecipeController extends Controller
{
public function __construct()
{
$this->middleware('auth:api')->except('index', 'show');
}
public function index(){
$recipes = Recipe::orderBy('created_at','desc')->get(['name','image','id']);
return response()->json(['recipes' => $recipes]);
}
public function create(){
$form = Recipe::form();
return response()->json(['form' => $form]);
}
public function store(Request $request){
$this->validate($request, [
'name' => 'required|max:255',
'description' => 'required|max:3000',
'image' => 'required|image',
'ingredients' => 'required|array|min:1',
'ingredients.*.name' => 'required|max:255',
'ingredients.*.qty' => 'required|max:255',
'directions' => 'required|array|min:1',
'directions.*.description' => 'required|max:3000'
]);
$ingredients = [];
foreach ($request->ingredients as $ingredient){
$ingredients[] = new RecipeIngredient($ingredient);
}
$directions = [];
foreach ($request->directions as $direction){
$directions[] = new RecipeDirection($direction);
}
if(!$request->hasFile('image') && !$request->file('image')->isValid()){
return abort(404, '图片没有上传');
}
$filename = $this->getFileName($request->image);
$request->image->move(base_path('public/images'), $filename);
$recipe = new Recipe($request->all());
$recipe->image = $filename;
$request->user()->recipes()->save($recipe);
$recipe->directions()->saveMany($directions);
$recipe->ingredients()->saveMany($ingredients);
return response()->json([
'saved' =>true,
'id' => $recipe->id,
'filename' => $filename,
'message' => '食谱创建成功!'
]);
}
protected function getFileName($file){
return str_random(32).'.'.$file->extension();
}
public function show($id){
$recipe = Recipe::with(['user','ingredients', 'directions'])->findOrFail($id);
return response()->json(['recipe' => $recipe]);
}
public function edit($id, Request $request){
$form = $request->user()->recipes()
->with(['ingredients' => function($query){
$query->get(['id','name','qty']);
}, 'directions' => function($query){
$query->get(['id','description']);
}])
->findOrFail($id, [
'id','name','description','image'
]);
return response()->json(['form' => $form]);
}
public function update($id, Request $request){
$this->validate($request, [
'name' => 'required|max:255',
'description' => 'required|max:3000',
'image' => 'image',
'ingredients' => 'required|array|min:1',
'ingredients.*.id' => 'integer|exists:recipe_ingredients',
'ingredients.*.name' => 'required|max:255',
'ingredients.*.qty' => 'required|max:255',
'directions' => 'required|array|min:1',
'directions.*.id' => 'integer|exists:recipe_directions',
'directions.*.description' => 'required|max:3000'
]);
$recipe = $request->user()->recipes()->findOrFail($id);
$ingredients = [];
$ingredientsUpdated = [];
foreach ($request->ingredients as $ingredient){
if(isset($ingredient['id'])){
RecipeIngredient::where('recipe_id', $recipe->id)
->where('id', $ingredient['id'])
->update($ingredient);
$ingredientsUpdated[] = $ingredient['id'];
}else{
$ingredients[] = new RecipeIngredient($ingredient);
}
}
$directions = [];
$directionsUpdated = [];
foreach ($request->directions as $direction){
if(isset($direction['id'])){
RecipeDirection::where('recipe_id', $recipe->id)
->where('id', $direction['id'])
->update($direction);
$directionsUpdated[] = $direction['id'];
}else{
$directions[] = new RecipeDirection($direction);
}
}
$recipe->name = $request->name;
$recipe->description = $request->description;
if($request->hasFile('image') && $request->file('image')->isValid()){
$filename = $this->getFileName($request->image);
$request->image->move(base_path('public/images'),$filename);
File::delete(base_path('public/images/'.$recipe->image));
$recipe->image = $filename;
}
$recipe->save();
RecipeIngredient::whereNotIn('id', $ingredientsUpdated)
->where('recipe_id', $recipe->id)->delete();
RecipeDirection::whereNotIn('id', $directionsUpdated)
->where('recipe_id', $recipe->id)->delete();
if(count($ingredients)){
$recipe->ingredients()->saveMany($ingredients);
}
if(count($ingredients)){
$recipe->directions()->saveMany($directions);
}
return response()->json([
'saved' => true,
'id' => $recipe->id,
'message' => '更新食谱成功!'
]);
}
public function destroy($id, Request $request){
$recipe = $request->user()->recipes()->findOrFail($id);
RecipeIngredient::where('recipe_id', $recipe->id)->delete();
RecipeDirection::where('recipe_id', $recipe->id)->delete();
File::delete(base_path('public/images/'.$recipe->image));
$recipe->delete();
return response()->json([
'deleted' => true
]);
}
}