Clean up activity model

This commit is contained in:
Toby Zerner 2015-07-01 13:19:24 +09:30
parent 6e7cb1ff0e
commit 094825792a
3 changed files with 59 additions and 23 deletions

View File

@ -1,5 +1,18 @@
<?php namespace Flarum\Core\Models; <?php namespace Flarum\Core\Models;
/**
* Models a user activity record in the database.
*
* Activity records show up in chronological order on a user's activity feed.
* They indicate when the user has done something, like making a new post. They
* can also be used to show any other relevant information on the user's
* activity feed, like if the user has been mentioned in another post.
*
* Each activity record has a *type*. The type determines how the record looks
* in the activity feed, and what *subject* is associated with it. For example,
* the 'posted' activity type represents that a user made a post. Its subject is
* a post, of which the ID is stored in the `subject_id` column.
*/
class Activity extends Model class Activity extends Model
{ {
/** /**
@ -17,33 +30,48 @@ class Activity extends Model
protected $dates = ['time']; protected $dates = ['time'];
/** /**
* * A map of activity types and the model classes to use for their subjects.
* For example, the 'posted' activity type, which represents that a user
* made a post, has the subject model class 'Flarum\Core\Models\Post'.
* *
* @var array * @var array
*/ */
protected static $subjects = []; protected static $subjectModels = [];
/** /**
* Unserialize the data attribute. * When getting the data attribute, unserialize the JSON stored in the
* database into a plain array.
* *
* @param string $value * @param string $value
* @return string * @return mixed
*/ */
public function getDataAttribute($value) public function getDataAttribute($value)
{ {
return json_decode($value); return json_decode($value, true);
} }
/** /**
* Serialize the data attribute. * When setting the data attribute, serialize it into JSON for storage in
* the database.
* *
* @param string $value * @param mixed $value
*/ */
public function setDataAttribute($value) public function setDataAttribute($value)
{ {
$this->attributes['data'] = json_encode($value); $this->attributes['data'] = json_encode($value);
} }
/**
* Get the subject model for this activity record by looking up its type in
* our subject model map.
*
* @return string|null
*/
public function getSubjectModelAttribute()
{
return array_get(static::$subjectModels, $this->type);
}
/** /**
* Define the relationship with the activity's recipient. * Define the relationship with the activity's recipient.
* *
@ -54,27 +82,35 @@ class Activity extends Model
return $this->belongsTo('Flarum\Core\Models\User', 'user_id'); return $this->belongsTo('Flarum\Core\Models\User', 'user_id');
} }
/**
* Define the relationship with the activity's subject.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphTo
*/
public function subject() public function subject()
{ {
return $this->mappedMorphTo(static::$subjects, 'subject', 'type', 'subject_id'); return $this->morphTo('subject', 'subjectModel', 'subject_id');
}
public static function getTypes()
{
return static::$subjects;
} }
/** /**
* Register a notification type. * Get the type-to-subject-model map.
* *
* @param string $type * @return array
* @param string $class */
public static function getSubjectModels()
{
return static::$subjectModels;
}
/**
* Set the subject model for the given activity type.
*
* @param string $type The activity type.
* @param string $class The class name of the subject model for that type.
* @return void * @return void
*/ */
public static function registerType($class) public static function setSubjectModel($type, $subjectModel)
{ {
if ($subject = $class::getSubjectModel()) { static::$subjectModels[$type] = $subjectModel;
static::$subjects[$class::getType()] = $subject;
}
} }
} }

View File

@ -8,7 +8,7 @@ class EloquentActivityRepository implements ActivityRepositoryInterface
public function findByUser($userId, User $viewer, $limit = null, $offset = 0, $type = null) public function findByUser($userId, User $viewer, $limit = null, $offset = 0, $type = null)
{ {
$query = Activity::where('user_id', $userId) $query = Activity::where('user_id', $userId)
->whereIn('type', array_keys(Activity::getTypes())) ->whereIn('type', array_keys(Activity::getSubjectModels()))
->orderBy('time', 'desc') ->orderBy('time', 'desc')
->skip($offset) ->skip($offset)
->take($limit); ->take($limit);

View File

@ -20,7 +20,7 @@ class ActivityType implements ExtenderInterface
{ {
$class = $this->class; $class = $this->class;
Activity::registerType($class); Activity::setSubjectModel($class::getType(), $class::getSubjectModel());
ActivitySerializer::$subjects[$class::getType()] = $this->serializer; ActivitySerializer::$subjects[$class::getType()] = $this->serializer;
} }