2016-05-27 21:12:40 +02:00
< ? php
/**
* Pony . fm - A community for pony fan music .
* Copyright ( C ) 2016 Peter Deltchev
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU Affero General Public License for more details .
*
* You should have received a copy of the GNU Affero General Public License
* along with this program . If not , see < http :// www . gnu . org / licenses />.
*/
namespace Poniverse\Ponyfm\Models ;
use Illuminate\Database\Eloquent\Model ;
2016-07-10 03:16:25 +02:00
use Illuminate\Database\Eloquent\SoftDeletes ;
2016-05-27 21:12:40 +02:00
/**
* Poniverse\Ponyfm\Models\Activity
*
* @ property integer $id
* @ property \Carbon\Carbon $created_at
* @ property integer $user_id
* @ property boolean $activity_type
* @ property boolean $resource_type
* @ property integer $resource_id
* @ property - read \Illuminate\Database\Eloquent\Collection | \Poniverse\Ponyfm\Models\Notification [] $notifications
* @ property - read \Poniverse\Ponyfm\Models\User $initiatingUser
* @ property - read \Poniverse\Ponyfm\Models\Activity $resource
* @ property - read mixed $url
* @ property - read mixed $thumbnail_url
* @ property - read mixed $text
2016-12-10 17:47:49 +01:00
* @ property string $deleted_at
* @ property - read \Illuminate\Database\Eloquent\Collection | \Poniverse\Ponyfm\Models\User [] $notificationRecipients
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereId ( $value )
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereCreatedAt ( $value )
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereUserId ( $value )
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereActivityType ( $value )
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereResourceType ( $value )
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereResourceId ( $value )
* @ method static \Illuminate\Database\Query\Builder | \Poniverse\Ponyfm\Models\Activity whereDeletedAt ( $value )
* @ mixin \Eloquent
2016-05-27 21:12:40 +02:00
*/
2016-09-30 00:26:31 +02:00
class Activity extends Model
{
2016-07-10 03:16:25 +02:00
use SoftDeletes ;
2016-05-27 21:12:40 +02:00
public $timestamps = false ;
protected $dates = [ 'created_at' ];
protected $fillable = [ 'created_at' , 'user_id' , 'activity_type' , 'resource_type' , 'resource_id' ];
protected $appends = [ 'url' , 'thumbnail_url' , 'human_friendly_resource_type' ];
protected $casts = [
'id' => 'integer' ,
'created_at' => 'datetime' ,
'user_id' => 'integer' ,
'activity_type' => 'integer' ,
// resource_type has its own accessor and mutator
'resource_id' => 'integer' ,
];
2016-12-09 11:53:32 +01:00
/**
* These constants are stored in the " activity_types " table for the purpose
* of referential data integrity . Any additions or changes to them MUST
* include a database migration to apply the changes to that table as well .
*/
2016-05-27 21:12:40 +02:00
const TYPE_NEWS = 1 ;
const TYPE_PUBLISHED_TRACK = 2 ;
const TYPE_PUBLISHED_ALBUM = 3 ;
const TYPE_PUBLISHED_PLAYLIST = 4 ;
const TYPE_NEW_FOLLOWER = 5 ;
const TYPE_NEW_COMMENT = 6 ;
const TYPE_CONTENT_FAVOURITED = 7 ;
/**
* These " target " constants are an implementation detail of this model and
* should not be used directly in other classes . They ' re used to efficiently
* store the type of resource this notification is about in the database .
*
* The " resource_type " attribute is transformed into a class name at runtime
* so that the use of an integer in the database to represent this info
* remains an implementation detail of this model . Outside of this class ,
* the resource_type attribute should be treated as a fully - qualified class
* name .
*/
const TARGET_USER = 1 ;
const TARGET_TRACK = 2 ;
const TARGET_ALBUM = 3 ;
const TARGET_PLAYLIST = 4 ;
const TARGET_COMMENT = 5 ;
2016-09-30 00:26:31 +02:00
public function initiatingUser ()
{
2016-05-27 21:12:40 +02:00
return $this -> belongsTo ( User :: class , 'user_id' , 'id' );
}
2016-09-30 00:26:31 +02:00
public function notifications ()
{
2016-05-27 21:12:40 +02:00
return $this -> hasMany ( Notification :: class , 'activity_id' , 'id' );
}
2016-09-30 00:26:31 +02:00
public function notificationRecipients ()
{
2016-05-27 21:12:40 +02:00
return $this -> hasManyThrough ( User :: class , Notification :: class , 'activity_id' , 'user_id' , 'id' );
}
2016-09-30 00:26:31 +02:00
public function resource ()
{
2016-05-27 21:12:40 +02:00
return $this -> morphTo ( 'resource' , 'resource_type' , 'resource_id' );
}
2016-09-30 00:26:31 +02:00
public function getUrlAttribute ()
{
2016-05-27 21:12:40 +02:00
return $this -> resource -> url ;
}
2016-09-30 00:26:31 +02:00
public function getResourceTypeAttribute ( $value )
{
2016-05-27 21:12:40 +02:00
switch ( $value ) {
case static :: TARGET_USER :
return User :: class ;
case static :: TARGET_TRACK :
return Track :: class ;
case static :: TARGET_ALBUM :
return Album :: class ;
case static :: TARGET_PLAYLIST :
return Playlist :: class ;
case static :: TARGET_COMMENT :
return Comment :: class ;
default :
// Null must be returned here for Eloquent's eager-loading
// of the polymorphic relation to work.
2016-09-30 00:26:31 +02:00
return null ;
2016-05-27 21:12:40 +02:00
}
}
2016-09-30 00:26:31 +02:00
public function setResourceTypeAttribute ( $value )
{
2016-05-27 21:12:40 +02:00
switch ( $value ) {
case User :: class :
$this -> attributes [ 'resource_type' ] = static :: TARGET_USER ;
break ;
case Track :: class :
$this -> attributes [ 'resource_type' ] = static :: TARGET_TRACK ;
break ;
case Album :: class :
$this -> attributes [ 'resource_type' ] = static :: TARGET_ALBUM ;
break ;
case Playlist :: class :
$this -> attributes [ 'resource_type' ] = static :: TARGET_PLAYLIST ;
break ;
case Comment :: class :
$this -> attributes [ 'resource_type' ] = static :: TARGET_COMMENT ;
break ;
}
}
public function getThumbnailUrlAttribute ()
{
switch ( $this -> resource_type ) {
case User :: class :
return $this -> resource -> getAvatarUrl ( Image :: THUMBNAIL );
case Track :: class :
case Album :: class :
case Playlist :: class :
return $this -> resource -> getCoverUrl ( Image :: THUMBNAIL );
case Comment :: class :
return $this -> resource -> user -> getAvatarUrl ( Image :: THUMBNAIL );
default :
throw new \Exception ( 'This activity\'s resource is of an unknown type!' );
}
}
2016-09-30 00:26:31 +02:00
public function getTitleFromActivityType ()
{
2016-08-28 02:01:37 +02:00
2016-09-30 00:26:31 +02:00
switch ( $this -> activity_type ) {
2016-06-12 01:58:10 +02:00
case static :: TYPE_PUBLISHED_TRACK :
return " Pony.fm - New track " ;
case static :: TYPE_PUBLISHED_PLAYLIST :
return " Pony.fm - New playlist " ;
case static :: TYPE_NEW_FOLLOWER :
return " Pony.fm - New follower " ;
case static :: TYPE_NEW_COMMENT :
return " Pony.fm - New comment " ;
case static :: TYPE_CONTENT_FAVOURITED :
return " Pony.fm - Favourited " ;
default :
return " Pony.fm - Unknown " ;
}
}
2016-05-27 21:12:40 +02:00
/**
* @ return string human - readable Markdown string describing this notification
* @ throws \Exception
*/
public function getTextAttribute ()
{
switch ( $this -> activity_type ) {
case static :: TYPE_NEWS :
// not implemented yet
throw new \InvalidArgumentException ( 'This type of activity has not been implemented yet!' );
case static :: TYPE_PUBLISHED_TRACK :
2016-06-02 05:12:56 +02:00
return " { $this -> resource -> user -> display_name } published a new track, { $this -> resource -> title } ! " ;
2016-05-27 21:12:40 +02:00
case static :: TYPE_PUBLISHED_PLAYLIST :
2016-06-02 05:12:56 +02:00
return " { $this -> resource -> user -> display_name } published a new playlist, { $this -> resource -> title } ! " ;
2016-05-27 21:12:40 +02:00
case static :: TYPE_NEW_FOLLOWER :
return " { $this -> initiatingUser -> display_name } is now following you! " ;
case static :: TYPE_NEW_COMMENT :
// Is this a profile comment?
if ( $this -> resource_type === User :: class ) {
return " { $this -> initiatingUser -> display_name } left a comment on your profile! " ;
// Must be a content comment.
} else {
2016-06-02 05:12:56 +02:00
return " { $this -> initiatingUser -> display_name } left a comment on your { $this -> resource -> resource -> getResourceType () } , { $this -> resource -> resource -> title } ! " ;
2016-05-27 21:12:40 +02:00
}
case static :: TYPE_CONTENT_FAVOURITED :
2016-08-07 17:42:36 +02:00
return " { $this -> initiatingUser -> display_name } favourited your { $this -> resource -> getResourceType () } , { $this -> resource -> title } ! " ;
2016-05-27 21:12:40 +02:00
default :
throw new \Exception ( 'This activity\'s activity type is unknown!' );
}
}
}