/app/Article.php
PHP | 358 lines | 193 code | 50 blank | 115 comment | 7 complexity | 6fdbededc33b03c99a76d8ecfa0d1580 MD5 | raw file
- <?php namespace App;
- use Auth;
- use App\Article;
- use Carbon\Carbon;
- use Conner\Likeable\LikeableTrait;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Eloquent\SoftDeletes;
- use AlgoliaSearch\Laravel\AlgoliaEloquentTrait;
- use Cviebrock\EloquentSluggable\SluggableTrait;
- use Cviebrock\EloquentSluggable\SluggableInterface;
- class Article extends Model implements SluggableInterface {
- use LikeableTrait, SluggableTrait, SoftDeletes, AlgoliaEloquentTrait;
- protected $fillable =
- [
- 'title',
- 'overview',
- 'example',
- 'advice',
- 'published',
- 'featured',
- 'user_id',
- 'category_id'
- ];
- protected $sluggable = array(
- 'build_from' => 'title',
- 'save_to' => 'slug',
- 'on_update' => true
- );
- /**
- * Make sure these return as dates
- * @var array
- */
- protected $dates = ['deleted_at'];
- /**
- * Attributes for Algolia Search
- *
- * @var array
- */
- public $algoliaSettings = [
- 'attributesToIndex' => [
- 'username',
- 'title',
- 'overview',
- 'example',
- 'advice'
- ]
- ];
- public function getAlgoliaRecord()
- {
- // Inject username into search record
- return array_merge($this->toArray(), [
- 'username' => $this->user->name,
- 'url' => '/article/' . $this->slug
- ]);
- }
- /**
- * User relationship
- * One user can have many articles
- */
- public function user()
- {
- return $this->belongsTo('App\User')->withTrashed();
- }
- /**
- * Category relationship
- * One category can have many articles
- */
- public function category()
- {
- return $this->belongsTo('App\Category');
- }
- /**
- * Tag relationship
- * Tags and articles can have many of each other
- */
- public function tags()
- {
- return $this->belongsToMany('App\Tag')->withTimestamps();
- }
- /**
- * Comment relationship
- * Articles can have many comments
- */
- public function comments()
- {
- // Order the comments with most recent
- return $this->hasMany('App\Comment')->orderBy('created_at', 'DESC');
- }
- /**
- * Get class for article if it's a draft
- */
- public function getDraftClassAttribute()
- {
- if ( ! $this->published ) {
- return ' draft';
- }
- return '';
- }
- /**
- * Get amount of comments this article has
- */
- public function getCommentCountAttribute()
- {
- return $this->comments()->count();
- }
- /**
- * Get the popularity count for the article
- * Based on count of bumps and comments
- */
- public function getPopularityAttribute()
- {
- return $this->comment_count + $this->likeCount;
- }
- /**
- * Has this article been featured?
- */
- public function getWasFeaturedAttribute()
- {
- return ( $this->featured_on !== '0000-00-00 00:00:00' );
- }
- /**
- * Get all classes related to the feature status
- */
- public function getFeatureClassesAttribute()
- {
- $classes = ['star'];
- if ( $this->wasFeatured ) {
- array_push( $classes, 'hasbeen');
- }
- if ( $this->featured ) {
- array_push( $classes, 'featured');
- } else {
- array_push( $classes, 'unfeatured');
- }
- return implode(' ', $classes);
- }
- /**
- * Set this article as featured
- */
- public function feature()
- {
- // set featured attribute
- $this->featured = true;
- // set the featured date
- $this->featured_on = Carbon::now();
- // save
- $this->save();
- }
- /**
- * Set this article as unfeatured
- */
- public function unFeature()
- {
- // set featured attribute
- $this->featured = false;
- // save
- $this->save();
- }
- /**
- * Toggle the featured status on/off
- */
- public function toggleFeatured() {
- if ( $this->featured == true ) {
- $this->unfeature();
- return false;
- } else {
- $this->feature();
- return true;
- }
- }
- /**
- * Query articles that are featured
- */
- public function scopeFeatured( $query )
- {
- return $query->where('featured', true);
- }
- /**
- * Query articles that have been featured before
- */
- public function scopeWasFeatured( $query )
- {
- return $query->where('featured_on', '!=', '0000-00-00 00:00:00');
- }
- /**
- * Get list of articles sorted by popularity
- * Get the top 20 super bumped articles
- */
- public static function getTopArticles()
- {
- // return Article::published()->get()->sortByDesc( function( $model )
- // {
- // return $model->popularity;
- // });
- return Article::superBumped()->take(20)->get();
- }
- /**
- * Get the total number of likes on Trace
- */
- public static function getTotalBumps()
- {
- return Article::published()->has('likes')->count();
- }
- /**
- * Get property of super bumped status
- */
- public function getSuperBumpedAttribute()
- {
- // This doesn't seem efficient...
- // Get the collection of super bumped articles
- $super_bumps = Article::superBumped()->take(20)->get();
- // Is this article in the super bumps collection?
- return $super_bumps->contains( $this );
- }
- /**
- * Query articles that have been super-bumped
- * And join in the likeable count if it's not 0
- */
- public function scopeSuperBumped( $query )
- {
- return $query
- ->published()
- ->where('created_at', '>', Carbon::now()->subYear())
- ->join('likeable_like_counters', function( $join ) {
- $join->on('articles.id', '=', 'likeable_like_counters.likable_id')
- ->where('likeable_like_counters.count', '>', 0);
- })
- ->select('likeable_like_counters.count as like_count', 'articles.*')
- ->orderBy('like_count', 'desc')
- ->orderBy('created_at', 'desc');
- }
- /**
- * Query Articles commented on by a user
- */
- public function scopeWhereCommented( $query, $user_id )
- {
- return $query->whereHas('comments', function( $q ) use ( $user_id ) {
- $q->where('user_id', $user_id);
- });
- }
- /**
- * Collect all articles that have been commented on by a user
- */
- public static function commented( $user_id )
- {
- return Article::published()->whereCommented( $user_id )
- ->get()
- ->sortByDesc( function( $article ) {
- return $article->comments()->first()->created_at;
- });
- }
- /**
- * Get a string appropriate for count of others
- */
- private function peopleString( $count )
- {
- return ( $count === 1 ) ? ' other' : ' others';
- }
- /**
- * Get the count and string of
- * others that have bumped this article
- */
- public function getOthersBumpedAttribute() {
- $count = $this->likeCount;
- $others = ( $this->liked() ) ? $count-1 : $count;
- return $others . $this->peopleString( $others );
- }
- /**
- * Only get published articles - query scope
- * @param query $query
- */
- public function scopePublished( $query )
- {
- $query
- ->where('published', true) // published
- ->whereNull('deleted_at'); // not deleted
- }
- /**
- * Only get unpublished articles
- */
- public function scopeUnpublished( $query )
- {
- $query->where('published', false);
- }
- /**
- * return list for $this->tag_list
- * @return Array
- */
- public function getTagListAttribute()
- {
- return $this->tags->lists('id')->all();
- }
- /**
- * Simple return for the created_at
- */
- public function getDateAttribute()
- {
- return $this->created_at;
- }
- /**
- * Return a human-readable difference
- * for the date attribute
- */
- public function getDateDiffAttribute()
- {
- return $this->created_at->diffForHumans();
- }
- }