263 lines
6.8 KiB
PHP
263 lines
6.8 KiB
PHP
<?php
|
|
|
|
namespace App\Domain\Feeds\Queries;
|
|
|
|
use App\Domain\Feeds\Models\Feed;
|
|
use App\Domain\Feeds\Enums\StatusEnum;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use App\Domain\Feeds\DataTransferObjects\FeedData;
|
|
use App\Domain\Subscriptions\Service\SubscriptionService;
|
|
|
|
class FeedQueryBuilder
|
|
{
|
|
const PAGINATION_COUNT = 10;
|
|
|
|
public $feed;
|
|
public $pagination = true;
|
|
public $onlyActiveFeed = true;
|
|
public $nextCursor;
|
|
public $is_ads = false;
|
|
public $hasPages;
|
|
|
|
public function __construct($query = null)
|
|
{
|
|
if($query){
|
|
$this->feed = $query;
|
|
}else{
|
|
$this->feed = Feed::query();
|
|
}
|
|
|
|
}
|
|
public function enableAdvertising()
|
|
{
|
|
$this->is_ads = true;
|
|
return $this;
|
|
}
|
|
|
|
public function search($filters)
|
|
{
|
|
$this->feed->when($filters['search'] ?? null, function ($query, $search) {
|
|
$query->where(function ($query) use ($search) {
|
|
$query->where('title', 'ilike', '%'.$search.'%')
|
|
->orWhere('body', 'ilike', '%'.$search.'%');
|
|
});
|
|
});
|
|
return $this;
|
|
}
|
|
|
|
public function addTags($tags)
|
|
{
|
|
$this->feed->whereHas('tags', function (Builder $query) use($tags) {
|
|
$query->whereIn('id', $tags);
|
|
});
|
|
return $this;
|
|
}
|
|
|
|
public function addType($type)
|
|
{
|
|
if($type == 'image'){
|
|
//$this->feed->whereHasMorph('feedable', [Image::class]);
|
|
$this->feed->where('type', 'images');
|
|
}
|
|
if($type == 'video'){
|
|
// $this->feed->whereHasMorph('feedable', [Video::class]);
|
|
$this->feed->where('type', 'videos');
|
|
}
|
|
if($type == 'music'){
|
|
//$this->feed->whereHasMorph('feedable', [Music::class]);
|
|
$this->feed->where('type', 'musics');
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
public function filter($filter = null)
|
|
{
|
|
if($filter === 'hot'){
|
|
return $this->order('likes_count');
|
|
}
|
|
return $this->order();
|
|
}
|
|
|
|
public function order($by = null)
|
|
{
|
|
if($by){
|
|
$this->feed->orderBy($by, 'desc');
|
|
}else{
|
|
$this->feed->orderBy('id', 'desc');
|
|
}
|
|
return $this;
|
|
|
|
}
|
|
|
|
public function selectBy($where, $by)
|
|
{
|
|
$this->feed->where($where, $by);
|
|
return $this;
|
|
}
|
|
|
|
public function selectByIds($ids)
|
|
{
|
|
if(is_array($ids)){
|
|
$this->feed->whereIn('id', $ids);
|
|
}else{
|
|
$this->feed->where('id', $ids);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
public function withTrashed() {
|
|
$this->feed->withTrashed();
|
|
return $this;
|
|
}
|
|
|
|
public function disableActiveFeed()
|
|
{
|
|
$this->onlyActiveFeed = false;
|
|
return $this;
|
|
}
|
|
|
|
public function disablePaginate()
|
|
{
|
|
$this->pagination = false;
|
|
return $this;
|
|
}
|
|
|
|
public function getData()
|
|
{
|
|
if($this->onlyActiveFeed){
|
|
$this->feed = $this->feed->where('status', StatusEnum::APPROVED());
|
|
}
|
|
$this->feed = $this->feed->withCount([
|
|
'comments',
|
|
'likes',
|
|
]);
|
|
|
|
if(auth()->user()){
|
|
$this->feed = $this->feed
|
|
->withCount(['likes as liked' => function (Builder $query) {
|
|
$query->where('user_id', auth()->user()->id);
|
|
}])
|
|
->withCasts(['liked' => 'boolean']);
|
|
}
|
|
if($this->pagination){
|
|
$this->feed = $this->feed->cursorPaginate(self::PAGINATION_COUNT);
|
|
$this->getCursorHash();
|
|
}else{
|
|
$this->feed = $this->feed->get();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
protected function getCursorHash()
|
|
{
|
|
$this->hasPages = $this->feed->hasMorePages();
|
|
$this->nextCursor = get_cursor_hash($this->feed);
|
|
}
|
|
|
|
public function withTags()
|
|
{
|
|
$this->feed->with('tags:id,name,slug');
|
|
return $this;
|
|
}
|
|
|
|
public function withUser()
|
|
{
|
|
$this->feed->with('user:id,first_name,last_name,username,photo_path,color,user_char,private');
|
|
return $this;
|
|
}
|
|
|
|
public function withFeedable()
|
|
{
|
|
|
|
// $this->feed->with('media');
|
|
// :id,model_type,model_id,name,file_name,collection_name,custom_properties
|
|
|
|
if(auth()->user()){
|
|
$this->feed->withCount('media')
|
|
->with(['media' => function($query){
|
|
// withCount('likes')->withCasts(['likes_count' => 'boolean']);
|
|
$query->withCount(['likes' => function (Builder $query) {
|
|
$query->where('user_id', auth()->user()->id);
|
|
}])->withCasts(['likes_count' => 'boolean']);
|
|
}]);
|
|
}else{
|
|
$this->feed->with('media');
|
|
}
|
|
|
|
|
|
return $this;
|
|
|
|
// $this->feed->with('feedable', function (MorphTo $morphTo) {
|
|
// $morphTo->morphWith([
|
|
// Image::class => ['media'],
|
|
// Video::class => ['media'],
|
|
// Music::class => ['media'],
|
|
// ]);
|
|
// });
|
|
// return $this;
|
|
}
|
|
|
|
public function transformData()
|
|
{
|
|
$feed_collect = collect();
|
|
|
|
if(auth()->user()){
|
|
$purchased_subscriptions_by_users = \DB::table('users_package_customers')
|
|
->where('customer_id', auth()->user()->id)
|
|
->where('time_end', '>', now())
|
|
->pluck('user_id')->toArray();
|
|
}else{
|
|
$purchased_subscriptions_by_users = [];
|
|
}
|
|
|
|
foreach ($this->feed as $feed) {
|
|
$feed = FeedData::fromDataBaseWithUser($feed, $purchased_subscriptions_by_users);
|
|
if($feed['entity']){
|
|
$feed['entity']->tags->transform(function ($item) {
|
|
return [
|
|
'id' => $item->id,
|
|
'name' => $item->name,
|
|
'slug' => $item->slug,
|
|
];
|
|
});
|
|
}
|
|
|
|
$feed_collect[] = $feed;
|
|
}
|
|
|
|
if(auth()->check()){
|
|
$subscription_purchased = SubscriptionService::activeSubscription();
|
|
if($subscription_purchased == false){
|
|
$adsMedia = Feed::where('is_ads', true)->with('media')->inRandomOrder()->first();
|
|
if($adsMedia && $this->is_ads){
|
|
$adsMediaData = FeedData::fromAds($adsMedia);
|
|
$feed_collect->splice(4, 0, [$adsMediaData]);
|
|
}
|
|
}
|
|
}
|
|
return $feed_collect;
|
|
}
|
|
|
|
public function build()
|
|
{
|
|
$this
|
|
->withFeedable()
|
|
->withUser()
|
|
->withTags()
|
|
->getData();
|
|
return $this;
|
|
}
|
|
|
|
public function transformGet()
|
|
{
|
|
|
|
return $this
|
|
->withFeedable()
|
|
->withUser()
|
|
->withTags()
|
|
->getData()->transformData();
|
|
}
|
|
|
|
}
|