家庭任務平台在紀錄活動時,活動會隨著計畫或是任務的變化而一起被記錄下來,如下圖左邊的部分,紀錄了:
為了紀錄活動,可以把紀錄不同活動的程式碼寫在Controller的各個對應方法中,例如紀錄更新計畫的活動時,則把該部分的程式碼寫在Controller的update方法中,但是這樣的壞處有:
為了處理上面提到的壞處,可以使用Laravel所提供的模型觀察者(Model Observer),下面是ProjectObserver/TaskObserver的程式碼,可以看到其中提供對應的Model活動,如created等等:
class ProjectObserver
{
use ActivityChange;
/**
* Handle the project "created" event.
*
* @param \App\Project $project
* @return void
*/
public function created(Project $project)
{
$project->recordActivity('created');
}
/**
* Handle the project "updated" event.
*
* @param \App\Project $project
* @return void
*/
public function updated(Project $project)
{
$changes =$this->getChanges($project);
$project->recordActivity('updated',$changes);
}
}
class TaskObserver
{
use ActivityChange;
/**
* Handle the task "created" event.
*
* @param \App\Task $task
* @return void
*/
public function created(Task $task)
{
$task->recordActivity('created_task');
}
/**
* Handle the task "updated" event.
*
* @param \App\Task $task
* @return void
*/
public function updated(Task $task)
{
$changes = $this->getChanges($task);
if ($this->isCompleted($task)) {
$task->recordActivity('completed_task', $changes);
} else if ($this->isUncompleted($task)) {
$task->recordActivity('uncompleted_task', $changes);
} else {
$task->recordActivity('updated_task', $changes);
}
}
/**
* Handle the task "deleted" event.
*
* @param \App\Task $task
* @return void
*/
public function deleted(Task $task)
{
$task->recordActivity('deleted_task');
}
protected function isCompleted(Task $task)
{
return $task->completed && !$task->getOriginal('completed');
}
protected function isUncompleted(Task $task)
{
return !$task->completed && $task->getOriginal('completed');
}
trait ActivityChange
{
protected function getChanges($recordable){
$after = Arr::except($recordable->getChanges(),'updated_at');
$original= $recordable->getOriginal();
$before = array_intersect_key($original,$after);
$changes =
['before'=>$before,
'after'=>$after];
return $changes;
}
}
所以我們要來認識一下Laravel所提供的Observor。