kopia lustrzana https://github.com/pixelfed/pixelfed
				
				
				
			
		
			
				
	
	
		
			383 wiersze
		
	
	
		
			7.3 KiB
		
	
	
	
		
			PHP
		
	
	
			
		
		
	
	
			383 wiersze
		
	
	
		
			7.3 KiB
		
	
	
	
		
			PHP
		
	
	
| <?php
 | |
| 
 | |
| namespace App;
 | |
| 
 | |
| use Auth, Cache, DB, Storage;
 | |
| use App\Util\Lexer\PrettyNumber;
 | |
| use App\HasSnowflakePrimary;
 | |
| use Illuminate\Database\Eloquent\{Model, SoftDeletes};
 | |
| use App\Services\FollowerService;
 | |
| use App\Models\ProfileAlias;
 | |
| 
 | |
| class Profile extends Model
 | |
| {
 | |
| 	use HasSnowflakePrimary, SoftDeletes;
 | |
| 
 | |
| 	/**
 | |
| 	 * Indicates if the IDs are auto-incrementing.
 | |
| 	 *
 | |
| 	 * @var bool
 | |
| 	 */
 | |
| 	public $incrementing = false;
 | |
| 
 | |
| 	protected $casts = [
 | |
| 		'deleted_at' => 'datetime',
 | |
| 		'last_fetched_at' => 'datetime',
 | |
| 		'last_status_at' => 'datetime'
 | |
| 	];
 | |
| 	protected $hidden = ['private_key'];
 | |
| 	protected $visible = ['id', 'user_id', 'username', 'name'];
 | |
| 	protected $guarded = [];
 | |
| 
 | |
| 	public function user()
 | |
| 	{
 | |
| 		return $this->belongsTo(User::class);
 | |
| 	}
 | |
| 
 | |
| 	public function url($suffix = null)
 | |
| 	{
 | |
| 		return $this->remote_url ?? url($this->username . $suffix);
 | |
| 	}
 | |
| 
 | |
| 	public function localUrl($suffix = null)
 | |
| 	{
 | |
| 		return url($this->username . $suffix);
 | |
| 	}
 | |
| 
 | |
| 	public function permalink($suffix = null)
 | |
| 	{
 | |
| 		return $this->remote_url ?? url('users/' . $this->username . $suffix);
 | |
| 	}
 | |
| 
 | |
| 	public function emailUrl()
 | |
| 	{
 | |
| 		if($this->domain) {
 | |
| 			return $this->username;
 | |
| 		}
 | |
| 
 | |
| 		$domain = parse_url(config('app.url'), PHP_URL_HOST);
 | |
| 
 | |
| 		return $this->username.'@'.$domain;
 | |
| 	}
 | |
| 
 | |
| 	public function statuses()
 | |
| 	{
 | |
| 		return $this->hasMany(Status::class);
 | |
| 	}
 | |
| 
 | |
| 	public function followingCount($short = false)
 | |
| 	{
 | |
| 		$count = Cache::remember('profile:following_count:'.$this->id, now()->addMonths(1), function() {
 | |
| 			if($this->domain == null && $this->user->settings->show_profile_following_count == false) {
 | |
| 				return 0;
 | |
| 			}
 | |
| 			$count = DB::table('followers')->where('profile_id', $this->id)->count();
 | |
| 			if($this->following_count != $count) {
 | |
| 				$this->following_count = $count;
 | |
| 				$this->save();
 | |
| 			}
 | |
| 			return $count;
 | |
| 		});
 | |
| 
 | |
| 		return $short ? PrettyNumber::convert($count) : $count;
 | |
| 	}
 | |
| 
 | |
| 	public function followerCount($short = false)
 | |
| 	{
 | |
| 		$count = Cache::remember('profile:follower_count:'.$this->id, now()->addMonths(1), function() {
 | |
| 			if($this->domain == null && $this->user->settings->show_profile_follower_count == false) {
 | |
| 				return 0;
 | |
| 			}
 | |
| 			$count = DB::table('followers')->where('following_id', $this->id)->count();
 | |
| 			if($this->followers_count != $count) {
 | |
| 				$this->followers_count = $count;
 | |
| 				$this->save();
 | |
| 			}
 | |
| 			return $count;
 | |
| 		});
 | |
| 		return $short ? PrettyNumber::convert($count) : $count;
 | |
| 	}
 | |
| 
 | |
| 	public function statusCount()
 | |
| 	{
 | |
| 		return $this->status_count;
 | |
| 	}
 | |
| 
 | |
| 	public function following()
 | |
| 	{
 | |
| 		return $this->belongsToMany(
 | |
| 			self::class,
 | |
| 			'followers',
 | |
| 			'profile_id',
 | |
| 			'following_id'
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	public function followers()
 | |
| 	{
 | |
| 		return $this->belongsToMany(
 | |
| 			self::class,
 | |
| 			'followers',
 | |
| 			'following_id',
 | |
| 			'profile_id'
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	public function follows($profile) : bool
 | |
| 	{
 | |
| 		return Follower::whereProfileId($this->id)->whereFollowingId($profile->id)->exists();
 | |
| 	}
 | |
| 
 | |
| 	public function followedBy($profile) : bool
 | |
| 	{
 | |
| 		return Follower::whereProfileId($profile->id)->whereFollowingId($this->id)->exists();
 | |
| 	}
 | |
| 
 | |
| 	public function bookmarks()
 | |
| 	{
 | |
| 		return $this->belongsToMany(
 | |
| 			Status::class,
 | |
| 			'bookmarks',
 | |
| 			'profile_id',
 | |
| 			'status_id'
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	public function likes()
 | |
| 	{
 | |
| 		return $this->hasMany(Like::class);
 | |
| 	}
 | |
| 
 | |
| 	public function avatar()
 | |
| 	{
 | |
| 		return $this->hasOne(Avatar::class)->withDefault([
 | |
| 			'media_path' => 'public/avatars/default.jpg',
 | |
| 			'change_count' => 0
 | |
| 		]);
 | |
| 	}
 | |
| 
 | |
| 	public function avatarUrl()
 | |
| 	{
 | |
| 		$url = Cache::remember('avatar:'.$this->id, 1209600, function () {
 | |
| 			$avatar = $this->avatar;
 | |
| 
 | |
| 			if(!$avatar) {
 | |
| 				return url('/storage/avatars/default.jpg');
 | |
| 			}
 | |
| 
 | |
| 			if($avatar->cdn_url) {
 | |
| 				if(substr($avatar->cdn_url, 0, 8) === 'https://') {
 | |
| 					return $avatar->cdn_url;
 | |
| 				} else {
 | |
| 					return url('/storage/avatars/default.jpg');
 | |
| 				}
 | |
| 			}
 | |
| 
 | |
| 			$path = $avatar->media_path;
 | |
| 
 | |
| 			if(!$path) {
 | |
| 				return url('/storage/avatars/default.jpg');
 | |
| 			}
 | |
| 
 | |
| 			if( $avatar->is_remote &&
 | |
| 				$avatar->remote_url &&
 | |
| 				boolval(config_cache('federation.avatars.store_local')) == true
 | |
| 			) {
 | |
| 				return $avatar->remote_url;
 | |
| 			}
 | |
| 
 | |
| 			if($path === 'public/avatars/default.jpg') {
 | |
| 				return url('/storage/avatars/default.jpg');
 | |
| 			}
 | |
| 
 | |
| 			if(substr($path, 0, 6) !== 'public') {
 | |
| 				return url('/storage/avatars/default.jpg');
 | |
| 			}
 | |
| 
 | |
| 			if(config('filesystems.default') !== 'local') {
 | |
| 				return Storage::url($path);
 | |
| 			}
 | |
| 
 | |
| 			$path = "{$path}?v={$avatar->change_count}";
 | |
| 
 | |
| 			return url(Storage::url($path));
 | |
| 		});
 | |
| 
 | |
| 		return $url;
 | |
| 	}
 | |
| 
 | |
| 	// deprecated
 | |
| 	public function recommendFollowers()
 | |
| 	{
 | |
| 		return collect([]);
 | |
| 	}
 | |
| 
 | |
| 	public function keyId()
 | |
| 	{
 | |
| 		if ($this->remote_url) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		return $this->permalink('#main-key');
 | |
| 	}
 | |
| 
 | |
| 	public function mutedIds()
 | |
| 	{
 | |
| 		return UserFilter::whereUserId($this->id)
 | |
| 			->whereFilterableType('App\Profile')
 | |
| 			->whereFilterType('mute')
 | |
| 			->pluck('filterable_id');
 | |
| 	}
 | |
| 
 | |
| 	public function blockedIds()
 | |
| 	{
 | |
| 		return UserFilter::whereUserId($this->id)
 | |
| 			->whereFilterableType('App\Profile')
 | |
| 			->whereFilterType('block')
 | |
| 			->pluck('filterable_id');
 | |
| 	}
 | |
| 
 | |
| 	public function mutedProfileUrls()
 | |
| 	{
 | |
| 		$ids = $this->mutedIds();
 | |
| 		return $this->whereIn('id', $ids)->get()->map(function($i) {
 | |
| 			return $i->url();
 | |
| 		});
 | |
| 	}
 | |
| 
 | |
| 	public function blockedProfileUrls()
 | |
| 	{
 | |
| 		$ids = $this->blockedIds();
 | |
| 		return $this->whereIn('id', $ids)->get()->map(function($i) {
 | |
| 			return $i->url();
 | |
| 		});
 | |
| 	}
 | |
| 
 | |
| 	public function reports()
 | |
| 	{
 | |
| 		return $this->hasMany(Report::class, 'profile_id');
 | |
| 	}
 | |
| 
 | |
| 	public function media()
 | |
| 	{
 | |
| 		return $this->hasMany(Media::class, 'profile_id');
 | |
| 	}
 | |
| 
 | |
| 	public function inboxUrl()
 | |
| 	{
 | |
| 		return $this->inbox_url ?? $this->permalink('/inbox');
 | |
| 	}
 | |
| 
 | |
| 	public function outboxUrl()
 | |
| 	{
 | |
| 		return $this->outbox_url ?? $this->permalink('/outbox');
 | |
| 	}
 | |
| 
 | |
| 	public function sharedInbox()
 | |
| 	{
 | |
| 		return $this->sharedInbox ?? $this->inboxUrl();
 | |
| 	}
 | |
| 
 | |
| 	public function getDefaultScope()
 | |
| 	{
 | |
| 		return $this->is_private == true ? 'private' : 'public';
 | |
| 	}
 | |
| 
 | |
| 	public function getAudience($scope = false)
 | |
| 	{
 | |
| 		if($this->remote_url) {
 | |
| 			return [];
 | |
| 		}
 | |
| 		$scope = $scope ?? $this->getDefaultScope();
 | |
| 		$audience = [];
 | |
| 		switch ($scope) {
 | |
| 			case 'public':
 | |
| 				$audience = [
 | |
| 					'to' => [
 | |
| 						'https://www.w3.org/ns/activitystreams#Public'
 | |
| 					],
 | |
| 					'cc' => [
 | |
| 						$this->permalink('/followers')
 | |
| 					]
 | |
| 				];
 | |
| 			break;
 | |
| 
 | |
| 			case 'unlisted':
 | |
| 				$audience = [
 | |
| 					'to' => [
 | |
| 					],
 | |
| 					'cc' => [
 | |
| 						'https://www.w3.org/ns/activitystreams#Public',
 | |
| 						$this->permalink('/followers')
 | |
| 					]
 | |
| 				];
 | |
| 			break;
 | |
| 
 | |
| 			case 'private':
 | |
| 				$audience = [
 | |
| 					'to' => [
 | |
| 						$this->permalink('/followers')
 | |
| 					],
 | |
| 					'cc' => [
 | |
| 					]
 | |
| 				];
 | |
| 			break;
 | |
| 		}
 | |
| 		return $audience;
 | |
| 	}
 | |
| 
 | |
| 	public function getAudienceInbox($scope = 'public')
 | |
| 	{
 | |
| 		return FollowerService::audience($this->id, $scope);
 | |
| 	}
 | |
| 
 | |
| 	public function circles()
 | |
| 	{
 | |
| 		return $this->hasMany(Circle::class);
 | |
| 	}
 | |
| 
 | |
| 	public function hashtags()
 | |
| 	{
 | |
| 		return $this->hasManyThrough(
 | |
| 			Hashtag::class,
 | |
| 			StatusHashtag::class,
 | |
| 			'profile_id',
 | |
| 			'id',
 | |
| 			'id',
 | |
| 			'hashtag_id'
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	public function hashtagFollowing()
 | |
| 	{
 | |
| 		return $this->hasMany(HashtagFollow::class);
 | |
| 	}
 | |
| 
 | |
| 	public function collections()
 | |
| 	{
 | |
| 		return $this->hasMany(Collection::class);
 | |
| 	}
 | |
| 
 | |
| 	public function hasFollowRequestById(int $id)
 | |
| 	{
 | |
| 		return FollowRequest::whereFollowerId($id)
 | |
| 			->whereFollowingId($this->id)
 | |
| 			->exists();
 | |
| 	}
 | |
| 
 | |
| 	public function stories()
 | |
| 	{
 | |
| 		return $this->hasMany(Story::class);
 | |
| 	}
 | |
| 
 | |
| 	public function reported()
 | |
| 	{
 | |
| 		return $this->hasMany(Report::class, 'object_id');
 | |
| 	}
 | |
| 
 | |
| 	public function aliases()
 | |
| 	{
 | |
| 		return $this->hasMany(ProfileAlias::class);
 | |
| 	}
 | |
| }
 |