datatable.directory codebase
				https://datatable.directory/
			
			
		
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							240 lines
						
					
					
						
							6.6 KiB
						
					
					
				
			
		
		
	
	
							240 lines
						
					
					
						
							6.6 KiB
						
					
					
				<?php
 | 
						|
 | 
						|
namespace App\Models;
 | 
						|
 | 
						|
use AdamWathan\EloquentOAuth\OAuthIdentity;
 | 
						|
use App\Models\Concerns\InstanceCache;
 | 
						|
use App\Models\Concerns\Reportable;
 | 
						|
use App\Notifications\ConfirmEmail;
 | 
						|
use Hash;
 | 
						|
use Illuminate\Database\Eloquent\Collection;
 | 
						|
use Illuminate\Notifications\Notifiable;
 | 
						|
use Illuminate\Notifications\Notification;
 | 
						|
use MightyPork\Exceptions\ArgumentException;
 | 
						|
use MightyPork\Exceptions\NotExistException;
 | 
						|
use Illuminate\Auth\Authenticatable;
 | 
						|
use Illuminate\Auth\Passwords\CanResetPassword;
 | 
						|
use Illuminate\Foundation\Auth\Access\Authorizable;
 | 
						|
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
 | 
						|
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
 | 
						|
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
 | 
						|
use MightyPork\Utils\Str;
 | 
						|
 | 
						|
/**
 | 
						|
 * A user in the application
 | 
						|
 *
 | 
						|
 * @property int $id
 | 
						|
 * @property \Carbon\Carbon $created_at
 | 
						|
 * @property \Carbon\Carbon $updated_at
 | 
						|
 * @property string $name - unique, for vanity URL
 | 
						|
 * @property string $title - for display
 | 
						|
 * @property string $bio - user bio
 | 
						|
 * @property string $website - custom url
 | 
						|
 * @property string $email - unique, for login and social auth chaining
 | 
						|
 * @property string $password - hashed pw
 | 
						|
 * @property bool $confirmed - user e-mail is confirmed
 | 
						|
 * @property-read Proposal[]|Collection $proposals
 | 
						|
 * @property-read Table[]|Collection $tables
 | 
						|
 * @property-read OAuthIdentity[]|Collection $socialIdentities
 | 
						|
 * @property-read TableComment[]|Collection $tableComments
 | 
						|
 * @property-read Table[]|Collection $favouriteTables
 | 
						|
 * @property-read Table[]|Collection $followedDiscussions
 | 
						|
 * @property-read EmailConfirmation[]|Collection $emailConfirmations
 | 
						|
 * @property-read ContentReport[]|Collection $authoredReports
 | 
						|
 * @property-read Notification[]|Collection $notifications
 | 
						|
 * @property-read Notification[]|Collection $readNotifications
 | 
						|
 * @property-read Notification[]|Collection $unreadNotifications
 | 
						|
 * @property-read string $handle - user handle, including @
 | 
						|
 */
 | 
						|
class User extends BaseModel implements
 | 
						|
    AuthenticatableContract,
 | 
						|
    AuthorizableContract,
 | 
						|
    CanResetPasswordContract
 | 
						|
{
 | 
						|
    use Authenticatable, Authorizable, CanResetPassword;
 | 
						|
    use Reportable;
 | 
						|
    use Notifiable;
 | 
						|
    use InstanceCache;
 | 
						|
 | 
						|
    /**
 | 
						|
     * The attributes that are mass assignable.
 | 
						|
     *
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected $fillable = [
 | 
						|
        'name', 'title', 'email', 'password', 'bio', 'website', 'confirmed'
 | 
						|
    ];
 | 
						|
 | 
						|
    /**
 | 
						|
     * The attributes that should be hidden for arrays.
 | 
						|
     *
 | 
						|
     * @var array
 | 
						|
     */
 | 
						|
    protected $hidden = [
 | 
						|
        'password', 'remember_token',
 | 
						|
    ];
 | 
						|
 | 
						|
    protected static function boot()
 | 
						|
    {
 | 
						|
        parent::boot();
 | 
						|
 | 
						|
        static::deleting(function(User $self) {
 | 
						|
            // comments are deleted via cascade
 | 
						|
 | 
						|
            $self->reportsOf()->delete();
 | 
						|
 | 
						|
            // manually delete proposals to ensure row refcounts are updated
 | 
						|
            foreach ($self->proposals as $proposal) {
 | 
						|
                $proposal->delete();
 | 
						|
            }
 | 
						|
 | 
						|
            foreach ($self->tables as $table) {
 | 
						|
                $table->delete();
 | 
						|
            }
 | 
						|
        });
 | 
						|
    }
 | 
						|
 | 
						|
    /** Owned tables */
 | 
						|
    public function tables()
 | 
						|
    {
 | 
						|
        return $this->hasMany(Table::class, 'owner_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Assigned OAuth identities */
 | 
						|
    public function socialIdentities()
 | 
						|
    {
 | 
						|
        return $this->hasMany(OAuthIdentity::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /** Authored proposals */
 | 
						|
    public function proposals()
 | 
						|
    {
 | 
						|
        return $this->hasMany(Proposal::class, 'author_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Authored comments */
 | 
						|
    public function tableComments()
 | 
						|
    {
 | 
						|
        return $this->hasMany(TableComment::class, 'author_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** User's favourite tables (personal collection) */
 | 
						|
    public function favouriteTables()
 | 
						|
    {
 | 
						|
        return $this->belongsToMany(Table::class, 'table_favourites');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Tables whose discussions user follows (this is similar to favourites) */
 | 
						|
    public function followedDiscussions()
 | 
						|
    {
 | 
						|
        return $this->belongsToMany(Table::class, 'discussion_follows');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Reports sent by this user */
 | 
						|
    public function authoredReports()
 | 
						|
    {
 | 
						|
        return $this->hasMany(ContentReport::class, 'author_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** User's e-mail confirmations */
 | 
						|
    public function emailConfirmations()
 | 
						|
    {
 | 
						|
        return $this->hasMany(EmailConfirmation::class);
 | 
						|
    }
 | 
						|
 | 
						|
    // --------- Relation Helpers ---------
 | 
						|
 | 
						|
    public function addFavourite(Table $table)
 | 
						|
    {
 | 
						|
        $this->favouriteTables()->attach($table);
 | 
						|
    }
 | 
						|
 | 
						|
    public function removeFavourite(Table $table)
 | 
						|
    {
 | 
						|
        $this->favouriteTables()->detach($table);
 | 
						|
    }
 | 
						|
 | 
						|
    public function followDiscussion(Table $table)
 | 
						|
    {
 | 
						|
        $this->followedDiscussions()->attach($table);
 | 
						|
    }
 | 
						|
 | 
						|
    public function unfollowDiscussion(Table $table)
 | 
						|
    {
 | 
						|
        $this->followedDiscussions()->detach($table);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Resolve user by a given name, id, or e-mail
 | 
						|
     *
 | 
						|
     * @param string $ident
 | 
						|
     * @return User
 | 
						|
     */
 | 
						|
    public static function resolve($ident)
 | 
						|
    {
 | 
						|
        $ident = "$ident";
 | 
						|
        if (strlen($ident) == 0) throw new ArgumentException("Can't find user by empty string.");
 | 
						|
 | 
						|
        if (is_numeric($ident)) {
 | 
						|
            $u = static::find((int)$ident);
 | 
						|
        }
 | 
						|
        else if ($ident[0] == '@') {
 | 
						|
            $u = static::where('name', substr($ident, 1))->first();
 | 
						|
        }
 | 
						|
        else {
 | 
						|
            $u = static::where('email', $ident)->first();
 | 
						|
 | 
						|
            if (!$u) {
 | 
						|
                $u = static::where('name', $ident)->first();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if (!$u) throw new NotExistException("No user found matching \"$ident\"");
 | 
						|
 | 
						|
        return $u;
 | 
						|
    }
 | 
						|
 | 
						|
    public function __get($name)
 | 
						|
    {
 | 
						|
        if ($name == 'handle') return "@$this->name";
 | 
						|
 | 
						|
        return parent::__get($name);
 | 
						|
    }
 | 
						|
 | 
						|
    public function ownsTable(Table $table)
 | 
						|
    {
 | 
						|
        return $table->owner_id == $this->id;
 | 
						|
    }
 | 
						|
 | 
						|
    public function favouritesTable(Table $table)
 | 
						|
    {
 | 
						|
        return \DB::table('table_favourites')
 | 
						|
            ->where('user_id', $this->id)
 | 
						|
            ->where('table_id', $table->id)->exists();
 | 
						|
    }
 | 
						|
 | 
						|
    public function sendEmailConfirmationLink($newEmail)
 | 
						|
    {
 | 
						|
        // delete old confirmation tokens
 | 
						|
        $this->emailConfirmations()->delete();
 | 
						|
 | 
						|
        $confirmation = EmailConfirmation::create([
 | 
						|
            'user_id' => $this->id,
 | 
						|
            'email' => $newEmail,
 | 
						|
            'token' => Hash::make(Str::random(40)),
 | 
						|
        ]);
 | 
						|
 | 
						|
        $this->notify(new ConfirmEmail($newEmail, $confirmation->token));
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Check if this user has a table with the givenname
 | 
						|
     *
 | 
						|
     * @param string $name
 | 
						|
     * @return bool
 | 
						|
     */
 | 
						|
    public function hasTable(string $name)
 | 
						|
    {
 | 
						|
        return $this->tables()->where('name', $name)->exists();
 | 
						|
    }
 | 
						|
}
 | 
						|
 |