用laravel4.2实现一个简单的图片墙博客(三)控制器(Controller)

至此,我们完成了数据库的建立和初始填充工作,也建立的三个主要对象的模型User, Picture, Comment,接下来要实现控制器部分了。

与其把所有路由逻辑写在一个 routes.php 文件中,你也许更希望用控制器类来组织它们。控制器可以把相关的路由逻辑组织在一个类中,而且可以使用由框架提供的更为强大的功能,比如自动依赖注入。关于控制器方面的文档参看

一.创建控制器

在Laravel中,我们通过扩展 app/controllers 目录的BaseController类来创建控制器,我们所有的控制器都存在app/controllers目录中。文件管理方面这一点类似MODEL,使用一个文件当作入口来管理所有的同类文件。

1#......BaseController.php

这是基控制器,$layout指定了初始布局,指向views目录下的master.blade.php。

调用setupLayout方法在控制器有非空布局时实现这个布局。其他的控制器基本都可以继承该控制器。

<?php

class BaseController extends \Controller {


	/**
	 * layout to use
	 * @var View
	 */
	protected $layout = 'master';

	/**
	 * Setup the layout used by the controller.
	 *
	 * @return void
	 */
	protected function setupLayout()
	{
		if ( ! is_null($this->layout) )
		{
			$this->layout = View::make($this->layout);
		}
	}

}

2#......BlogController.php

__construct使我们能够在控制器内部指定过滤器,过滤器的定义在app/filters.php。

getIndex()获取主页显示的元素,每页显示20张图片,调用布局home,在home.blade.php中的{{content}}部分填充布局index,布局由构造出的20张图片的键值对数组生成,这一步相当于显示了主页。

getLogin()获取验证状态并转移页面到管理员控制面板

getLogout()登出用户

postRegister()注册验证,需要验证未使用用户名和未使用的邮箱地址

postLogin()登陆验证

<?php

use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Schema;
class BlogController extends BaseController
{


    public function __construct()
    {
        //updated: prevents re-login.
        $this->beforeFilter('guest', ['only' => ['getLogin']]);
        $this->beforeFilter('auth', ['only' => ['getLogout']]);
    }

    public function getIndex()
    {
        $pictures = Picture::orderBy('id', 'desc')->paginate(10);
        $pictures->getFactory()->setViewName('pagination::slider');
        $this->layout->title = 'Home Page | Picture Wall Blog';
        $this->layout->main = View::make('home')->nest('content', 'index', compact('pictures'));
    }

    public function getSearch()
    {
    	$searchTerm = Input::get('s');
    	$pictures = Picture::whereRaw('match(title,description) against(? in boolean mode)', [$searchTerm])
    	->paginate(10);
    	$pictures->getFactory()->setViewName('pagination::slider');
    	$pictures->appends(['s' => $searchTerm]);
    	$this->layout->with('title', 'Search: ' . $searchTerm);
    	$this->layout->main = View::make('home')
    	->nest('content', 'index', ($pictures->isEmpty()) ? ['notFound' => true] : compact('pictures'));
    }
    public function getLiking()
    {
    	$pic_id = Input::get('pic_id');
    	if (Auth::check()){
    		$user_id = Auth::user()->id;
    	} else return 'not logined';
    	$like = DB::connection('mongodb')->table('likes')->where('picture_id', '=', $pic_id)->where('user_id', '=', $user_id)->get();
    	if (!empty($like)) return 'voted';
    	DB::connection('mongodb')->table('likes')->insert(array('user_id' => $user_id, 'picture_id' => $pic_id));
    	$count = DB::connection('mongodb')->table('count')->where('picture_id', '=', $pic_id)->lists('count');
    	if (empty($count)){
    		DB::connection('mongodb')->table('count')->insert(array('picture_id'=>$pic_id, 'count'=>'1'));
    	} else{
    		$up = $count[0]+1;
    		DB::connection('mongodb')->table('count')->where('picture_id',$pic_id)->
    				update(array('count'=>$up));
    	}
    	return "ok";
    	
    }
    public function getLikes()
    {
    	$pic_id = Input::get('pic_id');
    	$likecount = DB::connection('mongodb')->table('count')->where('picture_id', $pic_id)->lists('count');
    	if (empty($likecount)) return 0;
    	return $likecount[0];
    }
    public function getLogin()
    {
        $this->layout->title = 'login';
        $this->layout->main = View::make('login');
    }
	
    public function getRegister()
    {
    	$this->layout->title = 'register';
    	$this->layout->main = View::make('register');
    }
    
    public function postRegister()
    {
    	$credentials = [
    	'username' => Input::get('username'),
    	'password' => Input::get('password'),
    	'email' => Input::get('email')
    	];
    	$rules = [
    	'username' => 'required',
    	'password' => 'required',
    	'email' => 'required|email'
    			];
    	$validator = Validator::make($credentials, $rules);
    	if ($validator->passes()) {
    		$userCheck = DB::table('users')->where('username',$credentials['username'])->get();
    		if (!empty($userCheck)){
    			return Redirect::back()->withInput()->with('failure', 'username already exists!');
    		}
    		$emailCheck = DB::table('users')->where('email',$credentials['email'])->get();
    		if (!empty($emailCheck)){
    			return Redirect::back()->withInput()->with('failure', 'mail address already exists!');
    		}
    		$user = array(
            'username' => $credentials['username'],
            'password' => Hash::make($credentials['password']),
    		'email' => $credentials['email'],
            'created_at' => DB::raw('NOW()'),
            'updated_at' => DB::raw('NOW()'),
       	 	);
    		DB::table('users')->insert($user);
    		Auth::attempt($credentials);
    		return Redirect::to('admin/dash-board')->withInput()->with('success', 'register succeed!!!');
    	} else {
    		return Redirect::back()->withErrors($validator)->withInput();
    	}
    }
    
    public function postLogin()
    {
    	if (strcmp($_POST['operation'],"Register") == 0) return Redirect::to('register');
        $credentials = [
            'username' => Input::get('username'),
            'password' => Input::get('password')
        ];
        $rules = [
            'username' => 'required',
            'password' => 'required'
        ];
        $validator = Validator::make($credentials, $rules);
        if ($validator->passes()) {
            if (Auth::attempt($credentials))
                return Redirect::to('admin/dash-board');
            return Redirect::back()->withInput()->with('failure', 'username or password is invalid!');
        } else {
            return Redirect::back()->withErrors($validator)->withInput();
        }
    }

    public function getLogout()
    {
        Auth::logout();
        return Redirect::to('/');
    }

}



3#......PictureController.php

该文件定义了Picture的控制器,包括列举Picture,显示Picture,新建、编辑的界面,删除、保存、更新的操作等。这些方法会在app/routes.php中被引用。

其中用到了验证器的相关知识(请注意正则匹配的格式),参考 

<?php

class PictureController extends BaseController
{

    /* get functions */
    public function listPicture()
    {
        $pictures = Picture::orderBy('id', 'desc')->paginate(10);
        $this->layout->title = 'Picture listings';
        $this->layout->main = View::make('dash')->nest('content', 'pictures.list', compact('pictures'));
    }

    public function showPicture(Picture $picture)
    {
        $comments = $picture->comments()->get();
        $this->layout->title = $picture->title;
        $this->layout->main = View::make('home')->nest('content', 'pictures.single', compact('picture', 'comments'));
    }

    public function newPicture()
    {
        $this->layout->title = 'New Picture';
        $this->layout->main = View::make('dash')->nest('content', 'pictures.new');
    }

    public function editPicture(Picture $picture)
    {
        $this->layout->title = 'Edit Picture';
        $this->layout->main = View::make('dash')->nest('content', 'pictures.edit', compact('picture'));
    }

    public function deletePicture(Picture $picture)
    {
    	DB::connection('mongodb')->table('likes')->where('picture_id',$picture->id)->delete();
    	DB::connection('mongodb')->table('count')->where('picture_id',$picture->id)->delete();
        $picture->delete();
        return Redirect::route('picture.list')->with('success', 'Picture is deleted!');
    }

    /* picture functions */
    public function savePicture()
    {
    	$pre = "images/".date("YmdHis",time());
        $picture = [
            'title' => Input::get('title'),
            'description' => Input::get('description'),
            'image' => $_FILES['picture']['name'],
        ];
        $rules = [
            'title' => 'required',
            'description' => 'required',
            'image' => array('regex:/^[^&%]*\\.(jpg|gif|jpeg|png|bmp)$/u'),
        ];
        $messages = array(
        	'regex' => 'Please check there is no & and % character in the file path and is an image file!!'	
        );
        $valid = Validator::make($picture, $rules, $messages);
        if ($valid->passes()) {
        	$file_path = $_FILES['picture']['tmp_name'];
        	$image_path = "F:/mxampp/htdocs/piclist/public/".$pre.'/'.$_FILES['picture']['name'];
        	mkdir("F:/mxampp/htdocs/piclist/public/".$pre);
        	if (!move_uploaded_file($file_path, $image_path)){
        		return Redirect::to('admin/dash-board')->with('failure', 'wooops!!! failed on saving~');
        		//return Redirect::to('admin/dash_board')->with('failure', 'not valid picture');
        	} else{
        		$picture['image'] = $pre.'/'.$_FILES['picture']['name'];
            	$picture = new Picture($picture);
           	 	$picture->comment_count = 0;
            	$picture->save();
            	return Redirect::to('admin/dash-board')->with('success', 'Picture is saved!');
        	}
        } else
            return Redirect::back()->withErrors($valid)->withInput();
    }

    public function updatePicture(Picture $picture)
    {
        $data = [
            'title' => Input::get('title'),
            'description' => Input::get('description'),
        ];
        $rules = [
            'title' => 'required',
            'description' => 'required',
        ];
        $valid = Validator::make($data, $rules);
        if ($valid->passes()) {
            $picture->title = $data['title'];
            $picture->description = $data['description'];
            if (count($picture->getDirty()) > 0) /* avoiding resubmission of same content */ {
                $picture->save();
                return Redirect::back()->with('success', 'Picture is updated!');
            } else
                return Redirect::back()->with('success', 'Nothing to update!');
        } else
            return Redirect::back()->withErrors($valid)->withInput();
    }
	
}



4#......Comment.php

评论(Comment)的控制器,定义了所有评论相关的方法,注意picture->comment_count的改变,每次更新时也要更新这个计数器。

<?php


class CommentController extends BaseController
{


    /* get functions */
    public function listComment()
    {
        $comments = Comment::orderBy('id', 'desc')->paginate(20);
        $this->layout->title = 'Comment Listings';
        $this->layout->main = View::make('dash')->nest('content', 'comments.list', compact('comments'));
    }


    public function newComment(Picture $picture)
    {
        $comment = [
            'commenter' => Input::get('commenter'),
            'email' => Input::get('email'),
            'comment' => Input::get('comment'),
        ];
        $rules = [
            'commenter' => 'required',
            'email' => 'required | email',
            'comment' => 'required',
        ];
        $valid = Validator::make($comment, $rules);
        if ($valid->passes()) {
            $comment = new Comment($comment);
            $picture->comments()->save($comment);
            $picture->increment('comment_count');
            /* redirect back to the form portion of the page */
            return Redirect::to(URL::previous() . '#reply')
                ->with('success', 'Comment has been submitted!');
        } else {
            return Redirect::to(URL::previous() . '#reply')->withErrors($valid)->withInput();
        }
    }


    public function showComment(Comment $comment)
    {
        if (Request::ajax())
            return View::make('comments.show', compact('comment'));
        // handle non-ajax calls here
        //else{}
    }


    public function deleteComment(Comment $comment)
    {
        $picture = $comment->picture;
        $comment->delete();
        $picture->decrement('comment_count');
        return Redirect::back()->with('success', 'Comment deleted!');
    }


    /* picture functions */


    public function updateComment(Comment $comment)
    {
        $comment->save();
        $comment->picture->comment_count = Comment::where('picture_id', '=', $comment->picture->id)->count();
        $comment->picture->save();
        return Redirect::back();
    }


}

二.模型与路由的绑定

请查看

在app/routes.php中实现:

/* Model Bindings */
Route::model('picture', 'Picture');
Route::model('comment', 'Comment');
下一节将介绍路由和过滤器的相关设计


__________________________________________________________________________________________________

下一章将介绍路由和过滤器的实现,实现的路由和过滤器之后,我们整个博客的逻辑部分就算全部完成了~

对每个模型有对应的数据表,对模型的变化定义在控制器,通过路由的行为来调用控制器的方法,实现了用户与服务端交互的目的。

完成路由和过滤器之后,只要把所有页面的UI补充补充就能完成了,有点小激动呢~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值