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.
		
		
		
		
		
			
		
			
				
					
					
						
							261 lines
						
					
					
						
							7.6 KiB
						
					
					
				
			
		
		
	
	
							261 lines
						
					
					
						
							7.6 KiB
						
					
					
				<?php
 | 
						|
 | 
						|
namespace App\Models;
 | 
						|
 | 
						|
use App\Models\Concerns\Reportable;
 | 
						|
use function GuzzleHttp\Psr7\build_query;
 | 
						|
use http\QueryString;
 | 
						|
use Illuminate\Database\Eloquent\Builder;
 | 
						|
use Illuminate\Database\Eloquent\Collection;
 | 
						|
 | 
						|
/**
 | 
						|
 * A data table object (referencing revisions)
 | 
						|
 *
 | 
						|
 * @property int $id
 | 
						|
 * @property \Carbon\Carbon $created_at
 | 
						|
 * @property \Carbon\Carbon $updated_at
 | 
						|
 * @property int $owner_id
 | 
						|
 * @property int $ancestor_id
 | 
						|
 * @property int $revision_id
 | 
						|
 * @property string $name
 | 
						|
 * @property string $title
 | 
						|
 * @property string $description
 | 
						|
 * @property string $license
 | 
						|
 * @property string $origin
 | 
						|
 * @property int $visits
 | 
						|
 * @property-read string $viewRoute
 | 
						|
 * @property-read string $draftRoute
 | 
						|
 * @property-read string $settingsRoute
 | 
						|
 * @property-read string $deleteRoute
 | 
						|
 * @property-read string $draftSessionKey
 | 
						|
 * @property-read string $draftDiscardRoute
 | 
						|
 * @property-read string $draftUpdateRoute
 | 
						|
 * @property-read string $draftSubmitRoute
 | 
						|
 * @property-read string $revisionsRoute
 | 
						|
 * @property-read User $owner
 | 
						|
 * @property-read Table $parentTable
 | 
						|
 * @property-read Table[]|Collection $forks
 | 
						|
 * @property-read Revision[]|Collection $revisions
 | 
						|
 * @property-read Revision $revision
 | 
						|
 * @property-read Proposal[]|Collection $proposal
 | 
						|
 * @property-read TableComment[]|Collection $comments
 | 
						|
 * @property-read User[]|Collection $favouritingUsers
 | 
						|
 * @property-read User[]|Collection $discussionFollowers
 | 
						|
 */
 | 
						|
class Table extends BaseModel
 | 
						|
{
 | 
						|
    use Reportable;
 | 
						|
    protected $guarded = [];
 | 
						|
 | 
						|
    protected $touches = ['owner'];
 | 
						|
 | 
						|
    public function countVisit()
 | 
						|
    {
 | 
						|
        // Temporarily disable timestamps to avoid touching updated_at
 | 
						|
        $oldt = $this->touches;
 | 
						|
        $this->touches = [];
 | 
						|
        $this->timestamps = false;
 | 
						|
 | 
						|
        $this->increment('visits');
 | 
						|
 | 
						|
        $this->timestamps = true;
 | 
						|
        $this->touches = $oldt;
 | 
						|
    }
 | 
						|
 | 
						|
    /** Get owner from the instance cache (use when building table lists) */
 | 
						|
    public function cachedOwner()
 | 
						|
    {
 | 
						|
        return User::getCached($this->owner_id);
 | 
						|
    }
 | 
						|
 | 
						|
    /** Owning user */
 | 
						|
    public function owner()
 | 
						|
    {
 | 
						|
        return $this->belongsTo(User::class, 'owner_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Fork precursor */
 | 
						|
    public function parentTable()
 | 
						|
    {
 | 
						|
        return $this->belongsTo(Table::class, 'ancestor_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Fork descendants */
 | 
						|
    public function forks()
 | 
						|
    {
 | 
						|
        return $this->hasMany(Table::class, 'ancestor_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** All related revisions (this may include merged revisions) */
 | 
						|
    public function revisions()
 | 
						|
    {
 | 
						|
        return $this->belongsToMany(Revision::class, 'table_revision_pivot');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Active revision */
 | 
						|
    public function revision()
 | 
						|
    {
 | 
						|
        return $this->belongsTo(Revision::class, 'revision_id');
 | 
						|
    }
 | 
						|
 | 
						|
    /** Proposals submitted to this table */
 | 
						|
    public function proposals()
 | 
						|
    {
 | 
						|
        return $this->hasMany(Proposal::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /** User-submitted comments */
 | 
						|
    public function comments()
 | 
						|
    {
 | 
						|
        return $this->hasMany(TableComment::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /** Users favouriting this table */
 | 
						|
    public function favouritingUsers()
 | 
						|
    {
 | 
						|
        return $this->belongsToMany(User::class, 'table_favourites');
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Relation to the pivot table, for favourite counting
 | 
						|
     */
 | 
						|
    public function favourites()
 | 
						|
    {
 | 
						|
        return $this->hasMany(TableFavouritePivot::class);
 | 
						|
    }
 | 
						|
 | 
						|
    /** Users to notify about comments */
 | 
						|
    public function discussionFollowers()
 | 
						|
    {
 | 
						|
        return $this->belongsToMany(User::class, 'discussion_follows');
 | 
						|
    }
 | 
						|
 | 
						|
    public function __get($name)
 | 
						|
    {
 | 
						|
        if (ends_with($name, 'Route')) {
 | 
						|
            $arg = [
 | 
						|
                'user' => $this->cachedOwner()->name,
 | 
						|
                'table' => $this->name
 | 
						|
            ];
 | 
						|
 | 
						|
            switch ($name) {
 | 
						|
                case 'viewRoute':     return route('table.view', $arg);
 | 
						|
                case 'settingsRoute': return route('table.conf', $arg);
 | 
						|
                case 'draftRoute':    return route('table.draft', $arg);
 | 
						|
                case 'deleteRoute':   return route('table.delete', $arg);
 | 
						|
                case 'draftDiscardRoute':    return route('table.draft-discard', $arg);
 | 
						|
                case 'draftUpdateRoute':    return route('table.draft-update', $arg);
 | 
						|
                case 'draftSubmitRoute':    return route('table.draft-submit', $arg);
 | 
						|
                case 'revisionsRoute':    return route('table.revisions', $arg);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        if ($name == 'handle') return '@' . $this->cachedOwner()->name . '/' . $this->name;
 | 
						|
 | 
						|
        if ($name == 'draftSessionKey') return "proposal.{$this->id}";
 | 
						|
 | 
						|
        return parent::__get($name);
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get route to some action (so we dont have to add xxRoute for everything)
 | 
						|
     *
 | 
						|
     * @param $action
 | 
						|
     * @param array $getargs
 | 
						|
     * @return string
 | 
						|
     */
 | 
						|
    public function actionRoute($action, $getargs = [])
 | 
						|
    {
 | 
						|
        $user = $this->cachedOwner()->name;
 | 
						|
        $table = $this->name;
 | 
						|
 | 
						|
        $base = "/@$user/$table";
 | 
						|
        if ($action != 'view') $base .= "/$action";
 | 
						|
 | 
						|
        if ($getargs) {
 | 
						|
            return $base . '?' . build_query($getargs);
 | 
						|
        } else {
 | 
						|
            return $base;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    public function getDraftRoute($tab=null)
 | 
						|
    {
 | 
						|
        return route('table.draft', [
 | 
						|
            'user' => $this->cachedOwner()->name,
 | 
						|
            'table' => $this->name,
 | 
						|
            'tab' => $tab,
 | 
						|
        ]);
 | 
						|
    }
 | 
						|
 | 
						|
    public function scopeForList(Builder $query)
 | 
						|
    {
 | 
						|
        return $query->with('revision:id,row_count')
 | 
						|
            ->with('owner:id,name,title')
 | 
						|
            ->withCount(['favourites', 'forks', 'revisions', 'proposals', 'comments']);
 | 
						|
    }
 | 
						|
 | 
						|
    public static function getSortOptions()
 | 
						|
    {
 | 
						|
        return [
 | 
						|
            'most-visited' => 'Most Visited',
 | 
						|
            'last-updated' => 'Last Updated',
 | 
						|
            'most-updated' => 'Most Changed',
 | 
						|
//            'most-discussed' => 'Most Discussed',
 | 
						|
//            'most-liked' => 'Most Liked',
 | 
						|
            'newest' => 'Newest',
 | 
						|
            'oldest' => 'Oldest',
 | 
						|
            'most-rows' => 'Longest',
 | 
						|
            'least-rows' => 'Shortest',
 | 
						|
        ];
 | 
						|
    }
 | 
						|
 | 
						|
    public static function resolveSortType($sort)
 | 
						|
    {
 | 
						|
        $defaultSort = 'last-updated';
 | 
						|
        if (!in_array($sort, array_keys(self::getSortOptions()))) {
 | 
						|
            $sort = $defaultSort;
 | 
						|
        }
 | 
						|
        return $sort;
 | 
						|
    }
 | 
						|
 | 
						|
    public function scopeTableSort(Builder $query, $sort)
 | 
						|
    {
 | 
						|
 | 
						|
        switch ($sort) {
 | 
						|
            case 'most-visited':
 | 
						|
                $query = $query->orderBy('visits', 'desc');
 | 
						|
                break;
 | 
						|
            case 'last-updated':
 | 
						|
                $query = $query->orderBy('updated_at', 'desc');
 | 
						|
                break;
 | 
						|
            case 'most-updated':
 | 
						|
                $query = $query->orderBy('revisions_count', 'desc');
 | 
						|
                break;
 | 
						|
            case 'most-discussed':
 | 
						|
                $query = $query->orderBy('comments_count', 'desc');
 | 
						|
                break;
 | 
						|
            case 'most-liked':
 | 
						|
                $query = $query->orderBy('favourites_count', 'desc');
 | 
						|
                break;
 | 
						|
            case 'most-rows':
 | 
						|
                $query = $query
 | 
						|
                    ->join('revisions', 'revisions.id', '=', 'tables.revision_id')
 | 
						|
                    ->orderBy('revisions.row_count', 'desc');
 | 
						|
                break;
 | 
						|
            case 'least-rows':
 | 
						|
                $query = $query
 | 
						|
                    ->join('revisions', 'revisions.id', '=', 'tables.revision_id')
 | 
						|
                    ->orderBy('revisions.row_count', 'asc');
 | 
						|
                break;
 | 
						|
            case 'newest':
 | 
						|
                $query = $query->orderBy('created_at', 'desc');
 | 
						|
                break;
 | 
						|
            case 'oldest':
 | 
						|
                $query = $query->orderBy('created_at', 'asc');
 | 
						|
                break;
 | 
						|
        }
 | 
						|
 | 
						|
        return $query;
 | 
						|
    }
 | 
						|
}
 | 
						|
 |