Последняя версия с сервера прошлого разработчика
This commit is contained in:
92
app/Console/Commands/AutoSubscribeApp.php
Executable file
92
app/Console/Commands/AutoSubscribeApp.php
Executable file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use DB;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Domain\Subscriptions\Models\Package;
|
||||
use App\Domain\Subscriptions\Models\Subscription;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class AutoSubscribeApp extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'teaser:auto-subs-app';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Autosubscription to the site';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$plan = Package::findOrFail(1);
|
||||
$price = $plan->price;
|
||||
|
||||
$lists = DB::table('subscriptions')
|
||||
->join('users', 'subscriptions.user_id', '=', 'users.id')
|
||||
->selectRaw('subscriptions.user_id, MAX(subscriptions.ends_at) as last_time, users.autosubscription_site')
|
||||
->groupBy('subscriptions.user_id', 'users.autosubscription_site')
|
||||
->havingRaw('MAX(subscriptions.ends_at) <= ?', [now()])
|
||||
->having('users.autosubscription_site', true)
|
||||
->get();
|
||||
|
||||
foreach($lists as $list){
|
||||
$balance = SubscriptionService::calculate($list->user_id);
|
||||
$ends_at = Carbon::now()->addMonths();
|
||||
|
||||
if ($price > $balance) {
|
||||
echo 'Недостаточно средств ' . $list->user_id . PHP_EOL;
|
||||
|
||||
DB::table('users')
|
||||
->where('id', $list->user_id)
|
||||
->update(['autosubscription_site' => false]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$sub = new Subscription;
|
||||
$sub->user_id = $list->user_id;
|
||||
$sub->package_id = $plan->id;
|
||||
$sub->price = $price;
|
||||
$sub->ends_at = $ends_at;
|
||||
$sub->status = 'complete'; //YSV ENUM!
|
||||
$sub->save();
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id =$list->user_id;
|
||||
$point->point = $price;
|
||||
$point->type = 'Оплата за подписку'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::EXPENSE();
|
||||
$point->save();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
182
app/Console/Commands/AutoSubscribePaidUsers.php
Executable file
182
app/Console/Commands/AutoSubscribePaidUsers.php
Executable file
@@ -0,0 +1,182 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use DB;
|
||||
use App\Models\User;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Users\Models\UserPackage;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Notifications\UserCustomPaidSubscription;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class AutoSubscribePaidUsers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'teaser:user-auto-subs';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Auto-subscription for paid users';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
\DB::beginTransaction();
|
||||
|
||||
$users_package_customers = DB::table('users_package_customers')
|
||||
// ->join('users_subscribers', 'users_package_customers.customer_id', '=', 'users_subscribers.subscriber_id')
|
||||
->join('users_subscribers', function ($join) {
|
||||
$join
|
||||
->on('users_package_customers.user_id', '=', 'users_subscribers.subscriber_id')
|
||||
->where('users_subscribers.autosubscription', true);
|
||||
})
|
||||
//->select('users_package_customers.*', 'users_subscribers.user_id as userId', 'users_subscribers.subscriber_id as subscriberId', 'users_subscribers.autosubscription')
|
||||
->select(DB::raw('MAX(users_package_customers.time_end) as last_time,users_package_customers.customer_id,users_package_customers.package_id','users_subscribers.autosubscription'))
|
||||
->groupBy('users_package_customers.customer_id', 'users_package_customers.package_id', 'users_subscribers.autosubscription')
|
||||
->havingRaw('MAX(users_package_customers.time_end) <= ?', [now()])
|
||||
->get();
|
||||
|
||||
|
||||
foreach ($users_package_customers as $user_package_customers) {
|
||||
$userCustomer = User::find($user_package_customers->customer_id);
|
||||
$userPackage = UserPackage::find($user_package_customers->package_id);
|
||||
$userHeadPackage = User::find($userPackage->user_id);
|
||||
$balance = SubscriptionService::calculate($userCustomer->id);
|
||||
|
||||
if ($userPackage->price > $balance) {
|
||||
DB::table('users_subscribers')
|
||||
->where('user_id', $userCustomer->id)
|
||||
->where('subscriber_id', $userHeadPackage->id)
|
||||
->update(['autosubscription' => DB::raw('NOT autosubscription')]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
DB::table('users_package_customers')->insert([
|
||||
'user_id' => $userHeadPackage->id,
|
||||
'customer_id' => $userCustomer->id,
|
||||
'package_id' => $userPackage->id,
|
||||
'price' => $userPackage->price,
|
||||
'time_end' => now()->addMonths(),
|
||||
//'time_end' => now()->addMinutes(10),
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = $userCustomer->id;
|
||||
$point->point = $userPackage->price;
|
||||
$point->type = 'Оформлена подписка на пользователя: ' . $userHeadPackage->name . ' (' . $userHeadPackage->username . ')'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::EXPENSE();
|
||||
$point->save();
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = $userHeadPackage->id;
|
||||
$point->point = $userPackage->price;
|
||||
$point->type = 'Пользователь оформил платную подписку: ' . $userCustomer->name . ' (' . $userCustomer->username . ')'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
|
||||
$message = [
|
||||
'user_id' => $userCustomer->id,
|
||||
'node_id' => null,
|
||||
];
|
||||
$userHeadPackage->notify(new UserCustomPaidSubscription($message));
|
||||
|
||||
|
||||
}
|
||||
|
||||
\DB::commit();
|
||||
// dd($users_package_customers);
|
||||
|
||||
return 0;
|
||||
// max
|
||||
// $users_package_customers = DB::table('users_package_customers')
|
||||
// ->select(DB::raw('max(time_end) as last_time, avg(attempt_auto_paid) as attempt_auto_paid_avg,customer_id,package_id'))
|
||||
// ->groupBy('customer_id', 'package_id')
|
||||
// ->havingRaw('MAX(time_end) <= ?', [now()])
|
||||
// ->havingRaw('AVG(attempt_auto_paid) < ?', [3])
|
||||
// ->get();
|
||||
|
||||
|
||||
// foreach ($users_package_customers as $users_package_customer) {
|
||||
// $userCustomer = User::find($users_package_customer->customer_id);
|
||||
|
||||
// $userPackage = UserPackage::find($users_package_customer->package_id);
|
||||
// $userHeadPackage = User::find($userPackage->user_id);
|
||||
|
||||
// $balance = SubscriptionService::calculate($userCustomer->id);
|
||||
|
||||
// if ($userPackage->price > $balance) {
|
||||
// DB::table('users_package_customers')
|
||||
// ->where('customer_id', $users_package_customer->customer_id)
|
||||
// ->where('package_id', $users_package_customer->package_id)
|
||||
// ->increment('attempt_auto_paid');
|
||||
// continue;
|
||||
// }
|
||||
|
||||
|
||||
// DB::table('users_package_customers')->insert([
|
||||
// 'user_id' => $userHeadPackage->id,
|
||||
// 'customer_id' => $userCustomer->id,
|
||||
// 'package_id' => $userPackage->id,
|
||||
// 'price' => $userPackage->price,
|
||||
// // 'time_end' => now()->addMonths(),
|
||||
// 'time_end' => now()->addMinutes(10),
|
||||
// 'created_at' => now(),
|
||||
// ]);
|
||||
|
||||
|
||||
// $point = new Point;
|
||||
// $point->user_id = $userCustomer->id;
|
||||
// $point->point = $userPackage->price;
|
||||
// $point->type = 'Оформлена подписка на пользователя: ' . $userHeadPackage->username; //YSV ENUM!
|
||||
// $point->direction = DirectionEnum::EXPENSE();
|
||||
// $point->save();
|
||||
|
||||
// $point = new Point;
|
||||
// $point->user_id = $userHeadPackage->id;
|
||||
// $point->point = $userPackage->price;
|
||||
// $point->type = 'Пользователь оформил платную подписку: ' . $userCustomer->username; //YSV ENUM!
|
||||
// $point->direction = DirectionEnum::COMING();
|
||||
// $point->save();
|
||||
|
||||
|
||||
// $message = [
|
||||
// 'user_id' => $userCustomer->id,
|
||||
// 'node_id' => null,
|
||||
// ];
|
||||
// $userHeadPackage->notify(new UserCustomPaidSubscription($message));
|
||||
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// return 0;
|
||||
|
||||
}
|
||||
}
|
||||
43
app/Console/Kernel.php
Executable file
43
app/Console/Kernel.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* The Artisan commands provided by your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*
|
||||
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||
* @return void
|
||||
*/
|
||||
protected function schedule(Schedule $schedule)
|
||||
{
|
||||
$schedule->command('teaser:user-auto-subs')->weekly();
|
||||
|
||||
$schedule->command('teaser:auto-subs-app')->weekly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the commands for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function commands()
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
45
app/Domain/Comments/Models/Comment.php
Executable file
45
app/Domain/Comments/Models/Comment.php
Executable file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
namespace App\Domain\Comments\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use App\Domain\Complaints\Models\CommentComplaint;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
|
||||
use SoftDeletes;
|
||||
|
||||
public function feed()
|
||||
{
|
||||
return $this->belongsTo(Feed::class);
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function answer_to()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'to_user_id');
|
||||
}
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(Comment::class, 'parent_id');
|
||||
}
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'parent_id');
|
||||
}
|
||||
|
||||
|
||||
public function complaints()
|
||||
{
|
||||
return $this->hasMany(CommentComplaint::class);
|
||||
}
|
||||
|
||||
}
|
||||
20
app/Domain/Comments/Observers/NovaCommentObserver.php
Executable file
20
app/Domain/Comments/Observers/NovaCommentObserver.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Comments\Observers;
|
||||
|
||||
use App\Domain\Comments\Models\Comment;
|
||||
|
||||
class NovaCommentObserver
|
||||
{
|
||||
public function deleting(Comment $comment)
|
||||
{
|
||||
if(!$comment->trashed()){
|
||||
$complaints = $comment->complaints;
|
||||
foreach ($complaints as $complaint) {
|
||||
$complaint->status = 'reviewed_bad';
|
||||
$complaint->moderator_checking_id = auth()->id();
|
||||
$complaint->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
32
app/Domain/Complaints/Models/CommentComplaint.php
Executable file
32
app/Domain/Complaints/Models/CommentComplaint.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Complaints\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
use App\Domain\Comments\Models\Comment;
|
||||
use App\Domain\Complaints\Models\Reason;
|
||||
|
||||
class CommentComplaint extends Model
|
||||
{
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function moderator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'moderator_checking_id');
|
||||
}
|
||||
|
||||
public function reason()
|
||||
{
|
||||
return $this->belongsTo(Reason::class);
|
||||
}
|
||||
|
||||
public function comment()
|
||||
{
|
||||
return $this->belongsTo(Comment::class);
|
||||
}
|
||||
}
|
||||
36
app/Domain/Complaints/Models/Complaint.php
Executable file
36
app/Domain/Complaints/Models/Complaint.php
Executable file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\Domain\Complaints\Models;
|
||||
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Complaint extends Model
|
||||
{
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function moderator()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'moderator_checking_id');
|
||||
}
|
||||
|
||||
public function reason()
|
||||
{
|
||||
return $this->belongsTo(Reason::class);
|
||||
}
|
||||
|
||||
public function feed()
|
||||
{
|
||||
return $this->belongsTo(Feed::class);
|
||||
}
|
||||
|
||||
}
|
||||
10
app/Domain/Complaints/Models/Reason.php
Executable file
10
app/Domain/Complaints/Models/Reason.php
Executable file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Complaints\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class Reason extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
}
|
||||
14
app/Domain/Complaints/Observers/ComplaintObserver.php
Executable file
14
app/Domain/Complaints/Observers/ComplaintObserver.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace App\Domain\Complaints\Observers;
|
||||
|
||||
use App\Domain\Complaints\Models\Complaint;
|
||||
|
||||
class ComplaintObserver
|
||||
{
|
||||
public function updating(Complaint $complaint)
|
||||
{
|
||||
if (empty($complaint->moderator_checking_id)) {
|
||||
$complaint->moderator_checking_id = auth()->user()->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
29
app/Domain/Feeds/Action/CreateFeedAction.php
Executable file
29
app/Domain/Feeds/Action/CreateFeedAction.php
Executable file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\Action;
|
||||
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Tags\Action\CreateTagAction;
|
||||
|
||||
class CreateFeedAction
|
||||
{
|
||||
public $tooFeedAction;
|
||||
public $tagAction;
|
||||
|
||||
|
||||
public function __construct(ToFeedAction $tooFeedAction, CreateTagAction $tagAction)
|
||||
{
|
||||
$this->tooFeedAction = $tooFeedAction;
|
||||
$this->tagAction = $tagAction;
|
||||
}
|
||||
|
||||
public function __invoke($dataFeed)
|
||||
{
|
||||
|
||||
$feed = ($this->tooFeedAction)($dataFeed);
|
||||
|
||||
if(count($dataFeed->tags)){
|
||||
$idsTag = ($this->tagAction)($dataFeed->tags);
|
||||
$feed->tags()->sync($idsTag);
|
||||
}
|
||||
}
|
||||
}
|
||||
136
app/Domain/Feeds/DataTransferObjects/FeedData.php
Executable file
136
app/Domain/Feeds/DataTransferObjects/FeedData.php
Executable file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\DataTransferObjects;
|
||||
|
||||
use App\Domain\Feeds\Enums\CollectionMediaEnum;
|
||||
use App\Domain\Feeds\Service\FeedMediaTransform;
|
||||
use Spatie\DataTransferObject\DataTransferObject;
|
||||
|
||||
class FeedData extends DataTransferObject
|
||||
{
|
||||
|
||||
public static function fromAds($feed)
|
||||
{
|
||||
$user = new \stdClass();
|
||||
$user->id = 999999;
|
||||
$user->name = 'Реклама';
|
||||
$user->username = 'Реклама';
|
||||
$user->color = '#795541';
|
||||
$user->user_char = 'AD';
|
||||
|
||||
return [
|
||||
'id' => $feed->id,
|
||||
'type' => $feed->type,
|
||||
'user' => (array)$user,
|
||||
'entity' => self::fromDataAds($feed, CollectionMediaEnum::COMMON()),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function fromDataAds($feed, $collection_media_name)
|
||||
{
|
||||
$entity = (object) [];
|
||||
$entity->title = $feed->title;
|
||||
$entity->body = nl2br($feed->body);
|
||||
$entity->views_count = $feed->views_count;
|
||||
$entity->slug = $feed->slug;
|
||||
$entity->type = $feed->type;
|
||||
$entity->created_at_humans = $feed->created_at->diffForHumans();
|
||||
$mediaTransform = (new FeedMediaTransform($feed))
|
||||
->addCollectionMediaName($collection_media_name)
|
||||
->spot();
|
||||
$entity->preview = $mediaTransform['preview'];
|
||||
$entity->collection_medias = $mediaTransform['medias'];
|
||||
|
||||
$entity->is_ads = true;
|
||||
$entity->is_repost = false;
|
||||
$entity->price = null;
|
||||
$entity->is_paid = 0;
|
||||
$entity->likes = 0;
|
||||
$entity->liked = false;
|
||||
$entity->tags = [];
|
||||
$entity->status = 1;
|
||||
$entity->comments = 0;
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
|
||||
public static function fromDataBaseWithUser($feed, $purchased_subscriptions_by_users = [])
|
||||
{
|
||||
$feed_is_restrict = false;
|
||||
$feed_is_restrict_name = '';
|
||||
|
||||
$feed_user_id = $feed->user_id;
|
||||
|
||||
$is_my_feed = false;
|
||||
if(auth()->user()){
|
||||
$is_my_feed = auth()->user()->id === $feed_user_id;
|
||||
}
|
||||
|
||||
|
||||
$feed_is_semi_paid = $feed->is_paid === 2;
|
||||
|
||||
// $is_adult_feed = false;
|
||||
// $is_my_settings_adult_restrict = auth()->user()->allow_adult_content;
|
||||
$restrict_feed_adult = false;
|
||||
|
||||
// if(($is_my_settings_adult_restrict === false && $is_adult_feed) && $is_my_feed === false){
|
||||
// $feed_is_restrict_name = 'adults';
|
||||
// $restrict_feed_adult = true;
|
||||
// }
|
||||
|
||||
$private_user_feed = $feed->user->private;
|
||||
$restrict_feed_private_account = false;
|
||||
if(($feed_is_semi_paid && $private_user_feed && !in_array($feed_user_id, $purchased_subscriptions_by_users)) && $is_my_feed === false){
|
||||
$feed_is_restrict_name = 'prohibited';
|
||||
$restrict_feed_private_account = true;
|
||||
}
|
||||
|
||||
|
||||
if($restrict_feed_adult || $restrict_feed_private_account){
|
||||
$feed_is_restrict = true;
|
||||
}
|
||||
|
||||
$user = $feed->user->only('id', 'name', 'username', 'photo_path', 'color', 'user_char', 'private');
|
||||
return [
|
||||
'id' => $feed->id,
|
||||
'type' => $feed_is_restrict ? $feed_is_restrict_name : $feed->type,
|
||||
'user' => $user,
|
||||
'entity' => $feed_is_restrict ? null : self::fromData($feed, CollectionMediaEnum::COMMON()),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function fromData($feed, $collection_media_name)
|
||||
{
|
||||
$entity = (object) [];
|
||||
$entity->title = $feed->title;
|
||||
$entity->body = $feed->body;
|
||||
$entity->views_count = $feed->views_count;
|
||||
$entity->price = $feed->price;
|
||||
$entity->is_paid = $feed->is_paid;
|
||||
$entity->is_ads = false;
|
||||
// $entity->is_adult = $feed->is_adult;
|
||||
$entity->slug = $feed->slug;
|
||||
$entity->type = $feed->type;
|
||||
$entity->is_repost = $feed->is_repost;
|
||||
|
||||
$entity->likes = $feed->likes_count;
|
||||
$entity->liked = $feed->liked ?? false;
|
||||
$entity->tags = $feed->tags;
|
||||
$entity->status = $feed->status;
|
||||
$entity->comments = $feed->comments_count;
|
||||
$entity->created_at_humans = $feed->created_at->diffForHumans();
|
||||
|
||||
$mediaTransform = (new FeedMediaTransform($feed))
|
||||
->addCollectionMediaName($collection_media_name)
|
||||
->spot();
|
||||
|
||||
|
||||
$entity->preview = $mediaTransform['preview'];
|
||||
$entity->collection_medias = $mediaTransform['medias'];
|
||||
|
||||
return $entity;
|
||||
}
|
||||
}
|
||||
12
app/Domain/Feeds/DataTransferObjects/FeedDataCollection.php
Executable file
12
app/Domain/Feeds/DataTransferObjects/FeedDataCollection.php
Executable file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\DataTransferObjects;
|
||||
|
||||
use Spatie\DataTransferObject\DataTransferObjectCollection;
|
||||
|
||||
class FeedDataCollection extends DataTransferObjectCollection
|
||||
{
|
||||
public static function create(array $data)
|
||||
{
|
||||
return new static(FeedData::arrayOf($data));
|
||||
}
|
||||
}
|
||||
21
app/Domain/Feeds/Enums/CollectionMediaEnum.php
Executable file
21
app/Domain/Feeds/Enums/CollectionMediaEnum.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\Enums;
|
||||
|
||||
use Spatie\Enum\Laravel\Enum;
|
||||
|
||||
/**
|
||||
* @method static self PREVIEW()
|
||||
* @method static self PAID()
|
||||
* @method static self COMMON()
|
||||
*/
|
||||
final class CollectionMediaEnum extends Enum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'PREVIEW' => 'preview',
|
||||
'PAID' => 'paid',
|
||||
'COMMON' => 'common',
|
||||
];
|
||||
}
|
||||
}
|
||||
23
app/Domain/Feeds/Enums/StatusEnum.php
Executable file
23
app/Domain/Feeds/Enums/StatusEnum.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\Enums;
|
||||
|
||||
use Spatie\Enum\Laravel\Enum;
|
||||
|
||||
/**
|
||||
* @method static self PENDING()
|
||||
* @method static self APPROVED()
|
||||
* @method static self BANNED()
|
||||
* @method static self EDITABLE()
|
||||
*/
|
||||
final class StatusEnum extends Enum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'PENDING' => 0,
|
||||
'APPROVED' => 1,
|
||||
'BANNED' => 2,
|
||||
'EDITABLE' => 3,
|
||||
];
|
||||
}
|
||||
}
|
||||
76
app/Domain/Feeds/Models/Feed.php
Executable file
76
app/Domain/Feeds/Models/Feed.php
Executable file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
use App\Domain\Tags\Models\Tag;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Domain\Comments\Models\Comment;
|
||||
use App\Domain\Complaints\Models\Complaint;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
use App\Domain\Feeds\Observers\FeedObserver;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Feed extends Model implements HasMedia
|
||||
{
|
||||
use InteractsWithMedia, SoftDeletes;
|
||||
|
||||
public function getUserTypeAttribute()
|
||||
{
|
||||
return $this->user->type;
|
||||
}
|
||||
|
||||
protected $casts = [
|
||||
'is_paid' => 'integer',
|
||||
'is_ads' => 'boolean',
|
||||
'status' => StatusEnum::class,
|
||||
];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
self::observe(FeedObserver::class);
|
||||
}
|
||||
|
||||
public function feedable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
public function tags()
|
||||
{
|
||||
return $this->belongsToMany(Tag::class, 'feed_tags');
|
||||
}
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
}
|
||||
|
||||
public function views()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'users_feeds_view');
|
||||
}
|
||||
|
||||
public function likes()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'users_feeds_like');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function who_boughts()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'user_feed_purchase')->withPivot('amount')->withTimestamps();
|
||||
}
|
||||
|
||||
public function complaints()
|
||||
{
|
||||
return $this->hasMany(Complaint::class);
|
||||
}
|
||||
}
|
||||
40
app/Domain/Feeds/Observers/FeedObserver.php
Executable file
40
app/Domain/Feeds/Observers/FeedObserver.php
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Feeds\Observers;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Events\FeedAddProcessed;
|
||||
use App\Events\FeedRemoveProcessed;
|
||||
use App\Events\FeedUpdateProcessed;
|
||||
|
||||
class FeedObserver
|
||||
{
|
||||
public function creating(Feed $feed)
|
||||
{
|
||||
$uuid = (string) Str::uuid();
|
||||
$feed->slug = $uuid . '_' . $feed->type;
|
||||
}
|
||||
|
||||
|
||||
public function created(Feed $feed)
|
||||
{
|
||||
FeedAddProcessed::dispatch($feed);
|
||||
}
|
||||
|
||||
public function deleted(Feed $feed)
|
||||
{
|
||||
FeedRemoveProcessed::dispatch($feed);
|
||||
}
|
||||
|
||||
// public function forceDeleted(Feed $feed)
|
||||
// {
|
||||
// dd('forceDeleted');
|
||||
// }
|
||||
|
||||
public function updated(Feed $feed)
|
||||
{
|
||||
FeedUpdateProcessed::dispatch($feed);
|
||||
}
|
||||
|
||||
}
|
||||
19
app/Domain/Feeds/Observers/NovaFeedAdsObserver.php
Executable file
19
app/Domain/Feeds/Observers/NovaFeedAdsObserver.php
Executable file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Feeds\Observers;
|
||||
use App\Models\User;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
|
||||
|
||||
class NovaFeedAdsObserver
|
||||
{
|
||||
public function creating(Feed $feed){
|
||||
if(str_contains( request()->getPathInfo(), '/nova-api/feed-ads')){
|
||||
$user = User::system();
|
||||
$feed->user_id = $user->id;
|
||||
$feed->is_ads = true;
|
||||
$feed->created_at = now();
|
||||
$feed->updated_at = now();
|
||||
}
|
||||
}
|
||||
}
|
||||
61
app/Domain/Feeds/Observers/NovaFeedObserver.php
Executable file
61
app/Domain/Feeds/Observers/NovaFeedObserver.php
Executable file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Feeds\Observers;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Notifications\RemoveFeed;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Notifications\BannedMessageFeed;
|
||||
|
||||
class NovaFeedObserver
|
||||
{
|
||||
|
||||
public function updating(Feed $feed)
|
||||
{
|
||||
$oldStatus = $feed->getOriginal('status');
|
||||
$newStatus = $feed->status;
|
||||
|
||||
if(($oldStatus === StatusEnum::PENDING() || $oldStatus === StatusEnum::EDITABLE()) && $newStatus === StatusEnum::BANNED()){
|
||||
$user = $feed->user;
|
||||
$message = [
|
||||
'user_id' => $user->id,
|
||||
'node_id' => $feed->id,
|
||||
'text' => $feed->status_note,
|
||||
'success' => false
|
||||
];
|
||||
$user->notify(new BannedMessageFeed($message));
|
||||
}
|
||||
|
||||
if(($oldStatus === StatusEnum::PENDING() || $oldStatus === StatusEnum::EDITABLE()) && $newStatus === StatusEnum::APPROVED()){
|
||||
$user = $feed->user;
|
||||
$message = [
|
||||
'user_id' => $user->id,
|
||||
'node_id' => $feed->id,
|
||||
'text' => $feed->status_note,
|
||||
'success' => true
|
||||
];
|
||||
$user->notify(new BannedMessageFeed($message));
|
||||
$feed->status_note = '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function deleting(Feed $feed)
|
||||
{
|
||||
|
||||
if(!$feed->trashed()){
|
||||
$complaints = $feed->complaints;
|
||||
foreach ($complaints as $complaint) {
|
||||
$complaint->status = 'reviewed_bad';
|
||||
$complaint->moderator_checking_id = auth()->id();
|
||||
$complaint->save();
|
||||
}
|
||||
|
||||
$user = $feed->user;
|
||||
$message = [
|
||||
'user_id' => $user->id,
|
||||
'node_id' => $feed->id,
|
||||
];
|
||||
$user->notify(new RemoveFeed($message));
|
||||
}
|
||||
}
|
||||
}
|
||||
262
app/Domain/Feeds/Queries/FeedQueryBuilder.php
Executable file
262
app/Domain/Feeds/Queries/FeedQueryBuilder.php
Executable file
@@ -0,0 +1,262 @@
|
||||
<?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();
|
||||
}
|
||||
|
||||
}
|
||||
139
app/Domain/Feeds/Service/FeedMediaTransform.php
Executable file
139
app/Domain/Feeds/Service/FeedMediaTransform.php
Executable file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
namespace App\Domain\Feeds\Service;
|
||||
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\Enums\CollectionMediaEnum;
|
||||
|
||||
class FeedMediaTransform
|
||||
{
|
||||
public $feed;
|
||||
public $type;
|
||||
public $typeUrl = 'web';
|
||||
public $collection_name;
|
||||
|
||||
public function __construct(Feed $feed)
|
||||
{
|
||||
$this->feed = $feed;
|
||||
$this->type = $feed->type;
|
||||
}
|
||||
|
||||
public function getFullPath()
|
||||
{
|
||||
$this->typeUrl = 'disk';
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function paid()
|
||||
{
|
||||
return $this->addCollectionMediaName(CollectionMediaEnum::PAID());
|
||||
}
|
||||
|
||||
public function default()
|
||||
{
|
||||
return $this->addCollectionMediaName(CollectionMediaEnum::COMMON());
|
||||
}
|
||||
|
||||
public function addCollectionMediaName($collection_name)
|
||||
{
|
||||
$this->collection_name = $collection_name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function spot()
|
||||
{
|
||||
if($this->type === 'images'){
|
||||
return $this->images();
|
||||
}
|
||||
|
||||
if($this->type === 'videos'){
|
||||
return $this->videos();
|
||||
}
|
||||
|
||||
if($this->type === 'musics'){
|
||||
return $this->musics();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function videos()
|
||||
{
|
||||
$collection = [];
|
||||
$medias = $this->feed->getMedia($this->collection_name);
|
||||
$medias->each(function ($item) use (&$collection) {
|
||||
$collection[] = [
|
||||
'url' => $this->typeUrl === 'web' ? $item->getFullUrl() : $item->getPath(),
|
||||
'id' => $item->id,
|
||||
];
|
||||
});
|
||||
return [
|
||||
'preview' => $this->getPreview(),
|
||||
'medias' => $collection,
|
||||
];
|
||||
}
|
||||
public function images()
|
||||
{
|
||||
|
||||
$collection = [];
|
||||
$medias = $this->feed->getMedia($this->collection_name);
|
||||
$medias->each(function ($item) use (&$collection) {
|
||||
$collection[] = [
|
||||
'url' => $this->typeUrl === 'web' ? $item->getFullUrl() : $item->getPath(),
|
||||
'id' => $item->id,
|
||||
];
|
||||
});
|
||||
return [
|
||||
'preview' => $this->getPreview(),
|
||||
'medias' => $collection,
|
||||
];
|
||||
}
|
||||
|
||||
public function musics()
|
||||
{
|
||||
$collection = [];
|
||||
$medias = $this->feed->getMedia($this->collection_name);
|
||||
|
||||
$medias->each(function ($item) use (&$collection) {
|
||||
$collection[] = [
|
||||
'url' => $this->typeUrl === 'web' ? $item->getFullUrl() : $item->getPath(),
|
||||
'name' => $item->name,
|
||||
'playing' => false,
|
||||
'liked' => $item->likes_count ?? false,
|
||||
'time' => $item->getCustomProperty('time'),
|
||||
'id' => $item->id,
|
||||
];
|
||||
});
|
||||
return [
|
||||
'preview' => $this->getPreview(),
|
||||
'medias' => $collection,
|
||||
];
|
||||
}
|
||||
|
||||
public function getPreview($type = 0)
|
||||
{
|
||||
if($this->type === 'images'){
|
||||
$img_preview = $this->feed->getMedia($this->collection_name)->first();
|
||||
if($img_preview){
|
||||
if($type){
|
||||
return $img_preview;
|
||||
}
|
||||
return $img_preview->getFullUrl();
|
||||
}
|
||||
}
|
||||
|
||||
$preview = $this->feed->getMedia(CollectionMediaEnum::PREVIEW());
|
||||
if($type){
|
||||
return $preview->count() ? $preview->first() : null;
|
||||
}
|
||||
|
||||
return $preview->count() ? $preview->first()->getFullUrl() : null;
|
||||
}
|
||||
|
||||
public function getPreviewObject()
|
||||
{
|
||||
$preview = $this->getPreview(1);
|
||||
if($preview){
|
||||
return [ 'id'=> $preview->id, 'url' => $preview->getFullUrl() ];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
38
app/Domain/Feeds/Service/LiveFeed.php
Executable file
38
app/Domain/Feeds/Service/LiveFeed.php
Executable file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Feeds\Service;
|
||||
|
||||
use DB;
|
||||
|
||||
class LiveFeed
|
||||
{
|
||||
public static function addBySub($user)
|
||||
{
|
||||
$userID = $user->id;
|
||||
$userFeeds = $user->feeds()->pluck('created_at', 'id')->transform(function ($item) {
|
||||
return ['times' => $item->getTimestamp()];
|
||||
})->toArray();
|
||||
$add_posts = [];
|
||||
|
||||
foreach ($userFeeds as $feedID => $userFeed) {
|
||||
$add_posts[] = [
|
||||
'feed_id' => $feedID,
|
||||
'user_id' => auth()->user()->id,
|
||||
'home_user_id' => $userID,
|
||||
'times' => $userFeed['times'],
|
||||
];
|
||||
}
|
||||
DB::table('users_live_feeds')->insertOrIgnore($add_posts);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static function removeBySub($user)
|
||||
{
|
||||
$userID = $user->id;
|
||||
DB::table('users_live_feeds')
|
||||
->where('home_user_id', $userID)
|
||||
->where('user_id', auth()->user()->id)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
8
app/Domain/Feeds/ToFeedAction.php
Executable file
8
app/Domain/Feeds/ToFeedAction.php
Executable file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Feeds;
|
||||
|
||||
interface ToFeedAction
|
||||
{
|
||||
|
||||
}
|
||||
40
app/Domain/Images/Action/CreateImageAction.php
Executable file
40
app/Domain/Images/Action/CreateImageAction.php
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Images\Action;
|
||||
|
||||
use DB;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Images\DataTransferObjects\ImageData;
|
||||
|
||||
class CreateImageAction implements ToFeedAction
|
||||
{
|
||||
public function __invoke(ImageData $imageData)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
$imageFeed = Feed::create([
|
||||
'title' => $imageData->title,
|
||||
'body' => $imageData->body,
|
||||
'price' => $imageData->price,
|
||||
'is_paid' => $imageData->is_paid,
|
||||
'user_id' => $imageData->user->id,
|
||||
'is_ads' => false,
|
||||
'type' => 'images',
|
||||
]);
|
||||
|
||||
foreach ($imageData->photos as $photo) {
|
||||
$imageFeed->addMedia($photo)->toMediaCollection('common');
|
||||
}
|
||||
|
||||
if($imageData->is_loaded_photos_paid){
|
||||
foreach ($imageData->photos_paid as $photo) {
|
||||
$imageFeed->addMedia($photo)->toMediaCollection('paid');
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $imageFeed;
|
||||
}
|
||||
}
|
||||
68
app/Domain/Images/Action/UpdateImageAction.php
Executable file
68
app/Domain/Images/Action/UpdateImageAction.php
Executable file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Images\Action;
|
||||
|
||||
use DB;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Domain\Images\DataTransferObjects\ImageData;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class UpdateImageAction implements ToFeedAction
|
||||
{
|
||||
|
||||
public $imageFeed;
|
||||
|
||||
public function __construct(Feed $imageFeed)
|
||||
{
|
||||
$this->imageFeed = $imageFeed;
|
||||
}
|
||||
|
||||
public function __invoke(ImageData $imageData)
|
||||
{
|
||||
|
||||
$status = $this->imageFeed->status;
|
||||
if($status === StatusEnum::BANNED()){
|
||||
$status = StatusEnum::EDITABLE();
|
||||
}
|
||||
if($status === StatusEnum::APPROVED()){
|
||||
$status = StatusEnum::EDITABLE();
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
|
||||
$this->imageFeed->fill([
|
||||
'title' => $imageData->title,
|
||||
'body' => $imageData->body,
|
||||
'price' => $imageData->price,
|
||||
'is_paid' => $imageData->is_paid,
|
||||
'status' => $status,
|
||||
'is_ads' => false,
|
||||
])->save();
|
||||
|
||||
if($imageData->is_loaded_photos){
|
||||
foreach ($imageData->photos as $photo) {
|
||||
$this->imageFeed->addMedia($photo)->toMediaCollection('common');
|
||||
}
|
||||
}
|
||||
|
||||
if($imageData->is_loaded_photos_paid){
|
||||
foreach ($imageData->photos_paid as $photo) {
|
||||
$this->imageFeed->addMedia($photo)->toMediaCollection('paid');
|
||||
}
|
||||
}
|
||||
|
||||
if(count($imageData->removedItems)){
|
||||
foreach ($imageData->removedItems as $removedItem) {
|
||||
if($media = Media::find($removedItem)){
|
||||
$media->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $this->imageFeed->refresh();
|
||||
}
|
||||
}
|
||||
41
app/Domain/Images/DataTransferObjects/ImageData.php
Executable file
41
app/Domain/Images/DataTransferObjects/ImageData.php
Executable file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Images\DataTransferObjects;
|
||||
|
||||
use App\Http\Requests\ImageFormRequest;
|
||||
use Spatie\DataTransferObject\DataTransferObject;
|
||||
|
||||
class ImageData extends DataTransferObject
|
||||
{
|
||||
public $title;
|
||||
public $body;
|
||||
public $user;
|
||||
public $photos;
|
||||
public $price;
|
||||
public $tags;
|
||||
public $is_paid;
|
||||
public $is_loaded_photos_paid;
|
||||
public $is_loaded_photos;
|
||||
public $photos_paid;
|
||||
public $removedItems;
|
||||
|
||||
public static function fromRequest(ImageFormRequest $request)
|
||||
{
|
||||
return new self([
|
||||
'title' => $request->input('title'),
|
||||
'body' => $request->input('body'),
|
||||
'price' => $request->input('price'),
|
||||
'is_paid' => $request->input('is_paid'),
|
||||
'user' => auth()->user(),
|
||||
'tags' => $request->input('tags') ?? [],
|
||||
|
||||
'photos' => $request->file('photos'),
|
||||
'is_loaded_photos' => $request->hasFile('photos'),
|
||||
|
||||
'photos_paid' => $request->file('photos_paid'),
|
||||
'is_loaded_photos_paid' => $request->hasFile('photos_paid'),
|
||||
|
||||
'removedItems' => $request->input('removedItems') ?? [],
|
||||
]);
|
||||
}
|
||||
}
|
||||
32
app/Domain/Images/Models/Image.php
Executable file
32
app/Domain/Images/Models/Image.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Images\Models;
|
||||
|
||||
use App\Domain\Complaints\Models\Complaint;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
class Image extends Model implements HasMedia
|
||||
{
|
||||
use InteractsWithMedia;
|
||||
|
||||
public function feed()
|
||||
{
|
||||
return $this->morphOne(Feed::class, 'feedable');
|
||||
}
|
||||
|
||||
public function complaints()
|
||||
{
|
||||
return $this->morphMany(Complaint::class, 'complaintable');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
17
app/Domain/Medias/Models/TeaserMedia.php
Executable file
17
app/Domain/Medias/Models/TeaserMedia.php
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Medias\Models;
|
||||
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class TeaserMedia extends Media
|
||||
{
|
||||
|
||||
protected $table = 'media';
|
||||
|
||||
public function likes()
|
||||
{
|
||||
return $this->belongsToMany(\App\Models\User::class, 'user_audio_like', 'media_id', 'user_id');
|
||||
}
|
||||
|
||||
}
|
||||
25
app/Domain/Messenger/Models/ChatRoom.php
Executable file
25
app/Domain/Messenger/Models/ChatRoom.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Messenger\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
|
||||
class ChatRoom extends Model
|
||||
{
|
||||
|
||||
public function messsages()
|
||||
{
|
||||
return $this->hasMany(Message::class)->orderBy('created_at', 'desc');
|
||||
}
|
||||
|
||||
public function latestMessage()
|
||||
{
|
||||
return $this->hasOne(Message::class)->latestOfMany();
|
||||
}
|
||||
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany(User::class, 'user_chat_room');
|
||||
}
|
||||
}
|
||||
24
app/Domain/Messenger/Models/Message.php
Executable file
24
app/Domain/Messenger/Models/Message.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Messenger\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
use App\Domain\Messenger\Models\ChatRoom;
|
||||
|
||||
class Message extends Model
|
||||
{
|
||||
|
||||
// protected $touches = ['room'];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function room()
|
||||
{
|
||||
return $this->belongsTo(ChatRoom::class, 'chat_room_id');
|
||||
}
|
||||
|
||||
}
|
||||
70
app/Domain/Musics/Action/CreateMusicAction.php
Executable file
70
app/Domain/Musics/Action/CreateMusicAction.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
namespace App\Domain\Musics\Action;
|
||||
|
||||
use DB;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Musics\DataTransferObjects\MusicData;
|
||||
|
||||
class CreateMusicAction implements ToFeedAction
|
||||
{
|
||||
public function __invoke(MusicData $musicData)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
if(empty($musicData->title)){
|
||||
$file_count = count($musicData->musics);
|
||||
$first_file = $musicData->musics[0]->getClientOriginalName();
|
||||
$filename = pathinfo($first_file, PATHINFO_FILENAME);
|
||||
$musicData->title = $filename . ' (' . $file_count . ')';
|
||||
}
|
||||
|
||||
$musicFeed = Feed::create([
|
||||
'title' => $musicData->title,
|
||||
'body' => $musicData->body,
|
||||
'price' => $musicData->price,
|
||||
'is_paid' => $musicData->is_paid,
|
||||
'user_id' => $musicData->user->id,
|
||||
'is_ads' => false,
|
||||
'type' => 'musics',
|
||||
]);
|
||||
|
||||
$result_time_common = $this->calcTimeFile($musicData->times);
|
||||
|
||||
foreach ($musicData->musics as $music) {
|
||||
$name = $music->getClientOriginalName();
|
||||
$time = @$result_time_common[$name];
|
||||
$musicFeed->addMedia($music)
|
||||
->withCustomProperties(['time' => $time])
|
||||
->toMediaCollection('common');
|
||||
}
|
||||
if($musicData->is_loaded_preview){
|
||||
$musicFeed->addMedia($musicData->preview)->toMediaCollection('preview');
|
||||
}
|
||||
|
||||
if($musicData->is_loaded_paid_music){
|
||||
$result_time_paids = $this->calcTimeFile($musicData->times_paid);
|
||||
|
||||
foreach ($musicData->musics_paid as $music) {
|
||||
$name = $music->getClientOriginalName();
|
||||
$time = @$result_time_paids[$name];
|
||||
$musicFeed->addMedia($music)
|
||||
->withCustomProperties(['time' => $time])
|
||||
->toMediaCollection('paid');
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $musicFeed;
|
||||
}
|
||||
|
||||
protected function calcTimeFile($time_musics)
|
||||
{
|
||||
$times = array_map(function($line){
|
||||
$line = explode(',', $line);
|
||||
return [$line[0] => $line[1]];
|
||||
}, $time_musics);
|
||||
return array_merge(...$times);
|
||||
}
|
||||
}
|
||||
95
app/Domain/Musics/Action/UpdateMusicAction.php
Executable file
95
app/Domain/Musics/Action/UpdateMusicAction.php
Executable file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
namespace App\Domain\Musics\Action;
|
||||
|
||||
use DB;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Domain\Musics\DataTransferObjects\MusicData;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class UpdateMusicAction implements ToFeedAction
|
||||
{
|
||||
|
||||
public $musicFeed;
|
||||
|
||||
public function __construct(Feed $musicFeed)
|
||||
{
|
||||
$this->musicFeed = $musicFeed;
|
||||
}
|
||||
|
||||
public function __invoke(MusicData $musicData)
|
||||
{
|
||||
|
||||
$status = $this->musicFeed->status;
|
||||
if($status === StatusEnum::BANNED()){
|
||||
$status = StatusEnum::EDITABLE();
|
||||
}
|
||||
if($status === StatusEnum::APPROVED()){
|
||||
$status = StatusEnum::EDITABLE();
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
$this->musicFeed->fill([
|
||||
'title' => $musicData->title,
|
||||
'body' => $musicData->body,
|
||||
'price' => $musicData->price,
|
||||
'is_paid' => $musicData->is_paid,
|
||||
'is_ads' => false,
|
||||
'status' => $status,
|
||||
])->save();
|
||||
|
||||
if($musicData->is_loaded_preview){
|
||||
if($existPreview = $this->musicFeed->getMedia('preview')->first()){
|
||||
$existPreview->delete();
|
||||
}
|
||||
$this->musicFeed->addMedia($musicData->preview)->toMediaCollection('preview');
|
||||
}
|
||||
|
||||
if($musicData->is_loaded_music){
|
||||
$result_time_common = $this->calcTimeFile($musicData->times);
|
||||
|
||||
foreach ($musicData->musics as $music) {
|
||||
$name = $music->getClientOriginalName();
|
||||
$time = @$result_time_common[$name];
|
||||
$this->musicFeed->addMedia($music)
|
||||
->withCustomProperties(['time' => $time])
|
||||
->toMediaCollection('common');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($musicData->is_loaded_paid_music){
|
||||
$result_time_paids = $this->calcTimeFile($musicData->times_paid);
|
||||
|
||||
foreach ($musicData->musics_paid as $music) {
|
||||
$name = $music->getClientOriginalName();
|
||||
$time = @$result_time_paids[$name];
|
||||
$this->musicFeed->addMedia($music)
|
||||
->withCustomProperties(['time' => $time])
|
||||
->toMediaCollection('paid');
|
||||
}
|
||||
}
|
||||
|
||||
if(count($musicData->removedItems)){
|
||||
foreach ($musicData->removedItems as $removedItem) {
|
||||
if($media = Media::find($removedItem)){
|
||||
$media->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $this->musicFeed->refresh();
|
||||
}
|
||||
|
||||
protected function calcTimeFile($time_musics)
|
||||
{
|
||||
$times = array_map(function($line){
|
||||
$line = explode(',', $line);
|
||||
return [$line[0] => $line[1]];
|
||||
}, $time_musics);
|
||||
return array_merge(...$times);
|
||||
}
|
||||
}
|
||||
51
app/Domain/Musics/DataTransferObjects/MusicData.php
Executable file
51
app/Domain/Musics/DataTransferObjects/MusicData.php
Executable file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
namespace App\Domain\Musics\DataTransferObjects;
|
||||
|
||||
use App\Http\Requests\MusicFormRequest;
|
||||
use Spatie\DataTransferObject\DataTransferObject;
|
||||
|
||||
class MusicData extends DataTransferObject
|
||||
{
|
||||
public $title;
|
||||
public $body;
|
||||
public $user;
|
||||
public $musics;
|
||||
public $musics_paid;
|
||||
public $preview;
|
||||
public $is_loaded_music;
|
||||
public $is_loaded_paid_music;
|
||||
public $is_loaded_preview;
|
||||
public $price;
|
||||
public $times;
|
||||
public $times_paid;
|
||||
public $is_paid;
|
||||
public $tags;
|
||||
public $removedItems;
|
||||
|
||||
public static function fromRequest(MusicFormRequest $request)
|
||||
{
|
||||
return new self([
|
||||
'title' => $request->input('title'),
|
||||
'body' => $request->input('body'),
|
||||
'price' => $request->input('price'),
|
||||
'is_paid' => $request->input('is_paid'),
|
||||
'user' => auth()->user(),
|
||||
'tags' => $request->input('tags') ?? [],
|
||||
|
||||
|
||||
'preview' => $request->file('preview'),
|
||||
'is_loaded_preview' => $request->hasFile('preview'),
|
||||
|
||||
'musics' => $request->file('musics'),
|
||||
'is_loaded_music' => $request->hasFile('musics'),
|
||||
|
||||
'musics_paid' => $request->file('musics_paid'),
|
||||
'is_loaded_paid_music' => $request->hasFile('musics_paid'),
|
||||
|
||||
'times' => $request->input('times'),
|
||||
'times_paid' => $request->input('times_paid'),
|
||||
|
||||
'removedItems' => $request->input('removedItems') ?? [],
|
||||
]);
|
||||
}
|
||||
}
|
||||
32
app/Domain/Musics/Models/Music.php
Executable file
32
app/Domain/Musics/Models/Music.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Musics\Models;
|
||||
|
||||
use App\Domain\Complaints\Models\Complaint;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
class Music extends Model implements HasMedia
|
||||
{
|
||||
use InteractsWithMedia;
|
||||
|
||||
protected $table = 'musics';
|
||||
|
||||
public function complaints()
|
||||
{
|
||||
return $this->morphMany(Complaint::class, 'complaintable');
|
||||
}
|
||||
|
||||
public function feed()
|
||||
{
|
||||
return $this->morphOne(Feed::class, 'feedable');
|
||||
}
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
70
app/Domain/PaymentGateway/Models/PaymentGatewayOrder.php
Executable file
70
app/Domain/PaymentGateway/Models/PaymentGatewayOrder.php
Executable file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
namespace App\Domain\PaymentGateway\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PaymentGatewayOrder extends Model
|
||||
{
|
||||
const TYPE_INTERKASSA_NAME = "interkassa";
|
||||
const TYPE_UNITPAY_NAME = "unitpay";
|
||||
const TYPE_QIWI_NAME = "qiwi";
|
||||
const TYPE_YOO_NAME = "yookassa";
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public static function interkassa($amount)
|
||||
{
|
||||
$paymentGatewayOrder = new PaymentGatewayOrder;
|
||||
$paymentGatewayOrder->user_id = auth()->user()->id;
|
||||
$paymentGatewayOrder->amount = $amount;
|
||||
$paymentGatewayOrder->status = 0; // 0 - created/ 1- success/ 2-error/ 3-pending
|
||||
$paymentGatewayOrder->type = self::TYPE_INTERKASSA_NAME;
|
||||
$paymentGatewayOrder->save();
|
||||
|
||||
return $paymentGatewayOrder;
|
||||
}
|
||||
|
||||
public static function unitpay($amount)
|
||||
{
|
||||
$paymentGatewayOrder = new PaymentGatewayOrder;
|
||||
$paymentGatewayOrder->user_id = auth()->user()->id;
|
||||
$paymentGatewayOrder->amount = $amount;
|
||||
$paymentGatewayOrder->status = 0; // 0 - created/ 1- success/ 2-error/ 3-pending
|
||||
$paymentGatewayOrder->type = self::TYPE_UNITPAY_NAME;
|
||||
$paymentGatewayOrder->save();
|
||||
|
||||
return $paymentGatewayOrder;
|
||||
}
|
||||
|
||||
public static function qiwi($amount)
|
||||
{
|
||||
$paymentGatewayOrder = new PaymentGatewayOrder;
|
||||
$paymentGatewayOrder->user_id = auth()->user()->id;
|
||||
$paymentGatewayOrder->amount = $amount;
|
||||
$paymentGatewayOrder->number = (string) Str::uuid();
|
||||
$paymentGatewayOrder->status = 0; // 0 - created/ 1- success/ 2-error/ 3-pending
|
||||
$paymentGatewayOrder->type = self::TYPE_QIWI_NAME;
|
||||
$paymentGatewayOrder->save();
|
||||
|
||||
return $paymentGatewayOrder;
|
||||
}
|
||||
|
||||
public static function yookassa($amount)
|
||||
{
|
||||
$paymentGatewayOrder = new PaymentGatewayOrder;
|
||||
$paymentGatewayOrder->user_id = auth()->user()->id;
|
||||
$paymentGatewayOrder->amount = $amount;
|
||||
$paymentGatewayOrder->number = (string) Str::uuid();
|
||||
$paymentGatewayOrder->status = 0; // 0 - created/ 1- success/ 2-error/ 3-pending
|
||||
$paymentGatewayOrder->type = self::TYPE_YOO_NAME;
|
||||
$paymentGatewayOrder->save();
|
||||
|
||||
return $paymentGatewayOrder;
|
||||
}
|
||||
|
||||
}
|
||||
25
app/Domain/PaymentGateway/Services/InterkassaService.php
Executable file
25
app/Domain/PaymentGateway/Services/InterkassaService.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\PaymentGateway\Services;
|
||||
|
||||
class InterkassaService
|
||||
{
|
||||
public static function payments_link($amount, $order_id)
|
||||
{
|
||||
$configuration = new \Interkassa\Helper\Config();
|
||||
$configuration->setCheckoutSecretKey(env('INTERKASSA_SECRET_KEY'));
|
||||
$configuration->setAuthorizationKey(env('INTERKASSA_AUTH_KEY'));
|
||||
$configuration->setAccountId(env('INTERKASSA_ACCOUNT_ID'));
|
||||
$SDKClient = new \Interkassa\Interkassa($configuration);
|
||||
|
||||
$invoiceRequest = new \Interkassa\Request\GetInvoiceRequest();
|
||||
$invoiceRequest
|
||||
->setCheckoutId(env('INTERKASSA_ID'))
|
||||
->setPaymentNumber($order_id)
|
||||
->setAmount($amount)
|
||||
->setCurrency('RUB')
|
||||
->setDescription('Пополнение баланса');
|
||||
|
||||
return $SDKClient->makeInvoiceSciLink($invoiceRequest);
|
||||
}
|
||||
}
|
||||
27
app/Domain/PaymentGateway/Services/QiwiService.php
Executable file
27
app/Domain/PaymentGateway/Services/QiwiService.php
Executable file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\PaymentGateway\Services;
|
||||
|
||||
class QiwiService
|
||||
{
|
||||
public static function payments_link($amount, $order, $user)
|
||||
{
|
||||
$publicKey = env('QIWI_PUBLIC');
|
||||
$SECRET_KEY = env('QIWI_SECRET');
|
||||
|
||||
$billPayments = new \Qiwi\Api\BillPayments($SECRET_KEY);
|
||||
$success_url = env('APP_URL') . '/qiwi-to-payments/status/' . $order->number;
|
||||
|
||||
$params = [
|
||||
'publicKey' => $publicKey,
|
||||
'amount' => $amount,
|
||||
'billId' => $order->number,
|
||||
'successUrl' => $success_url,
|
||||
'email' => $user->email,
|
||||
'comment' => 'Пополнение баланса',
|
||||
];
|
||||
|
||||
return $billPayments->createPaymentForm($params);
|
||||
|
||||
}
|
||||
}
|
||||
66
app/Domain/PaymentGateway/Services/UnitpayService.php
Executable file
66
app/Domain/PaymentGateway/Services/UnitpayService.php
Executable file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\PaymentGateway\Services;
|
||||
|
||||
use UnitPay;
|
||||
use CashItem;
|
||||
|
||||
class UnitpayService
|
||||
{
|
||||
public static function payments_link($amount, $order_id)
|
||||
{
|
||||
|
||||
// Project Data
|
||||
$domain = 'unitpay.ru';// Your working domain: unitpay.ru or address provided by unitpay support service
|
||||
$secretKey = '72449d551500fb99bb66499203ed1ccb';// Project secret key
|
||||
$publicId = 'demo';
|
||||
// $publicId = '438925-9eafe';
|
||||
|
||||
// My item Info
|
||||
$itemName = 'Пополнение баланса';
|
||||
|
||||
// My Order Data
|
||||
$orderId = $order_id;
|
||||
$orderSum = $amount;
|
||||
$orderDesc = 'Payment for item "' . $itemName . '"';
|
||||
$orderCurrency = 'RUB';
|
||||
|
||||
$unitpay = new UnitPay($domain, $secretKey);
|
||||
|
||||
// ->setCustomerEmail('customer@domain.com')
|
||||
// ->setCustomerPhone('79001235555')
|
||||
|
||||
|
||||
$unitpay
|
||||
->setBackUrl('https://teeaseer.com')
|
||||
->setCashItems([
|
||||
new CashItem($itemName, 1, $orderSum)
|
||||
]);
|
||||
|
||||
$redirectUrl = $unitpay->form(
|
||||
$publicId,
|
||||
$orderSum,
|
||||
$orderId,
|
||||
$orderDesc,
|
||||
$orderCurrency
|
||||
);
|
||||
return $redirectUrl;
|
||||
|
||||
|
||||
// $configuration = new \Interkassa\Helper\Config();
|
||||
// $configuration->setCheckoutSecretKey(env('INTERKASSA_SECRET_KEY'));
|
||||
// $configuration->setAuthorizationKey(env('INTERKASSA_AUTH_KEY'));
|
||||
// $configuration->setAccountId(env('INTERKASSA_ACCOUNT_ID'));
|
||||
// $SDKClient = new \Interkassa\Interkassa($configuration);
|
||||
|
||||
// $invoiceRequest = new \Interkassa\Request\GetInvoiceRequest();
|
||||
// $invoiceRequest
|
||||
// ->setCheckoutId(env('INTERKASSA_ID'))
|
||||
// ->setPaymentNumber($order_id)
|
||||
// ->setAmount($amount)
|
||||
// ->setCurrency('RUB')
|
||||
// ->setDescription('Пополнение баланса');
|
||||
|
||||
// return $SDKClient->makeInvoiceSciLink($invoiceRequest);
|
||||
}
|
||||
}
|
||||
65
app/Domain/PaymentGateway/Services/YookassaService.php
Executable file
65
app/Domain/PaymentGateway/Services/YookassaService.php
Executable file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\PaymentGateway\Services;
|
||||
|
||||
use YooKassa\Client;
|
||||
|
||||
class YookassaService
|
||||
{
|
||||
public static function payments_link($amount, $order, $user)
|
||||
{
|
||||
|
||||
$YOOKASSA_SHOP_ID = env('YOOKASSA_SHOP_ID');
|
||||
$YOOKASSA_KEY = env('YOOKASSA_KEY');
|
||||
|
||||
$idempotenceKey = $order->number;
|
||||
$client = new Client();
|
||||
$client->setAuth($YOOKASSA_SHOP_ID, $YOOKASSA_KEY);
|
||||
$success_url = env('APP_URL') . '/payments/status/' . $order->number;
|
||||
$response = $client->createPayment(
|
||||
[
|
||||
'amount' => [
|
||||
'value' => $amount,
|
||||
'currency' => 'RUB',
|
||||
],
|
||||
'capture' => true,
|
||||
'payment_method_data' => [
|
||||
'type' => 'sbp',
|
||||
],
|
||||
'confirmation' => [
|
||||
'type' => 'redirect',
|
||||
'return_url' => $success_url,
|
||||
],
|
||||
'receipt' => [
|
||||
'customer' => [
|
||||
'full_name' => $user->name ?? $user->username,
|
||||
'phone' => $user->phone,
|
||||
"email" => $user->email
|
||||
],
|
||||
'items' => [
|
||||
[
|
||||
'description' => 'оплата бонусов тизер',
|
||||
'quantity' => 1.00,
|
||||
'amount' => [
|
||||
'value' => $amount,
|
||||
'currency' => 'RUB',
|
||||
],
|
||||
'vat_code' => 1,
|
||||
'payment_mode' => 'full_payment'
|
||||
]
|
||||
]
|
||||
],
|
||||
'description' => 'Заказ №' . $order->id,
|
||||
],
|
||||
$idempotenceKey
|
||||
);
|
||||
$order->system_payment_id = $response->getId();
|
||||
$order->save();
|
||||
|
||||
|
||||
$confirmationUrl = $response->getConfirmation()->getConfirmationUrl();
|
||||
return $confirmationUrl;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
19
app/Domain/Payments/Models/BankRequisites.php
Executable file
19
app/Domain/Payments/Models/BankRequisites.php
Executable file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace App\Domain\Payments\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class BankRequisites extends Model
|
||||
{
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function requisites()
|
||||
{
|
||||
return $this->morphOne(Requisites::class, 'requisiteable');
|
||||
}
|
||||
|
||||
}
|
||||
19
app/Domain/Payments/Models/Requisites.php
Executable file
19
app/Domain/Payments/Models/Requisites.php
Executable file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Payments\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Requisites extends Model
|
||||
{
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function requisiteable()
|
||||
{
|
||||
return $this->morphTo();
|
||||
}
|
||||
}
|
||||
63
app/Domain/Payments/Models/Withdrawal.php
Executable file
63
app/Domain/Payments/Models/Withdrawal.php
Executable file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Payments\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Model;
|
||||
use App\Domain\Points\Models\Point;
|
||||
|
||||
class Withdrawal extends Model
|
||||
{
|
||||
|
||||
public function getUserPhoneAttribute()
|
||||
{
|
||||
return $this->user->phone;
|
||||
}
|
||||
|
||||
public function getUserTypeAttribute()
|
||||
{
|
||||
return $this->user->type;
|
||||
}
|
||||
|
||||
public function getRequisitesAttribute()
|
||||
{
|
||||
return 'ИНН: ' . $this->user->inn . ' ' .
|
||||
'БИК: ' . $this->user->bik . ' ' .
|
||||
'Счет: ' . $this->user->checking_account;
|
||||
}
|
||||
|
||||
public static function getTotalAmountForUserInCurrentMonth($userId)
|
||||
{
|
||||
return self::where('user_id', $userId)
|
||||
->where('status', '<>', 'cancel')
|
||||
->where('created_at', '>=', now()->startOfMonth())
|
||||
->where('created_at', '<', now()->startOfMonth()->addMonth())
|
||||
->sum('amount');
|
||||
}
|
||||
|
||||
public static function canRequestWithdrawalPhysical($userId, $requestedAmount)
|
||||
{
|
||||
$totalAmount = self::getTotalAmountForUserInCurrentMonth($userId);
|
||||
|
||||
return ($totalAmount + $requestedAmount) <= 12000;
|
||||
}
|
||||
|
||||
public static function canRequestWithdrawalLegal($userId, $requestedAmount)
|
||||
{
|
||||
$totalAmount = self::getTotalAmountForUserInCurrentMonth($userId);
|
||||
return ($totalAmount + $requestedAmount) <= 150000;
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
public function requisites()
|
||||
{
|
||||
return $this->belongsTo(Requisites::class);
|
||||
}
|
||||
public function point()
|
||||
{
|
||||
return $this->belongsTo(Point::class);
|
||||
}
|
||||
}
|
||||
24
app/Domain/Payments/Observers/WithdrawalObserver.php
Executable file
24
app/Domain/Payments/Observers/WithdrawalObserver.php
Executable file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Payments\Observers;
|
||||
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Payments\Models\Withdrawal;
|
||||
|
||||
class WithdrawalObserver
|
||||
{
|
||||
public function updated(Withdrawal $withdrawal)
|
||||
{
|
||||
$status = $withdrawal->status;
|
||||
$point_id = $withdrawal->point_id;
|
||||
|
||||
if($status === 'cancel'){
|
||||
Point::destroy($point_id);
|
||||
}
|
||||
if($status === 'success'){
|
||||
$point = Point::find($point_id);
|
||||
$point->type = "Вывод средств";
|
||||
$point->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
app/Domain/Points/Enums/DirectionEnum.php
Executable file
21
app/Domain/Points/Enums/DirectionEnum.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace App\Domain\Points\Enums;
|
||||
|
||||
use Spatie\Enum\Laravel\Enum;
|
||||
|
||||
/**
|
||||
* @method static self COMING()
|
||||
* @method static self EXPENSE()
|
||||
* @method static self PENDING()
|
||||
*/
|
||||
final class DirectionEnum extends Enum
|
||||
{
|
||||
protected static function values(): array
|
||||
{
|
||||
return [
|
||||
'COMING' => 0, // приход
|
||||
'EXPENSE' => 1, //расход
|
||||
'PENDING' => 2, //ожидание
|
||||
];
|
||||
}
|
||||
}
|
||||
14
app/Domain/Points/Models/Point.php
Executable file
14
app/Domain/Points/Models/Point.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Points\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Point extends Model
|
||||
{
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
10
app/Domain/Subscriptions/Models/Package.php
Executable file
10
app/Domain/Subscriptions/Models/Package.php
Executable file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Subscriptions\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class Package extends Model
|
||||
{
|
||||
public $timestamps = false;
|
||||
}
|
||||
23
app/Domain/Subscriptions/Models/Subscription.php
Executable file
23
app/Domain/Subscriptions/Models/Subscription.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Subscriptions\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Subscription extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
'ends_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function package()
|
||||
{
|
||||
return $this->belongsTo(Package::class);
|
||||
}
|
||||
}
|
||||
106
app/Domain/Subscriptions/Service/SubscriptionService.php
Executable file
106
app/Domain/Subscriptions/Service/SubscriptionService.php
Executable file
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
namespace App\Domain\Subscriptions\Service;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Subscriptions\Models\Subscription;
|
||||
|
||||
class SubscriptionService
|
||||
{
|
||||
public static function amount()
|
||||
{
|
||||
$subscriptions = Subscription::where('ends_at', '>', Carbon::now())
|
||||
->where('status', 'complete')->get();
|
||||
return $subscriptions->sum('price');
|
||||
}
|
||||
|
||||
|
||||
public static function hasSubscription()
|
||||
{
|
||||
return auth()->user()->subscription()->count();
|
||||
}
|
||||
|
||||
public static function activeSubscription()
|
||||
{
|
||||
$last = auth()->user()->subscription()->first();
|
||||
if (empty($last)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($last->ends_at > Carbon::now()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function freeLeaders()
|
||||
{
|
||||
$leader_count = nova_get_setting('vote_leader_count');
|
||||
|
||||
$users = \DB::table('users_subscribers')->get();
|
||||
|
||||
$users = $users->groupBy('subscriber_id');
|
||||
|
||||
$leaders = collect();
|
||||
|
||||
$users = $users->map(function ($item) {
|
||||
return $item->sum('leader');
|
||||
})->sortDesc()->take($leader_count);
|
||||
|
||||
foreach ($users as $user_id => $leader) {
|
||||
$lUser = User::find($user_id);
|
||||
$lUser->name = $lUser->name;
|
||||
$lUser->countVote = $leader;
|
||||
$leaders[] = $lUser;
|
||||
}
|
||||
|
||||
return $leaders;
|
||||
}
|
||||
|
||||
public static function leaders()
|
||||
{
|
||||
$leaders = \DB::select("SELECT vote.subscriber_id as user_id, SUM(vote.leader) as vote_count FROM
|
||||
(
|
||||
SELECT friends.subscriber_id, friends.leader
|
||||
FROM users_subscribers friends,
|
||||
(
|
||||
SELECT user_id,ends_at FROM subscriptions
|
||||
WHERE ends_at > CURRENT_TIMESTAMP
|
||||
)user_active,
|
||||
(
|
||||
SELECT user_id,ends_at FROM subscriptions
|
||||
WHERE ends_at > CURRENT_TIMESTAMP
|
||||
)user_active2
|
||||
|
||||
where
|
||||
friends.user_id = user_active.user_id
|
||||
and friends.subscriber_id = user_active2.user_id
|
||||
) vote
|
||||
GROUP BY vote.subscriber_id ORDER BY vote_count DESC");
|
||||
|
||||
|
||||
return $leaders;
|
||||
}
|
||||
|
||||
public static function calculate($user_id)
|
||||
{
|
||||
$balance = \DB::select("SELECT T_IN.user_id, T_IN.in-T_OUT.out as balance FROM
|
||||
(SELECT user_id, sum(point) as out FROM points WHERE user_id = {$user_id} AND direction = 1 GROUP BY user_id) T_OUT,
|
||||
(SELECT user_id, sum(point) as in FROM points WHERE user_id = {$user_id} AND direction = 0 GROUP BY user_id) T_IN
|
||||
where T_IN.user_id = T_OUT.user_id");
|
||||
$balance = @$balance[0]->balance;
|
||||
|
||||
if (empty($balance)) {
|
||||
$points = Point::where('user_id', $user_id)->get();
|
||||
$in = $points->where('direction', 0)->sum('point');
|
||||
$out = $points->where('direction', 1)->sum('point');
|
||||
$sum = $in-$out;
|
||||
if ($sum <= 0) {
|
||||
return 0;
|
||||
}
|
||||
return $sum;
|
||||
}
|
||||
return $balance;
|
||||
}
|
||||
}
|
||||
39
app/Domain/Tags/Action/CreateTagAction.php
Executable file
39
app/Domain/Tags/Action/CreateTagAction.php
Executable file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Tags\Action;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use App\Domain\Tags\Models\Tag;
|
||||
|
||||
class CreateTagAction
|
||||
{
|
||||
public function __invoke(Array $tags)
|
||||
{
|
||||
$tagIds = [];
|
||||
$tags = array_map(function($tag){
|
||||
$tag = trim(strip_tags($tag));
|
||||
//$tag = mb_strtolower($tag);
|
||||
//$tag = mb_ucfirst($tag);
|
||||
return $tag;
|
||||
}, $tags);
|
||||
$tags = array_unique($tags);
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
$slug = Str::slug($tag, '-');
|
||||
|
||||
$tagDB = Tag::firstOrCreate(
|
||||
['slug' => $slug],
|
||||
['name' => $tag]
|
||||
);
|
||||
|
||||
$tagIds[] = $tagDB->id;
|
||||
}
|
||||
|
||||
return $tagIds;
|
||||
}
|
||||
|
||||
protected function create()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
16
app/Domain/Tags/Models/Tag.php
Executable file
16
app/Domain/Tags/Models/Tag.php
Executable file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Tags\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
|
||||
public function feeds()
|
||||
{
|
||||
return $this->belongsToMany(Feed::class, 'feed_tags');
|
||||
}
|
||||
|
||||
}
|
||||
34
app/Domain/Users/DataTransferObjects/UserData.php
Executable file
34
app/Domain/Users/DataTransferObjects/UserData.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
namespace App\Domain\Users\DataTransferObjects;
|
||||
|
||||
use App\Models\User;
|
||||
use Spatie\DataTransferObject\DataTransferObject;
|
||||
|
||||
class UserData extends DataTransferObject
|
||||
{
|
||||
public $id;
|
||||
public $name;
|
||||
public $user_char;
|
||||
public $color;
|
||||
public $photo_path;
|
||||
public $banner_path;
|
||||
public $username;
|
||||
public $private;
|
||||
public $is_auth_user;
|
||||
|
||||
public static function fromModel(User $user)
|
||||
{
|
||||
$idCheck = auth()->user() ? $user->id === auth()->user()->id : false;
|
||||
return new self([
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'user_char' => $user->user_char,
|
||||
'color' => $user->color,
|
||||
'photo_path' => $user->photo_path,
|
||||
'banner_path' => $user->banner_path,
|
||||
'username' => $user->username,
|
||||
'private' => $user->private,
|
||||
'is_auth_user' => $idCheck,
|
||||
]);
|
||||
}
|
||||
}
|
||||
11
app/Domain/Users/Models/UserPackage.php
Executable file
11
app/Domain/Users/Models/UserPackage.php
Executable file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Users\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use App\Models\Model;
|
||||
|
||||
class UserPackage extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
}
|
||||
54
app/Domain/Users/Observers/UserObserver.php
Executable file
54
app/Domain/Users/Observers/UserObserver.php
Executable file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Users\Observers;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Arr;
|
||||
// use App\Domain\Points\Models\Point;
|
||||
// use App\Domain\Points\Enums\DirectionEnum;
|
||||
|
||||
class UserObserver
|
||||
{
|
||||
public function creating(User $user)
|
||||
{
|
||||
$user->color = $this->generateColors();
|
||||
if(!$user->username){
|
||||
$user->username = 'id_' . uniqid();
|
||||
}
|
||||
}
|
||||
|
||||
public function created(User $user)
|
||||
{
|
||||
// if($user->username != 'inner_systemuser_api'){
|
||||
// $point = new Point;
|
||||
// $point->user_id = $user->id;
|
||||
// $point->point = 100;
|
||||
// $point->type = 'Тестовое пополнение'; //YSV ENUM!
|
||||
// $point->direction = DirectionEnum::COMING();
|
||||
// $point->save();
|
||||
// }
|
||||
}
|
||||
|
||||
public function saving(User $user)
|
||||
{
|
||||
$user->user_char = $this->getChar($user);
|
||||
}
|
||||
|
||||
private function generateColors()
|
||||
{
|
||||
$colors = ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4caf50', '#8bc34a', '#ffc107', '#ff9800', '#ff5722', '#795548', '#9e9e9e', '#607d8b', '#f44331', '#e91e61', '#9c27b1', '#673ab1', '#3f51b1', '#2196f1', '#03a9f1', '#00bcd1', '#009681', '#4caf51', '#8bc341', '#ffc101', '#ff9801', '#ff5721', '#795541', '#9e9e91', '#607d81'];
|
||||
return Arr::random($colors);
|
||||
}
|
||||
|
||||
private function getChar($user)
|
||||
{
|
||||
$fname = mb_strtoupper($user->first_name);
|
||||
$lname = @$user->last_name;
|
||||
if($lname){
|
||||
$lname = mb_strtoupper($lname);
|
||||
return mb_substr($fname, 0, 1) . mb_substr($lname, 0, 1);
|
||||
}
|
||||
return mb_substr($fname, 0, 1) . mb_substr($fname, 1, 1);
|
||||
}
|
||||
|
||||
}
|
||||
56
app/Domain/Users/Service/ProfileDataService.php
Executable file
56
app/Domain/Users/Service/ProfileDataService.php
Executable file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Users\Service;
|
||||
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class ProfileDataService
|
||||
{
|
||||
public static function get($user)
|
||||
{
|
||||
|
||||
$gues = auth()->user();
|
||||
if($gues){
|
||||
$gues = auth()->user()->id;
|
||||
}else{
|
||||
$gues = null;
|
||||
}
|
||||
|
||||
$user->loadCount(['subscriber_reverse as is_sub' => function (Builder $query) use($gues) {
|
||||
$query->where('user_id', $gues);
|
||||
},'subscribers as is_reader' => function (Builder $query) use($gues) {
|
||||
$query->where('subscriber_id', $gues);
|
||||
}])->withCasts(['is_sub' => 'boolean', 'is_reader' => 'boolean']);
|
||||
|
||||
$is_leader = false;
|
||||
|
||||
if($user->is_sub && auth()->user()){
|
||||
$leader = auth()->user()->subscribers()->where('subscriber_id', $user->id)->first();
|
||||
if($leader){
|
||||
$is_leader = (boolean)$leader->pivot->leader;
|
||||
}
|
||||
}
|
||||
|
||||
$count_feeds = $user->feeds()->count();
|
||||
$count_readable = $user->subscribers()->count();
|
||||
$count_subscribers = $user->subscriber_reverse()->count();
|
||||
|
||||
$is_auth_user = $user->id === $gues;
|
||||
if($is_auth_user){
|
||||
$close_account = false;
|
||||
}else{
|
||||
$close_account = $user->private == true && ($user->is_sub == 0 || $user->is_reader == 0);
|
||||
}
|
||||
|
||||
$object = new \stdClass();
|
||||
$object->user = $user;
|
||||
$object->count_feeds = $count_feeds;
|
||||
$object->count_readable = $count_readable;
|
||||
$object->count_subscribers = $count_subscribers;
|
||||
$object->close_account = $close_account;
|
||||
$object->is_leader = $is_leader;
|
||||
|
||||
return $object;
|
||||
}
|
||||
}
|
||||
52
app/Domain/Videos/Action/CreateVideoAction.php
Executable file
52
app/Domain/Videos/Action/CreateVideoAction.php
Executable file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
namespace App\Domain\Videos\Action;
|
||||
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use DB;
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Videos\DataTransferObjects\VideoData;
|
||||
|
||||
class CreateVideoAction implements ToFeedAction
|
||||
{
|
||||
public function __invoke(VideoData $videoData)
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
//$youtube_code = $videoData->youtube ? $this->getCodeYoutube($videoData->youtube) : '';
|
||||
|
||||
$videoFeed = Feed::create([
|
||||
'title' => $videoData->title,
|
||||
'body' => $videoData->body,
|
||||
'price' => $videoData->price,
|
||||
'is_paid' => $videoData->is_paid,
|
||||
'user_id' => $videoData->user->id,
|
||||
'type' => 'videos',
|
||||
'is_ads' => false,
|
||||
//'iframe_code' => $youtube_code,
|
||||
]);
|
||||
|
||||
foreach ($videoData->videos as $video) {
|
||||
$videoFeed->addMedia($video)->toMediaCollection('common');
|
||||
}
|
||||
if($videoData->is_loaded_preview){
|
||||
$videoFeed->addMedia($videoData->preview)->toMediaCollection('preview');
|
||||
}
|
||||
if($videoData->is_loaded_videos_paid){
|
||||
foreach ($videoData->videos_paid as $video) {
|
||||
$videoFeed->addMedia($video)->toMediaCollection('paid');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $videoFeed;
|
||||
}
|
||||
|
||||
private function getCodeYoutube($video)
|
||||
{
|
||||
$youtuberegexp = '/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/i';
|
||||
preg_match($youtuberegexp, $video, $matches);
|
||||
return @$matches[1];
|
||||
}
|
||||
}
|
||||
74
app/Domain/Videos/Action/UpdateVideoAction.php
Executable file
74
app/Domain/Videos/Action/UpdateVideoAction.php
Executable file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace App\Domain\Videos\Action;
|
||||
|
||||
use DB;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\ToFeedAction;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Domain\Videos\DataTransferObjects\VideoData;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class UpdateVideoAction implements ToFeedAction
|
||||
{
|
||||
|
||||
public $videoFeed;
|
||||
|
||||
public function __construct(Feed $videoFeed)
|
||||
{
|
||||
$this->videoFeed = $videoFeed;
|
||||
}
|
||||
|
||||
public function __invoke(VideoData $videoData)
|
||||
{
|
||||
|
||||
$status = $this->videoFeed->status;
|
||||
if($status === StatusEnum::BANNED()){
|
||||
$status = StatusEnum::EDITABLE();
|
||||
}
|
||||
if($status === StatusEnum::APPROVED()){
|
||||
$status = StatusEnum::EDITABLE();
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
$this->videoFeed->fill([
|
||||
'title' => $videoData->title,
|
||||
'body' => $videoData->body,
|
||||
'price' => $videoData->price,
|
||||
'is_paid' => $videoData->is_paid,
|
||||
'status' => $status,
|
||||
'is_ads' => false,
|
||||
])->save();
|
||||
|
||||
if($videoData->is_loaded_video){
|
||||
foreach ($videoData->videos as $video) {
|
||||
$this->videoFeed->addMedia($video)->toMediaCollection('common');
|
||||
}
|
||||
}
|
||||
|
||||
if($videoData->is_loaded_preview){
|
||||
if($existPreview = $this->videoFeed->getMedia('preview')->first()){
|
||||
$existPreview->delete();
|
||||
}
|
||||
$this->videoFeed->addMedia($videoData->preview)->toMediaCollection('preview');
|
||||
}
|
||||
if($videoData->is_loaded_videos_paid){
|
||||
foreach ($videoData->videos_paid as $video) {
|
||||
$this->videoFeed->addMedia($video)->toMediaCollection('paid');
|
||||
}
|
||||
}
|
||||
|
||||
if(count($videoData->removedItems)){
|
||||
foreach ($videoData->removedItems as $removedItem) {
|
||||
if($media = Media::find($removedItem)){
|
||||
$media->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
return $this->videoFeed->refresh();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
46
app/Domain/Videos/DataTransferObjects/VideoData.php
Executable file
46
app/Domain/Videos/DataTransferObjects/VideoData.php
Executable file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
namespace App\Domain\Videos\DataTransferObjects;
|
||||
|
||||
use App\Http\Requests\VideoFormRequest;
|
||||
use Spatie\DataTransferObject\DataTransferObject;
|
||||
|
||||
class VideoData extends DataTransferObject
|
||||
{
|
||||
public $title;
|
||||
public $body;
|
||||
public $user;
|
||||
public $videos;
|
||||
public $videos_paid;
|
||||
public $preview;
|
||||
public $is_loaded_video;
|
||||
public $is_loaded_preview;
|
||||
public $is_loaded_videos_paid;
|
||||
public $price;
|
||||
public $is_paid;
|
||||
public $tags;
|
||||
public $removedItems;
|
||||
|
||||
public static function fromRequest(VideoFormRequest $request)
|
||||
{
|
||||
return new self([
|
||||
'title' => $request->input('title'),
|
||||
'body' => $request->input('body'),
|
||||
'price' => $request->input('price'),
|
||||
'is_paid' => $request->input('is_paid'),
|
||||
'user' => auth()->user(),
|
||||
'tags' => $request->input('tags') ?? [],
|
||||
|
||||
'preview' => $request->file('preview'),
|
||||
'is_loaded_preview' => $request->hasFile('preview'),
|
||||
|
||||
'videos' => $request->file('videos'),
|
||||
'is_loaded_video' => $request->hasFile('videos'),
|
||||
|
||||
'videos_paid' => $request->file('videos_paid'),
|
||||
'is_loaded_videos_paid' => $request->hasFile('videos_paid'),
|
||||
|
||||
'removedItems' => $request->input('removedItems') ?? [],
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
30
app/Domain/Videos/Models/Video.php
Executable file
30
app/Domain/Videos/Models/Video.php
Executable file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Videos\Models;
|
||||
|
||||
use App\Domain\Complaints\Models\Complaint;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
use Spatie\MediaLibrary\HasMedia;
|
||||
use Spatie\MediaLibrary\InteractsWithMedia;
|
||||
|
||||
class Video extends Model implements HasMedia
|
||||
{
|
||||
use InteractsWithMedia;
|
||||
|
||||
|
||||
public function complaints()
|
||||
{
|
||||
return $this->morphMany(Complaint::class, 'complaintable');
|
||||
}
|
||||
|
||||
public function feed()
|
||||
{
|
||||
return $this->morphOne(Feed::class, 'feedable');
|
||||
}
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
14
app/Domain/Votes/Models/Vote.php
Executable file
14
app/Domain/Votes/Models/Vote.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\Votes\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
use App\Models\User;
|
||||
|
||||
class Vote extends Model
|
||||
{
|
||||
public function users()
|
||||
{
|
||||
return $this->belongsToMany(User::class)->withPivot('payment');
|
||||
}
|
||||
}
|
||||
22
app/Domain/Votes/Observers/VoteObserver.php
Executable file
22
app/Domain/Votes/Observers/VoteObserver.php
Executable file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
namespace App\Domain\Votes\Observers;
|
||||
|
||||
use App\Domain\Votes\Models\Vote;
|
||||
use App\Domain\Votes\Services\VoteService;
|
||||
|
||||
class VoteObserver
|
||||
{
|
||||
|
||||
public function created(Vote $vote)
|
||||
{
|
||||
$mode = nova_get_setting('vote_paid_mode');
|
||||
|
||||
// Платный режим
|
||||
if($mode){
|
||||
(new VoteService($vote))->accrualPoints();
|
||||
}else{
|
||||
(new VoteService($vote))->freeMode();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
180
app/Domain/Votes/Services/VoteService.php
Executable file
180
app/Domain/Votes/Services/VoteService.php
Executable file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
namespace App\Domain\Votes\Services;
|
||||
|
||||
use DB;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Domain\Subscriptions\Models\Subscription;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class VoteService
|
||||
{
|
||||
public $vote;
|
||||
public $leaders;
|
||||
|
||||
public function __construct($vote)
|
||||
{
|
||||
$leader_count = nova_get_setting('vote_leader_count');
|
||||
$leaders = SubscriptionService::leaders();
|
||||
$leaders = array_column(array_slice($leaders, 0, $leader_count), 'user_id');
|
||||
$this->leaders = $leaders;
|
||||
$this->vote = $vote;
|
||||
}
|
||||
|
||||
|
||||
public function accrualPoints()
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
$procent_site = (int)nova_get_setting('vote_procent_site');
|
||||
$procent_site = $procent_site / 100;
|
||||
|
||||
$procent_top = (int)nova_get_setting('vote_procent_leader');
|
||||
$procent_top = $procent_top / 100;
|
||||
|
||||
$procent_local = (int)nova_get_setting('vote_procent_local_leader');
|
||||
$procent_local = $procent_local / 100;
|
||||
|
||||
$subscriptions = Subscription::with('user.subscribers.subscription')->where('ends_at', '>', Carbon::now())
|
||||
->where('status', 'complete')->get();
|
||||
|
||||
$sum_site = 0;
|
||||
$sdr_leader_pay = 0;
|
||||
$sdr_leader_for_all_pay = [];
|
||||
|
||||
foreach ($subscriptions as $subscription) {
|
||||
|
||||
|
||||
$user = $subscription->user;
|
||||
$subscribers = $this->activeSubs($user->subscribers);
|
||||
|
||||
// Фильтр лидеров
|
||||
$subscribersLeader = $subscribers->filter(function ($subscriber) {
|
||||
return $subscriber->pivot->leader === 1;
|
||||
});
|
||||
// Фильтр простых пользователей
|
||||
$subscribersSimple = $subscribers->filter(function ($subscriber) {
|
||||
return $subscriber->pivot->leader === 0;
|
||||
});
|
||||
|
||||
|
||||
|
||||
$price = $subscription->price;
|
||||
$to_site = round($price * $procent_site);
|
||||
$sum_site += $to_site;
|
||||
|
||||
$sdr = round($price - $to_site); // сумма для распределения
|
||||
|
||||
$sdr_leader_global = round($sdr * $procent_top);
|
||||
$sdr_leader_local = round($sdr * $procent_local);
|
||||
|
||||
$sdr_simple = $sdr - $sdr_leader_global - $sdr_leader_local;
|
||||
|
||||
// добавляем лидерам
|
||||
$sdr_leader_pay += $sdr_leader_global;
|
||||
|
||||
//если 0 подписок, но куплена подписка на сайт
|
||||
// отдаем лидеру 40%, а 60% сайту
|
||||
if($subscribers->isEmpty()){
|
||||
$sum_site += ($sdr - $sdr_leader_global); // 20%сайту(вместо локальных) и 40%сайту (вместо простых)
|
||||
}else {
|
||||
if ($subscribersLeader->isNotEmpty()) {
|
||||
//Выплачиваем каждому локальному лидеру
|
||||
$sdr_parts_local = round($sdr_leader_local / $subscribersLeader->count());
|
||||
//сохраняем транзакции локальных лидеров
|
||||
foreach ($subscribersLeader as $subs) {
|
||||
$sdr_leader_for_all_pay[$subs->id][] = $sdr_parts_local;
|
||||
}
|
||||
}else{
|
||||
$sum_site += $sdr_leader_local; //если у пользователя есть подписки, но он не выбрал лидеров
|
||||
}
|
||||
|
||||
if ($subscribersSimple->isNotEmpty()) {
|
||||
//Выплачиваем каждому юзеру
|
||||
$sdr_parts = round($sdr_simple / $subscribersSimple->count());
|
||||
//сохраняем транзакции простых пользователей
|
||||
foreach ($subscribersSimple as $subs) {
|
||||
$sdr_leader_for_all_pay[$subs->id][] = $sdr_parts;
|
||||
}
|
||||
}else{
|
||||
$sum_site += $sdr_simple;
|
||||
}
|
||||
}
|
||||
|
||||
$this->updateSubs($subscription);
|
||||
}
|
||||
|
||||
$part_for_leader = round($sdr_leader_pay/count($this->leaders));
|
||||
foreach ($this->leaders as $leader) {
|
||||
$sdr_leader_for_all_pay[$leader][] = $part_for_leader;
|
||||
}
|
||||
|
||||
|
||||
$this->payUsers($sdr_leader_for_all_pay);
|
||||
$this->payForSystemUser($sum_site);
|
||||
|
||||
DB::commit();
|
||||
}
|
||||
|
||||
private function payUsers($sdr)
|
||||
{
|
||||
$sdr_users_pay = array_map(function ($lines) {
|
||||
return array_sum($lines);
|
||||
}, $sdr);
|
||||
|
||||
|
||||
foreach ($sdr_users_pay as $user_pay_id => $sdr_user) {
|
||||
$this->addPoint($user_pay_id, $sdr_user);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function payForSystemUser($sum_site)
|
||||
{
|
||||
$system_user_id = User::system()->id;
|
||||
$this->addPoint($system_user_id, $sum_site);
|
||||
}
|
||||
|
||||
|
||||
private function addPoint($user_id, $amount)
|
||||
{
|
||||
$point = new Point;
|
||||
$point->user_id = $user_id;
|
||||
$point->point = $amount;
|
||||
$point->type = 'votes'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
$this->vote->users()->attach($user_id, ['payment' => $amount]);
|
||||
}
|
||||
|
||||
private function updateSubs($sub)
|
||||
{
|
||||
$sub->status = 'end'; //YSV ENUM!
|
||||
$sub->save();
|
||||
}
|
||||
|
||||
|
||||
//проверка на акт. подписки
|
||||
private function activeSubs($subscribers)
|
||||
{
|
||||
return $subscribers->filter(function ($subscriber) {
|
||||
return optional($subscriber->subscription->first())->ends_at > Carbon::now();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function freeMode()
|
||||
{
|
||||
|
||||
$users = SubscriptionService::freeLeaders();
|
||||
|
||||
foreach ($users as $leader) {
|
||||
$this->vote->users()->attach($leader->id, ['payment' => $leader->countVote]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
155
app/Domain/Votes/Services/VoteServiceOld.php
Executable file
155
app/Domain/Votes/Services/VoteServiceOld.php
Executable file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
namespace App\Domain\Votes\Services;
|
||||
|
||||
use DB;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Domain\Subscriptions\Models\Subscription;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class VoteServiceOld
|
||||
{
|
||||
public $vote;
|
||||
public $leaders;
|
||||
|
||||
public function __construct($vote)
|
||||
{
|
||||
$leaders = SubscriptionService::leaders();
|
||||
$leaders = array_column(array_slice($leaders, 0, 2), 'user_id');
|
||||
$this->leaders = $leaders;
|
||||
$this->vote = $vote;
|
||||
}
|
||||
|
||||
|
||||
public function accrualPoints()
|
||||
{
|
||||
DB::beginTransaction();
|
||||
|
||||
$procent_site = (int)$this->vote->procent_site;
|
||||
$procent_site = $procent_site / 100;
|
||||
$procent_top = (int)$this->vote->procent_top;
|
||||
$procent_top = $procent_top / 100;
|
||||
|
||||
$subscriptions = Subscription::with('user.subscribers.subscription')->where('ends_at', '>', Carbon::now())
|
||||
->where('status', 'complete')->get();
|
||||
|
||||
$sum_site = 0;
|
||||
$sdr_leader_pay = 0;
|
||||
$sdr_users_pay = [];
|
||||
foreach ($subscriptions as $subscription) {
|
||||
$subscribers_simple = collect([]);
|
||||
$user = $subscription->user;
|
||||
|
||||
$subscribers = $this->activeSubs($user->subscribers);
|
||||
$one_sub_is_leader = $this->oneLeaders($subscribers);
|
||||
|
||||
if (! $one_sub_is_leader) {
|
||||
$subscribers_simple = $subscribers->filter(function ($subscriber) {
|
||||
return ! in_array($subscriber->id, $this->leaders);
|
||||
});
|
||||
}
|
||||
|
||||
$price = $subscription->price;
|
||||
$to_site = $price * $procent_site;
|
||||
$sum_site += $to_site;
|
||||
$sdr = round($price - $to_site);
|
||||
|
||||
$sdr_leader = round($sdr * $procent_top);
|
||||
$sdr_simple = $sdr - $sdr_leader;
|
||||
|
||||
if ($one_sub_is_leader) {
|
||||
//выплачиваем весь sdr если чел. подписан на лидеров, и у него больше нет простых
|
||||
$sdr_leader_pay += $sdr;
|
||||
} else {
|
||||
$sdr_leader_pay += $sdr_leader;
|
||||
}
|
||||
|
||||
if ($subscribers_simple->isNotEmpty()) {
|
||||
//Выплачиваем каждому юзеру
|
||||
$sdr_parts = round($sdr_simple / $subscribers_simple->count());
|
||||
//сохраняем транзакции простых пользователей
|
||||
foreach ($subscribers_simple as $subs) {
|
||||
$sdr_users_pay[$subs->id][] = $sdr_parts;
|
||||
}
|
||||
}
|
||||
|
||||
$this->updateSubs($subscription);
|
||||
}
|
||||
|
||||
$this->payForSimpleUser($sdr_users_pay);
|
||||
$this->payForLeaderUser($sdr_leader_pay);
|
||||
$this->payForSystemUser($sum_site);
|
||||
|
||||
DB::commit();
|
||||
}
|
||||
|
||||
public function payForSystemUser($sum_site)
|
||||
{
|
||||
$system_user_id = User::system()->id;
|
||||
$this->addPoint($system_user_id, $sum_site);
|
||||
}
|
||||
|
||||
//оплата лидеров
|
||||
public function payForLeaderUser($sdr_leader_pay)
|
||||
{
|
||||
$part_for_leader = round($sdr_leader_pay/count($this->leaders));
|
||||
|
||||
foreach ($this->leaders as $leader) {
|
||||
$this->addPoint($leader, $part_for_leader);
|
||||
}
|
||||
}
|
||||
|
||||
//оплата обычных
|
||||
public function payForSimpleUser($sdr_users_pay)
|
||||
{
|
||||
$sdr_users_pay = array_map(function ($lines) {
|
||||
return array_sum($lines);
|
||||
}, $sdr_users_pay);
|
||||
|
||||
foreach ($sdr_users_pay as $user_pay_id => $sdr_users) {
|
||||
$this->addPoint($user_pay_id, $sdr_users);
|
||||
}
|
||||
}
|
||||
|
||||
public function addPoint($user_id, $amount)
|
||||
{
|
||||
$point = new Point;
|
||||
$point->user_id = $user_id;
|
||||
$point->point = $amount;
|
||||
$point->type = 'votes'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
$this->vote->users()->attach($user_id, ['payment' => $amount]);
|
||||
}
|
||||
|
||||
public function updateSubs($sub)
|
||||
{
|
||||
$sub->status = 'end'; //YSV ENUM!
|
||||
$sub->save();
|
||||
}
|
||||
|
||||
// есть в списке только лидеры
|
||||
public function oneLeaders($subscribers)
|
||||
{
|
||||
if ($subscribers->count() <= count($this->leaders)) {
|
||||
$contains = $subscribers->filter(function ($subscriber) {
|
||||
return in_array($subscriber->id, $this->leaders);
|
||||
});
|
||||
if ($contains->count() === $subscribers->count()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//проверка на акт. подписки
|
||||
public function activeSubs($subscribers)
|
||||
{
|
||||
return $subscribers->filter(function ($subscriber) {
|
||||
return optional($subscriber->subscription->first())->ends_at > Carbon::now();
|
||||
});
|
||||
}
|
||||
}
|
||||
40
app/Events/FeedAddProcessed.php
Executable file
40
app/Events/FeedAddProcessed.php
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
|
||||
class FeedAddProcessed
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
|
||||
public $feed;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Feed $feed)
|
||||
{
|
||||
$this->feed = $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('add-feed-for-readers');
|
||||
}
|
||||
}
|
||||
40
app/Events/FeedRemoveProcessed.php
Executable file
40
app/Events/FeedRemoveProcessed.php
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
|
||||
class FeedRemoveProcessed
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
|
||||
public $feed;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Feed $feed)
|
||||
{
|
||||
$this->feed = $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('remove-feed-for-readers');
|
||||
}
|
||||
}
|
||||
40
app/Events/FeedUpdateProcessed.php
Executable file
40
app/Events/FeedUpdateProcessed.php
Executable file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use Illuminate\Broadcasting\Channel;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Broadcasting\PresenceChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
|
||||
|
||||
class FeedUpdateProcessed
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
|
||||
public $feed;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Feed $feed)
|
||||
{
|
||||
$this->feed = $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return \Illuminate\Broadcasting\Channel|array
|
||||
*/
|
||||
public function broadcastOn()
|
||||
{
|
||||
return new PrivateChannel('update-feed-for-readers');
|
||||
}
|
||||
}
|
||||
51
app/Exceptions/Handler.php
Executable file
51
app/Exceptions/Handler.php
Executable file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* A list of the exception types that are not reported.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontReport = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* A list of the inputs that are never flashed for validation exceptions.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
public function render($request, Throwable $e)
|
||||
{
|
||||
$response = parent::render($request, $e);
|
||||
|
||||
if ($response->status() === 419) {
|
||||
return back()->with([
|
||||
'message' => 'The page expired, please try again.',
|
||||
]);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
54
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Executable file
54
app/Http/Controllers/Auth/AuthenticatedSessionController.php
Executable file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Auth\LoginRequest;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Inertia\Inertia;
|
||||
|
||||
class AuthenticatedSessionController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the login view.
|
||||
*
|
||||
* @return \Inertia\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return Inertia::render('Auth/Login');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming authentication request.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function store(LoginRequest $request)
|
||||
{
|
||||
|
||||
$request->authenticate();
|
||||
|
||||
$request->session()->regenerate();
|
||||
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy an authenticated session.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
|
||||
$request->session()->invalidate();
|
||||
|
||||
$request->session()->regenerateToken();
|
||||
|
||||
return redirect('/');
|
||||
}
|
||||
}
|
||||
25
app/Http/Controllers/Auth/EmailVerificationPromptController.php
Executable file
25
app/Http/Controllers/Auth/EmailVerificationPromptController.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
|
||||
class EmailVerificationPromptController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the email verification prompt.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed
|
||||
*/
|
||||
public function __invoke(Request $request)
|
||||
{
|
||||
if($request->user()->hasVerifiedEmail()){
|
||||
return redirect()->intended(RouteServiceProvider::HOME);
|
||||
}
|
||||
return Inertia::render('Auth/VerifyEmail');
|
||||
}
|
||||
}
|
||||
66
app/Http/Controllers/Auth/NewPasswordController.php
Executable file
66
app/Http/Controllers/Auth/NewPasswordController.php
Executable file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rules;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use Illuminate\Auth\Events\PasswordReset;
|
||||
|
||||
class NewPasswordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the password reset view.
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
|
||||
return Inertia::render('Auth/ResetPassword', [
|
||||
'token' => $request->route('token'),
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming new password request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'token' => ['required'],
|
||||
'email' => ['required', 'email'],
|
||||
'password' => ['required', 'confirmed', Rules\Password::defaults()],
|
||||
]);
|
||||
|
||||
|
||||
// Here we will attempt to reset the user's password. If it is successful we
|
||||
// will update the password on an actual user model and persist it to the
|
||||
// database. Otherwise we will parse the error and return the response.
|
||||
$status = Password::reset(
|
||||
$request->only('email', 'password', 'password_confirmation', 'token'),
|
||||
function ($user) use ($request) {
|
||||
$user->forceFill([
|
||||
'password' => Hash::make($request->password),
|
||||
'remember_token' => Str::random(60),
|
||||
])->save();
|
||||
|
||||
event(new PasswordReset($user));
|
||||
}
|
||||
);
|
||||
|
||||
// If the password was successfully reset, we will redirect the user back to
|
||||
// the application's home authenticated view. If there is an error we can
|
||||
// redirect them back to where they came from with their error message.
|
||||
return $status == Password::PASSWORD_RESET
|
||||
? redirect()->route('login')->with('status', __($status))
|
||||
: back()->with('status', __($status));
|
||||
}
|
||||
}
|
||||
43
app/Http/Controllers/Auth/PasswordResetLinkController.php
Executable file
43
app/Http/Controllers/Auth/PasswordResetLinkController.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
class PasswordResetLinkController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the password reset link request view.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return Inertia::render('Auth/ForgotPassword');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming password reset link request.
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
$request->validate([
|
||||
'email' => ['required', 'email'],
|
||||
]);
|
||||
|
||||
// We will send the password reset link to this user. Once we have attempted
|
||||
// to send the link, we will examine the response then see the message we
|
||||
// need to show to the user. Finally, we'll send out a proper response.
|
||||
$status = Password::sendResetLink(
|
||||
$request->only('email')
|
||||
);
|
||||
|
||||
|
||||
return back()->with('status', __($status));
|
||||
}
|
||||
}
|
||||
60
app/Http/Controllers/Auth/RegisteredUserController.php
Executable file
60
app/Http/Controllers/Auth/RegisteredUserController.php
Executable file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Models\User;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rules;
|
||||
use App\Mail\AfterReigsterToAdmin;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
|
||||
class RegisteredUserController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display the registration view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return Inertia::render('Auth/Register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming registration request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*
|
||||
* @throws \Illuminate\Validation\ValidationException
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'first_name' => 'required|string|max:255',
|
||||
'email' => 'required|string|email|max:255|unique:users',
|
||||
'password' => ['required', Rules\Password::defaults()],
|
||||
]);
|
||||
$user = User::create([
|
||||
'first_name' => $request->first_name,
|
||||
'email' => $request->email,
|
||||
'password' => Hash::make($request->password),
|
||||
]);
|
||||
|
||||
event(new Registered($user));
|
||||
|
||||
Auth::login($user);
|
||||
|
||||
Mail::to(env('MAIL_ADMIN_EMAIL'))->send(new AfterReigsterToAdmin($user));
|
||||
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
34
app/Http/Controllers/Auth/VerifyEmailController.php
Executable file
34
app/Http/Controllers/Auth/VerifyEmailController.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Auth\Events\Verified;
|
||||
use Illuminate\Foundation\Auth\EmailVerificationRequest;
|
||||
|
||||
class VerifyEmailController extends Controller
|
||||
{
|
||||
/**
|
||||
* Mark the authenticated user's email address as verified.
|
||||
*
|
||||
* @param \Illuminate\Foundation\Auth\EmailVerificationRequest $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function __invoke(EmailVerificationRequest $request)
|
||||
{
|
||||
if ($request->user()->hasVerifiedEmail()) {
|
||||
return redirect()->intended(
|
||||
config('app.frontend_url').RouteServiceProvider::HOME.'?verified=1'
|
||||
);
|
||||
}
|
||||
|
||||
if ($request->user()->markEmailAsVerified()) {
|
||||
event(new Verified($request->user()));
|
||||
}
|
||||
|
||||
return redirect()->intended(
|
||||
config('app.frontend_url').RouteServiceProvider::HOME.'?verified=1'
|
||||
);
|
||||
}
|
||||
}
|
||||
151
app/Http/Controllers/CommentController.php
Executable file
151
app/Http/Controllers/CommentController.php
Executable file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use Illuminate\Pagination\Cursor;
|
||||
use App\Notifications\CommentAdded;
|
||||
use App\Domain\Comments\Models\Comment;
|
||||
use Illuminate\Http\Request as HttpRequest;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// $this->middleware('subs.paid');
|
||||
}
|
||||
|
||||
public function show($feed_id)
|
||||
{
|
||||
$count_pagination = 50;
|
||||
$cursor_request = request('cursor') ?? null;
|
||||
$feed = Feed::find($feed_id);
|
||||
if(empty($feed)){
|
||||
return [
|
||||
'nextCursor' => null,
|
||||
'items' => []
|
||||
];
|
||||
}
|
||||
$comments = $feed->comments()
|
||||
->where('parent_id', null)
|
||||
->withCount('children')
|
||||
->with('user:id,first_name,last_name,username,photo_path,color,user_char')->cursorPaginate($count_pagination, ['*'], 'cursor', Cursor::fromEncoded($cursor_request));
|
||||
$nextCursor = $comments->nextCursor();
|
||||
if($nextCursor){
|
||||
$nextCursor = $nextCursor->encode();
|
||||
}else{
|
||||
$nextCursor = null;
|
||||
}
|
||||
return [
|
||||
'nextCursor' => $nextCursor,
|
||||
'items' => $comments->transform(function ($item) {
|
||||
$item->childrens = [];
|
||||
$item->closed_children_comments = 1;
|
||||
$item->created_at_humans = $item->created_at->diffForHumans();
|
||||
return $item;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
public function children($comment_id)
|
||||
{
|
||||
$count_pagination = 50;
|
||||
$cursor_request = request('cursor') ?? null;
|
||||
$comments = Comment::findOrFail($comment_id)
|
||||
->children()
|
||||
->with('user:id,first_name,last_name,username,photo_path,color,user_char', 'answer_to:id,username')
|
||||
->cursorPaginate($count_pagination, ['*'], 'cursor', Cursor::fromEncoded($cursor_request));
|
||||
|
||||
$nextCursor = $comments->nextCursor();
|
||||
if($nextCursor){
|
||||
$nextCursor = $nextCursor->encode();
|
||||
}else{
|
||||
$nextCursor = null;
|
||||
}
|
||||
|
||||
return [
|
||||
'nextCursor' => $nextCursor,
|
||||
'items' => $comments->transform(function ($item) {
|
||||
$item->created_at_humans = $item->created_at->diffForHumans();
|
||||
return $item;
|
||||
})
|
||||
];
|
||||
}
|
||||
|
||||
public function store(HttpRequest $request, $feed_id)
|
||||
{
|
||||
$disabled_notify_main = 0;
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
|
||||
$body = $request->input('body');
|
||||
$body = preg_replace('/(?<=\s|^)@\S+/', "", $body);
|
||||
$body = htmlentities(trim($body));
|
||||
|
||||
$to = $request->input('to');
|
||||
$parent = $request->input('parent');
|
||||
|
||||
$comment = new Comment;
|
||||
$comment->body = $body;
|
||||
$comment->user_id = auth()->user()->id;
|
||||
$comment->feed_id = $feed_id;
|
||||
if($parent){
|
||||
$comment->parent_id = $parent;
|
||||
}
|
||||
if($to){
|
||||
$comment->to_user_id = $to;
|
||||
}
|
||||
|
||||
$feed->comments()->save($comment);
|
||||
$comment->setRelation('user', auth()->user());
|
||||
if($to){
|
||||
$toUser = User::find($to);
|
||||
$comment->setRelation('answer_to', $toUser);
|
||||
if($toUser->id !== auth()->user()->id){
|
||||
$disabled_notify_main = 1;
|
||||
$message = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'node_id' => $feed_id,
|
||||
'comment' => $body
|
||||
];
|
||||
$toUser->notify(new CommentAdded($message));
|
||||
}
|
||||
}
|
||||
|
||||
$comment->created_at_humans = $comment->created_at->diffForHumans();
|
||||
|
||||
if(empty($parent)){
|
||||
$comment->childrens = [];
|
||||
$comment->closed_children_comments = 1;
|
||||
}
|
||||
|
||||
if($feed->user_id !== auth()->user()->id && $disabled_notify_main === 0){
|
||||
$message = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'node_id' => $feed_id,
|
||||
'comment' => $body
|
||||
];
|
||||
$feed->user->notify(new CommentAdded($message));
|
||||
}
|
||||
|
||||
return $comment;
|
||||
}
|
||||
|
||||
public function remove($comment_id)
|
||||
{
|
||||
$remove_count = 1;
|
||||
$comment = Comment::findOrFail($comment_id);
|
||||
$children_count = $comment->children()->count();
|
||||
if($children_count){
|
||||
$comment->children()->forceDelete();
|
||||
$remove_count = $remove_count + $children_count;
|
||||
}
|
||||
$comment->forceDelete();
|
||||
|
||||
// Comment::destroy($comment_id);
|
||||
return $remove_count;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
101
app/Http/Controllers/ComplaintController.php
Executable file
101
app/Http/Controllers/ComplaintController.php
Executable file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Domain\Comments\Models\Comment;
|
||||
use App\Domain\Complaints\Models\CommentComplaint;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Complaints\Models\Reason;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use App\Domain\Complaints\Models\Complaint;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
|
||||
class ComplaintController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid');
|
||||
}
|
||||
|
||||
public function index($feed_id)
|
||||
{
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
if ($feed->user()->is(auth()->user())) {
|
||||
return Redirect::back();
|
||||
}
|
||||
|
||||
$reasons = Reason::all();
|
||||
$feed = new FeedQueryBuilder();
|
||||
$feed = $feed->selectByIds($feed_id)->disablePaginate()->transformGet()->first();
|
||||
|
||||
return Inertia::render('Complaint/Index', [
|
||||
'user' => $feed['user'],
|
||||
'feed' => $feed,
|
||||
'reasons' => $reasons,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
||||
$feed_id = $request->get('feed');
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
|
||||
if(empty($request->get('reason'))){
|
||||
return Redirect::back()->with('error', 'Выберите тип жалобы!');
|
||||
}
|
||||
$reason_id = $request->get('reason');
|
||||
$reason = Reason::findOrFail($reason_id);
|
||||
|
||||
$complaint = new Complaint;
|
||||
$complaint->user_id = auth()->user()->id;
|
||||
$complaint->reason_id = $reason->id;
|
||||
$complaint->feed_id = $feed->id;
|
||||
$complaint->save();
|
||||
|
||||
// return Redirect::route('feeds.layoutsidebar')->with('success', 'Жалоба успешно отправлена');
|
||||
return Redirect::back()->with('success', 'Жалоба успешно отправлена');
|
||||
}
|
||||
|
||||
|
||||
public function commentIndex($comment_id)
|
||||
{
|
||||
$comment = Comment::findOrFail($comment_id);
|
||||
if ($comment->user()->is(auth()->user())) {
|
||||
return Redirect::back();
|
||||
}
|
||||
|
||||
$reasons = Reason::all();
|
||||
$user = $comment->user;
|
||||
$user->name = $user->name;
|
||||
return Inertia::render('Complaint/IndexComment', [
|
||||
'user' => $comment->user,
|
||||
'comment' => $comment,
|
||||
'reasons' => $reasons,
|
||||
]);
|
||||
}
|
||||
|
||||
public function commentStore(Request $request)
|
||||
{
|
||||
$comment_id = $request->get('comment');
|
||||
$comment = Comment::findOrFail($comment_id);
|
||||
|
||||
if(empty($request->get('reason'))){
|
||||
return Redirect::back()->with('error', 'Выберите тип жалобы!');
|
||||
}
|
||||
$reason_id = $request->get('reason');
|
||||
$reason = Reason::findOrFail($reason_id);
|
||||
|
||||
$complaint = new CommentComplaint;
|
||||
$complaint->user_id = auth()->user()->id;
|
||||
$complaint->reason_id = $reason->id;
|
||||
$complaint->comment_id = $comment->id;
|
||||
$complaint->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Жалоба успешно отправлена');
|
||||
}
|
||||
|
||||
}
|
||||
13
app/Http/Controllers/Controller.php
Executable file
13
app/Http/Controllers/Controller.php
Executable file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
}
|
||||
92
app/Http/Controllers/DashboardController.php
Executable file
92
app/Http/Controllers/DashboardController.php
Executable file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Mail\FeedbackToAdmin;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Http\Request as HttpRequest;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
// $this->middleware('subs.paid');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$filter = Request::get('filter');
|
||||
$feeds = (new FeedQueryBuilder())->filter()->search(Request::only('search'))->build();
|
||||
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if($filter === 'hot'){
|
||||
$feeds = $feeds->sortByDesc('entity.likes')->values();
|
||||
}
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Dashboard/Index', [
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function commonSendWriteToUs()
|
||||
{
|
||||
return Inertia::render('Auth/Feedback', []);
|
||||
}
|
||||
|
||||
public function sendWriteToUs(HttpRequest $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
if($user){
|
||||
$request->validate([
|
||||
'title' => ['required'],
|
||||
'body' => ['required'],
|
||||
]);
|
||||
|
||||
$userInfo = (object)[
|
||||
'userFullName' => $user->name,
|
||||
'userPhone' => $user->phone,
|
||||
'userEmail' => $user->email,
|
||||
'profileUrl' => env('APP_URL') . '/profile/' . $user->username,
|
||||
'guest' => false
|
||||
];
|
||||
}else{
|
||||
$request->validate([
|
||||
'title' => ['required'],
|
||||
'body' => ['required'],
|
||||
'email' => ['required'],
|
||||
]);
|
||||
|
||||
$userInfo = (object)[
|
||||
'userEmail' => request()->post('email'),
|
||||
'guest' => true
|
||||
];
|
||||
}
|
||||
|
||||
$data = (object) [
|
||||
'title' => request()->post('title'),
|
||||
'body' => request()->post('body'),
|
||||
'userInfo' => $userInfo
|
||||
];
|
||||
|
||||
Mail::to(env('MAIL_ADMIN_EMAIL'))->send(new FeedbackToAdmin($data));
|
||||
|
||||
return back()->with('success', 'Сообщение успешно отправлено')->with('status', 'Сообщение успешно отправлено');
|
||||
}
|
||||
|
||||
}
|
||||
234
app/Http/Controllers/FeedsController.php
Executable file
234
app/Http/Controllers/FeedsController.php
Executable file
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Notifications\LikeAdded;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Notifications\PurchaseAdded;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Feeds\Service\FeedMediaTransform;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class FeedsController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid')->except('comments', 'commentsShowChildren', 'add_view_feed');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$feeds = (new FeedQueryBuilder(auth()->user()->live_feeds()))->enableAdvertising()->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Feed/Index', [
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
'active_button' => ''
|
||||
]);
|
||||
}
|
||||
|
||||
public function onlyImages()
|
||||
{
|
||||
$feeds = (new FeedQueryBuilder(auth()->user()->live_feeds()))->enableAdvertising()->addType('image')->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Feed/Index', [
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
'active_button' => 'image'
|
||||
]);
|
||||
}
|
||||
|
||||
public function onlyVideos()
|
||||
{
|
||||
$feeds = (new FeedQueryBuilder(auth()->user()->live_feeds()))->enableAdvertising()->addType('video')->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Feed/Index', [
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
'active_button' => 'video'
|
||||
]);
|
||||
}
|
||||
public function onlyMusics()
|
||||
{
|
||||
$feeds = (new FeedQueryBuilder(auth()->user()->live_feeds()))->enableAdvertising()->addType('music')->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Feed/Index', [
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
'active_button' => 'music'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function toggleLike($feed_id)
|
||||
{
|
||||
$auth_user = auth()->user();
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
$check = \DB::table('users_feeds_like')->where('user_id', $auth_user->id)->where('feed_id', $feed_id)->first();
|
||||
// $check_notifications = \DB::table('notifications')
|
||||
// ->where('notifiable_id', $auth_user->id)
|
||||
// ->where('entity_once', $feed_id)
|
||||
// ->where('once', 1)
|
||||
// ->first();
|
||||
|
||||
$auth_user->likes()->toggle([$feed_id]);
|
||||
|
||||
if(!$check && $feed->user_id !== $auth_user->id){
|
||||
$message = [
|
||||
'user_id' => $auth_user->id,
|
||||
'node_id' => $feed_id,
|
||||
];
|
||||
$feed->user->notify(new LikeAdded($message));
|
||||
}
|
||||
|
||||
return Redirect::back();
|
||||
}
|
||||
|
||||
public function audioLike($media_id)
|
||||
{
|
||||
sleep(1);
|
||||
auth()->user()->audioLike()->toggle([$media_id]);
|
||||
return Redirect::back();
|
||||
}
|
||||
|
||||
public function purchase($feed_id)
|
||||
{
|
||||
\DB::beginTransaction();
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
$price_feed = (int) $feed->price;
|
||||
$balance = SubscriptionService::calculate(auth()->user()->id);
|
||||
$check = \DB::table('user_feed_purchase')->where('user_id', auth()->user()->id)->where('feed_id', $feed_id)->first();
|
||||
if ($check) {
|
||||
return ['error' => 1, 'msg' => 'Вы уже купили данный продукт'];
|
||||
}
|
||||
if ($feed->user()->is(auth()->user())) {
|
||||
return ['error' => 1, 'msg' => 'Ошибка'];
|
||||
}
|
||||
if ($price_feed > $balance) {
|
||||
return ['error' => 1, 'msg' => 'Недостаточно средств'];
|
||||
}
|
||||
$user = auth()->user();
|
||||
$user->purchases()->attach($feed_id, ['amount' => $price_feed]);
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = $user->id;
|
||||
$point->feed_id = $feed->id;
|
||||
$point->point = $price_feed;
|
||||
$point->type = 'Покупка - ' . $feed->type; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::EXPENSE();
|
||||
$point->save();
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = $feed->user_id;
|
||||
$point->feed_id = $feed->id;
|
||||
$point->point = $price_feed;
|
||||
$point->type = 'Покупка - ' . $feed->type; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
$new_medias = $this->replace(null, $feed);
|
||||
|
||||
$message = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'node_id' => $feed->id,
|
||||
'price' => $price_feed,
|
||||
];
|
||||
$feed->user->notify(new PurchaseAdded($message));
|
||||
|
||||
\DB::commit();
|
||||
|
||||
return $new_medias;
|
||||
}
|
||||
|
||||
public function replace($feed_id = null, $feed = null)
|
||||
{
|
||||
if(empty($feed)){
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
}
|
||||
|
||||
$preview = '';
|
||||
$medias = [];
|
||||
|
||||
if($feed->is_paid === 1){
|
||||
$mediaTransform = new FeedMediaTransform($feed);
|
||||
$mediaTransform = $mediaTransform->paid()->spot();
|
||||
$preview = $mediaTransform['preview'];
|
||||
$medias = $mediaTransform['medias'];
|
||||
}
|
||||
|
||||
return ['preview' => $preview, 'collection' => $medias];
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function purchase_check($feed_id)
|
||||
{
|
||||
$check = \DB::table('user_feed_purchase')->where('user_id', auth()->user()->id)->where('feed_id', $feed_id)->first();
|
||||
if ($check) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public function add_view_feed($feed_id)
|
||||
{
|
||||
if(!auth()->check()){
|
||||
return 0;
|
||||
}
|
||||
|
||||
$check = \DB::table('users_feeds_view')->where('user_id', auth()->user()->id)->where('feed_id', $feed_id)->first();
|
||||
if(!$check){
|
||||
\DB::table('users_feeds_view')->insert([
|
||||
'user_id' => auth()->user()->id,
|
||||
'feed_id' => $feed_id
|
||||
]);
|
||||
$feed = Feed::findOrFail($feed_id);
|
||||
$feed->increment('views_count');
|
||||
return 1;
|
||||
}else{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function destroy(Feed $feed)
|
||||
{
|
||||
if ($feed->user()->is(auth()->user())) {
|
||||
$feed->delete();
|
||||
}
|
||||
|
||||
return Redirect::route('profile.user', auth()->user()->username)->with('success', 'Запись успешно удалена!');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
165
app/Http/Controllers/ImagesController.php
Executable file
165
app/Http/Controllers/ImagesController.php
Executable file
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
// use Illuminate\Http\Request as HttpRequest;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Http\Requests\ImageFormRequest;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use App\Domain\Tags\Action\CreateTagAction;
|
||||
use App\Domain\Feeds\Action\CreateFeedAction;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Images\Action\CreateImageAction;
|
||||
use App\Domain\Images\Action\UpdateImageAction;
|
||||
use App\Domain\Feeds\Service\FeedMediaTransform;
|
||||
use App\Domain\Images\DataTransferObjects\ImageData;
|
||||
|
||||
class ImagesController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid')->except('show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addType('image')
|
||||
->enableAdvertising()
|
||||
->search(Request::only('search'))
|
||||
->filter($filter)
|
||||
->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('images.index');
|
||||
return Inertia::render('Image/Index', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'local_route' => $route,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return Inertia::render('Image/Create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\ImageFormRequest $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(ImageFormRequest $request)
|
||||
{
|
||||
$action = new CreateFeedAction(
|
||||
new CreateImageAction(),
|
||||
new CreateTagAction(),
|
||||
);
|
||||
|
||||
$imageData = ImageData::fromRequest($request);
|
||||
$action($imageData);
|
||||
$msg = 'Изображение успешно загружено и находится на модерации!';
|
||||
return Redirect::route('profile.user', auth()->user()->username)->with('success', $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($slug)
|
||||
{
|
||||
$feed = new FeedQueryBuilder();
|
||||
$feed = $feed->selectBy('slug', $slug)->disablePaginate()->transformGet()->first();
|
||||
if(!$feed){
|
||||
abort(404);
|
||||
}
|
||||
return Inertia::render('Image/Show', [
|
||||
'user' => $feed['user'],
|
||||
'feed' => $feed,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($slug)
|
||||
{
|
||||
$feed = Feed::where('slug', $slug)->firstOrFail();
|
||||
if (!$feed->user()->is(auth()->user())) {
|
||||
abort(404);
|
||||
}
|
||||
$tags = $feed->tags()->pluck('name')->toArray();
|
||||
|
||||
$mediaTransformCommon = (new FeedMediaTransform($feed))->default()->spot();
|
||||
$mediaTransformPaid = (new FeedMediaTransform($feed))->paid()->spot();
|
||||
|
||||
return Inertia::render('Image/Edit', [
|
||||
'feed' => $feed,
|
||||
'tags' => $tags,
|
||||
'mediasCount' => count($mediaTransformCommon['medias']),
|
||||
'mediasCommon' => $mediaTransformCommon['medias'],
|
||||
'mediasPaid' => $mediaTransformPaid['medias'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(ImageFormRequest $request, Feed $feed)
|
||||
{
|
||||
$oldStatus = $feed->status;
|
||||
if (!$feed->user()->is(auth()->user())) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$action = new CreateFeedAction(
|
||||
new UpdateImageAction($feed),
|
||||
new CreateTagAction(),
|
||||
);
|
||||
|
||||
$imageData = ImageData::fromRequest($request);
|
||||
$action($imageData);
|
||||
|
||||
$newStatus = $feed->status;
|
||||
|
||||
$message = 'Изображение успешно обновлено!';
|
||||
if($oldStatus === StatusEnum::APPROVED() && $newStatus === StatusEnum::EDITABLE()){
|
||||
$message = 'Изображение успешно обновлено и находится на модерации!';
|
||||
}
|
||||
return Redirect::back()->with('success', $message);
|
||||
|
||||
}
|
||||
}
|
||||
331
app/Http/Controllers/MessengerController.php
Executable file
331
app/Http/Controllers/MessengerController.php
Executable file
@@ -0,0 +1,331 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Domain\Messenger\Models\ChatRoom;
|
||||
use App\Domain\Messenger\Models\Message;
|
||||
use App\Models\User;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Http\Request as HttpRequest;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
|
||||
class MessengerController extends Controller
|
||||
{
|
||||
|
||||
protected function getSearchByMessage($currentUser, $search)
|
||||
{
|
||||
return $currentUser
|
||||
->chat_rooms()
|
||||
->orderBy('updated_at', 'desc')
|
||||
->with(['messsages' => function ($query) use($search) {
|
||||
$query->where('message', 'ilike', "{$search}%");
|
||||
}, 'users:id,first_name,last_name,username,photo_path,banner_path,color,user_char'])
|
||||
->whereHas('messsages', function (Builder $query) use($search) {
|
||||
$query->where('message', 'ilike', "{$search}%");
|
||||
})
|
||||
->get();
|
||||
}
|
||||
|
||||
protected function getSearchByUser($currentUser, $search)
|
||||
{
|
||||
return $currentUser
|
||||
->chat_rooms()
|
||||
->orderBy('updated_at', 'desc')
|
||||
->with(['users:id,first_name,last_name,username,photo_path,banner_path,color,user_char', 'messsages'])
|
||||
->whereHas('users', function (Builder $query) use($search) {
|
||||
$query->where('first_name', 'ilike', '%'.$search.'%')
|
||||
->orWhere('last_name', 'ilike', '%'.$search.'%');
|
||||
})
|
||||
->get();
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
// Если пользователь выбирается по гет параметру
|
||||
$chatSelectUser = null;
|
||||
$chatSelectUserID = 0;
|
||||
if($getUsername = request()->get('user')){
|
||||
$chatSelectUser = User::where('username', $getUsername)->firstOrFail();
|
||||
$chatSelectUser->name = $chatSelectUser->name;
|
||||
$chatSelectUserID = $chatSelectUser->id;
|
||||
}
|
||||
|
||||
$search = request()->get('search');
|
||||
$type = request()->get('type');
|
||||
$currentUser = auth()->user();
|
||||
|
||||
if($search){
|
||||
if($type == 1){
|
||||
$chat_rooms = $this->getSearchByMessage($currentUser, $search);
|
||||
}else{
|
||||
$chat_rooms = $this->getSearchByUser($currentUser, $search);
|
||||
}
|
||||
|
||||
$chat_rooms->transform(function ($room) {
|
||||
$message = $room->messsages->first();
|
||||
$room->latestMessage = $message;
|
||||
return $room;
|
||||
});
|
||||
}else{
|
||||
$chat_rooms = $currentUser
|
||||
->chat_rooms()
|
||||
->orderBy('updated_at', 'desc')
|
||||
->with('latestMessage', 'users:id,first_name,last_name,username,photo_path,banner_path,color,user_char')
|
||||
->get();
|
||||
}
|
||||
|
||||
$rooms = $chat_rooms->map(function ($room) use ($currentUser, $chatSelectUserID) {
|
||||
$is_my_message = false;
|
||||
$classActive = false;
|
||||
if($room->latestMessage->user_id === $currentUser->id){
|
||||
$is_my_message = true;
|
||||
}
|
||||
$message = $room->latestMessage->message;
|
||||
$updated_at_human = $room->latestMessage->created_at->diffForHumans();
|
||||
$updated_at = $room->latestMessage->created_at->format('U');
|
||||
|
||||
$correspond = $room->users->where('id', '<>', $currentUser->id)->first();
|
||||
unset($correspond->pivot);
|
||||
$correspond->name = $correspond->name;
|
||||
if($chatSelectUserID === $correspond->id){ // делаем активным
|
||||
$classActive = true;
|
||||
}
|
||||
return [
|
||||
'id' => $room->id,
|
||||
'is_freeze' => $room->is_freeze,
|
||||
'classActive' => $classActive,
|
||||
'is_my_message' => $is_my_message,
|
||||
'message' => $message,
|
||||
'is_reading' => $room->latestMessage->is_reading,
|
||||
'updated_at' => $updated_at,
|
||||
'updated_at_human' => $updated_at_human,
|
||||
'correspond' => $correspond->toArray(),
|
||||
];
|
||||
});
|
||||
|
||||
if($chatSelectUserID){
|
||||
$checkActiveRoom = $rooms->contains(function ($item) {
|
||||
return $item['classActive'] === true;
|
||||
});
|
||||
if(!$checkActiveRoom){
|
||||
$globalRoomUser = $this->isRoomCreate($chatSelectUserID);
|
||||
if($globalRoomUser){
|
||||
$globalRoomUser->load('latestMessage');
|
||||
$is_my_message = false;
|
||||
if($globalRoomUser->latestMessage->user_id === auth()->user()->id){
|
||||
$is_my_message = true;
|
||||
}
|
||||
$new_room = [
|
||||
'id' => $globalRoomUser->id,
|
||||
'is_freeze' => $globalRoomUser->is_freeze,
|
||||
'classActive' => true,
|
||||
'is_my_message' => $is_my_message,
|
||||
'message' => $globalRoomUser->latestMessage->message,
|
||||
'is_reading' => $globalRoomUser->latestMessage->is_reading,
|
||||
'updated_at' => $globalRoomUser->updated_at->format('U'),
|
||||
'updated_at_human' => $globalRoomUser->updated_at->diffForHumans(),
|
||||
'correspond' => $chatSelectUser->only(['id','name','first_name','last_name','photo_path','banner_path','color','user_char', 'username']),
|
||||
];
|
||||
$rooms[] = $new_room;
|
||||
}
|
||||
}
|
||||
$rooms = $rooms->sortByDesc('classActive')->values();
|
||||
}
|
||||
|
||||
return Inertia::render('Messenger/Index', [
|
||||
'rooms' => $rooms,
|
||||
'roomSearch' => $search,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$room = ChatRoom::findOrFail($id);
|
||||
$search = request()->get('search');
|
||||
|
||||
$messages = $room->messsages()->with('user:id,first_name,photo_path,color,user_char')->orderBy('id');
|
||||
if($search){
|
||||
$messages = $messages->where('message', 'ilike', "{$search}%");
|
||||
}
|
||||
$messages = $messages->cursorPaginate(50);
|
||||
$nextCursor = get_cursor_hash($messages);
|
||||
|
||||
|
||||
|
||||
$messages->each(function ($message) {
|
||||
if($message->is_reading === false && $message->user_id != auth()->user()->id){
|
||||
$message->is_reading = true;
|
||||
$message->save();
|
||||
}
|
||||
$message->group = $message->created_at->format('d.m.Y');
|
||||
$message->created = $message->created_at->format('H:i');
|
||||
return $message;
|
||||
});
|
||||
$messages = $messages->groupBy(function ($val) {
|
||||
return \Carbon\Carbon::parse($val->created_at)->format('d.m.Y');
|
||||
});
|
||||
|
||||
return ['records' => $messages, 'cursor' => $nextCursor];
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function store(HttpRequest $request)
|
||||
{
|
||||
$message = $request->input('params.message');
|
||||
$chat_room_id = $request->input('params.room');
|
||||
$status = $this->createMessage($message, $chat_room_id);
|
||||
if($status === false){
|
||||
return null;
|
||||
}
|
||||
return $status;
|
||||
}
|
||||
|
||||
public function storeFromProfile(HttpRequest $request)
|
||||
{
|
||||
$message = $request->input('message');
|
||||
$chat_room_id = $request->input('chat_room');
|
||||
|
||||
$status = $this->createMessage($message, $chat_room_id);
|
||||
if($status === false){
|
||||
return redirect()->back()->with('error', 'Вы не можете отправить сообщение данному пользователю');
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', 'Сообщение успешно отправлено!');
|
||||
}
|
||||
|
||||
protected function createMessage($text, $chat_room_id)
|
||||
{
|
||||
$user = auth()->user();
|
||||
$chatRoom = ChatRoom::find($chat_room_id);
|
||||
if($chatRoom->is_freeze){
|
||||
return false;
|
||||
}
|
||||
$message = new Message;
|
||||
$message->message = $text;
|
||||
$message->user_id = $user->id;
|
||||
$message->chat_room_id = $chat_room_id;
|
||||
$message->save();
|
||||
|
||||
$chatRoom->touch();
|
||||
|
||||
$message->created = $message->created_at->format('H:i');
|
||||
$message->updated_at_room_human = $message->created_at->diffForHumans();
|
||||
$message->updated_at_room = $message->created_at->format('U');
|
||||
$message->group = $message->created_at->format('d.m.Y');
|
||||
$message->keyGroupDate = $message->created_at->format('d.m.Y');
|
||||
$message->user = $user->only(['id','first_name','photo_path','color','user_char']);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
public function checkRoom(HttpRequest $request)
|
||||
{
|
||||
$userId = $request->input('params.user');
|
||||
$room = $this->isRoomCreate($userId);
|
||||
return $room ? $room->id : 0;
|
||||
}
|
||||
|
||||
protected function isRoomCreate($userId)
|
||||
{
|
||||
return auth()->user()->chat_rooms()->whereHas('users', function (Builder $query) use($userId) {
|
||||
$query->where('id', $userId);
|
||||
})->first();
|
||||
}
|
||||
|
||||
public function createRoom(HttpRequest $request)
|
||||
{
|
||||
$message = $request->input('message');
|
||||
$user_id = $request->input('user_id');
|
||||
|
||||
$existBannedUsers = $this->getBannedUser($user_id);
|
||||
if($existBannedUsers){
|
||||
return redirect()->back()->with('error', 'Вы не можете отправить сообщение данному пользователю');
|
||||
}
|
||||
|
||||
$room = new ChatRoom;
|
||||
$room->save();
|
||||
$room->users()->attach([$user_id, auth()->user()->id]);
|
||||
|
||||
$this->createMessage($message, $room->id);
|
||||
|
||||
return redirect()->back()->with('success', 'Сообщение успешно отправлено!');
|
||||
}
|
||||
|
||||
public function freezeRoom(HttpRequest $request)
|
||||
{
|
||||
$room_id = $request->input('room');
|
||||
$room = ChatRoom::find($room_id);
|
||||
$roomUsers = $room->users;
|
||||
$isAuthUserExist = $roomUsers->contains(fn($user) => $user->id === auth()->user()->id);
|
||||
$correspond = $roomUsers->where('id', '<>', auth()->user()->id)->first();
|
||||
if(!$isAuthUserExist){
|
||||
return redirect()->back()->with('error', 'Доступ запрещен');
|
||||
}
|
||||
|
||||
// добавляем пользователя
|
||||
$status = auth()->user()->bannedUsers()->toggle([$correspond->id]);
|
||||
|
||||
// проверяем есть ли пользователя из чата в черном списке, если есть замораживаем чат
|
||||
$existBannedUsers = $this->getBannedUser($correspond->id);
|
||||
|
||||
if($existBannedUsers){ //disable touch update_at column
|
||||
\DB::table('chat_rooms')->where('id', $room->id)->update(['is_freeze' => true]);
|
||||
}else{
|
||||
\DB::table('chat_rooms')->where('id', $room->id)->update(['is_freeze' => false]);
|
||||
}
|
||||
|
||||
$msg = 'Пользователь успешно удален из чернго списка';
|
||||
if(count($status['attached'])){
|
||||
$msg = 'Пользователь успешно добавлен в черный список';
|
||||
}
|
||||
|
||||
return redirect()->back()->with('success', $msg);
|
||||
}
|
||||
|
||||
public function checkBannedUser(HttpRequest $request)
|
||||
{
|
||||
$correspond_id = $request->input('params.user');
|
||||
$partnerIsBanned = \DB::table('user_banned')
|
||||
->where('user_id', auth()->user()->id)
|
||||
->where('banned_user_id', $correspond_id)->count();
|
||||
if($partnerIsBanned){
|
||||
return ['banned' => true];
|
||||
}
|
||||
|
||||
return ['banned' => false];
|
||||
}
|
||||
|
||||
public function leaveRoom(HttpRequest $request)
|
||||
{
|
||||
$room_id = $request->input('room');
|
||||
|
||||
$room = ChatRoom::find($room_id);
|
||||
$room->users()->detach(auth()->user()->id);
|
||||
|
||||
return redirect()->back()->with('success', 'Успешно покинули беседу');
|
||||
}
|
||||
|
||||
|
||||
public function removeMessage($id)
|
||||
{
|
||||
$message = Message::findOrFail($id);
|
||||
$message->delete();
|
||||
|
||||
return ['success' => true];
|
||||
}
|
||||
|
||||
protected function getBannedUser($correspondId)
|
||||
{
|
||||
return \DB::table('user_banned')
|
||||
->where('user_id', auth()->user()->id)
|
||||
->where('banned_user_id', $correspondId)
|
||||
->orWhere(function($query) use($correspondId) {
|
||||
$query->where('user_id', $correspondId)
|
||||
->where('banned_user_id', auth()->user()->id);
|
||||
})->count();
|
||||
}
|
||||
}
|
||||
326
app/Http/Controllers/MoneyController.php
Executable file
326
app/Http/Controllers/MoneyController.php
Executable file
@@ -0,0 +1,326 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use YooKassa\Client;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Payments\Models\Withdrawal;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Domain\PaymentGateway\Services\QiwiService;
|
||||
use App\Domain\PaymentGateway\Services\UnitpayService;
|
||||
use App\Domain\PaymentGateway\Services\YookassaService;
|
||||
use App\Domain\PaymentGateway\Models\PaymentGatewayOrder;
|
||||
use App\Domain\PaymentGateway\Services\InterkassaService;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class MoneyController extends Controller
|
||||
{
|
||||
|
||||
public function startProcess(Request $request)
|
||||
{
|
||||
|
||||
$this->validate($request, [
|
||||
'sum' => 'required|integer|numeric',
|
||||
]);
|
||||
|
||||
$sum = (int) abs($request->input('sum'));
|
||||
|
||||
$amount = round(($sum * 0.035) + $sum, 1);
|
||||
|
||||
$order = PaymentGatewayOrder::yookassa($sum);
|
||||
$order_number = ['order_number' => $order->number];
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = auth()->user()->id;
|
||||
$point->point = $sum;
|
||||
$point->type = 'Ожидание поступления';
|
||||
$point->direction = DirectionEnum::PENDING();
|
||||
$point->meta = json_encode($order_number);
|
||||
$point->save();
|
||||
|
||||
|
||||
return redirect(YookassaService::payments_link($amount, $order, auth()->user()));
|
||||
}
|
||||
|
||||
// public function startProcess()
|
||||
// {
|
||||
// $amount = filter_input(INPUT_GET, 'sum', FILTER_VALIDATE_INT);
|
||||
|
||||
// if(empty($amount)){
|
||||
// return redirect()->back();
|
||||
// }
|
||||
|
||||
// $order = PaymentGatewayOrder::yookassa($amount);
|
||||
// return redirect(YookassaService::payments_link($amount, $order, auth()->user()));
|
||||
// }
|
||||
|
||||
|
||||
public function checkPointPay($id)
|
||||
{
|
||||
|
||||
$point = Point::findOrFail($id);
|
||||
|
||||
if($point->direction != 2){
|
||||
return redirect()->route('setting.money')->with('error', 'Ошбика');
|
||||
}
|
||||
|
||||
$order_number = json_decode($point->meta);
|
||||
if(empty($order_number)){
|
||||
return redirect()->route('setting.money')->with('error', 'Ошбика');
|
||||
}
|
||||
$order = PaymentGatewayOrder::where('number', $order_number->order_number)->first();
|
||||
|
||||
if(empty($order)){
|
||||
return redirect()->route('setting.money')->with('error', 'Ошбика');
|
||||
}
|
||||
|
||||
if($order->status !== 0){
|
||||
return redirect()->route('setting.money')->with('error', 'Ошбика');
|
||||
}
|
||||
|
||||
$YOOKASSA_SHOP_ID = env('YOOKASSA_SHOP_ID');
|
||||
$YOOKASSA_KEY = env('YOOKASSA_KEY');
|
||||
|
||||
$client = new Client();
|
||||
$client->setAuth($YOOKASSA_SHOP_ID, $YOOKASSA_KEY);
|
||||
$payment = $client->getPaymentInfo($order->system_payment_id);
|
||||
|
||||
if ($payment->getStatus() === "succeeded")
|
||||
{
|
||||
$order->status = 1;
|
||||
$order->save();
|
||||
|
||||
$point->point = $order->amount;
|
||||
$point->type = 'Пополнение счета: ' . $order->type . ' # ' . $order->id;
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
return redirect()->route('setting.money')->with('success', 'Счет успешно пополнен!');
|
||||
}
|
||||
else{
|
||||
|
||||
PaymentGatewayOrder::destroy($order->id);
|
||||
Point::destroy($point->id);
|
||||
|
||||
return redirect()->route('setting.money')->with('error', 'Платеж не прошел. Попробуйте еще или выберите другой способ оплаты');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function paymentStatus($number)
|
||||
{
|
||||
|
||||
$order = PaymentGatewayOrder::where('number', $number)->firstOrFail();
|
||||
|
||||
if($order->status !== 0){
|
||||
return redirect()->to('/');
|
||||
}
|
||||
|
||||
$YOOKASSA_SHOP_ID = env('YOOKASSA_SHOP_ID');
|
||||
$YOOKASSA_KEY = env('YOOKASSA_KEY');
|
||||
$client = new Client();
|
||||
$client->setAuth($YOOKASSA_SHOP_ID, $YOOKASSA_KEY);
|
||||
$payment = $client->getPaymentInfo($order->system_payment_id);
|
||||
|
||||
$point = Point::where('meta->order_number', $number)->first();
|
||||
if(empty($point)){
|
||||
$point = new Point;
|
||||
$point->user_id = auth()->user()->id;
|
||||
}
|
||||
|
||||
if ($payment->getStatus() === "succeeded")
|
||||
{
|
||||
$order->status = 1;
|
||||
$order->save();
|
||||
|
||||
|
||||
|
||||
$point->point = $order->amount;
|
||||
$point->type = 'Пополнение счета: ' . $order->type . ' # ' . $order->id;
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
return redirect()->route('setting.money')->with('success', 'Счет успешно пополнен!');
|
||||
}
|
||||
else{
|
||||
PaymentGatewayOrder::destroy($order->id);
|
||||
Point::destroy($point->id);
|
||||
return redirect()->route('setting.money')->with('error', 'Платеж не прошел. Попробуйте еще или выберите другой способ оплаты');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// public function qiwiStatus($number)
|
||||
// {
|
||||
// $YOOKASSA_SHOP_ID = env('YOOKASSA_SHOP_ID');
|
||||
// $YOOKASSA_KEY = env('YOOKASSA_KEY');
|
||||
// $client = new Client();
|
||||
// $client->setAuth($YOOKASSA_SHOP_ID, $YOOKASSA_KEY);
|
||||
// $payment = $client->getPaymentInfo($number);
|
||||
// dd($payment);
|
||||
|
||||
// $SECRET_KEY = env('QIWI_SECRET');
|
||||
|
||||
// $order = PaymentGatewayOrder::where('number', $number)->firstOrFail();
|
||||
// if($order->status !== 0){
|
||||
// return redirect()->to('/');
|
||||
// }
|
||||
|
||||
// $billPayments = new \Qiwi\Api\BillPayments($SECRET_KEY);
|
||||
// $response = $billPayments->getBillInfo($number);
|
||||
|
||||
// if ($response['status']['value'] === "PAID")
|
||||
// {
|
||||
// $order->status = 1;
|
||||
// $order->save();
|
||||
|
||||
// $point = new Point;
|
||||
// $point->user_id = auth()->user()->id;
|
||||
// $point->point = $order->amount;
|
||||
// $point->type = 'Пополнение счета: ' . $order->type . ' # ' . $order->id;
|
||||
// $point->direction = DirectionEnum::COMING();
|
||||
// $point->save();
|
||||
|
||||
// return redirect()->route('setting.money')->with('success', 'Счет успешно пополнен!');
|
||||
// }
|
||||
// else if ($response['status']['value'] === "WAITING")
|
||||
// {
|
||||
// echo "Ваш платеж в обработке \n Не закрывайте страницу и попробуйте обновить страницу позже";
|
||||
// die;
|
||||
// }
|
||||
|
||||
|
||||
// PaymentGatewayOrder::destroy($order->id);
|
||||
|
||||
// $msg_error = 'Заказ завершен с ошибкой';
|
||||
// if($response['status']['value'] === "REJECTED"){
|
||||
// $msg_error .= ' - Счет отклонен';
|
||||
// }
|
||||
// return redirect()->route('setting.money')->with('error', $msg_error);
|
||||
|
||||
// }
|
||||
|
||||
public function unitpayStatus()
|
||||
{
|
||||
dd(request()->all());
|
||||
}
|
||||
|
||||
public function interkassa()
|
||||
{
|
||||
$amount = filter_input(INPUT_GET, 'ik_am', FILTER_VALIDATE_INT);
|
||||
|
||||
if(empty($amount)){
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$order = PaymentGatewayOrder::interkassa($amount);
|
||||
|
||||
return redirect(InterkassaService::payments_link($amount, $order->id));
|
||||
}
|
||||
|
||||
public function interkassaStatus()
|
||||
{
|
||||
$ik_co_id = request()->ik_co_id; // Идентификатор кассы
|
||||
$ik_inv_id = request()->ik_inv_id; // Идентификатор платежа в системе Интеркасса
|
||||
$ik_inv_st = request()->ik_inv_st; // Состояние платежа. - success; fail
|
||||
$ik_pm_no = request()->ik_pm_no; // Номер заказа. example - ID_4233
|
||||
|
||||
if($ik_inv_st === 'success'){
|
||||
$order = PaymentGatewayOrder::findOrFail($ik_pm_no);
|
||||
if($order->status === 1){
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
$order->status = 1;
|
||||
$order->system_payment_id = $ik_inv_id;
|
||||
$order->save();
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = auth()->user()->id;
|
||||
$point->point = $order->amount;
|
||||
$point->type = 'Пополнение счета: ' . $order->type . ' # ' . $order->id;
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
return redirect()->route('setting.money')->with('success', 'Счет успешно пополнен!');
|
||||
}
|
||||
|
||||
return $this->fails($ik_pm_no, $ik_inv_st);
|
||||
|
||||
}
|
||||
|
||||
protected function fails($order_id, $status)
|
||||
{
|
||||
PaymentGatewayOrder::destroy($order_id);
|
||||
|
||||
$msg_error = 'Заказ завершен с ошибкой';
|
||||
if($status === 'canceled'){
|
||||
$msg_error = 'Заказ отменен';
|
||||
}
|
||||
return redirect()->route('setting.money')->with('error', $msg_error);
|
||||
}
|
||||
|
||||
|
||||
public function payouts()
|
||||
{
|
||||
$amount = request()->amount;
|
||||
$user = auth()->user();
|
||||
// $bankRequisites = $user->bank_requisites->first();
|
||||
|
||||
if(!$user->isVerifiedForWithdrawal()){
|
||||
return redirect()->back()->with('error', 'Нужно верифицировать аккаунт, загрузить копию паспорта и ввести данные бик, инн, расчетный счет');
|
||||
// return redirect()->back()->with('error', 'Нужно верифицировать ваш номер телефона');
|
||||
}
|
||||
|
||||
// if(empty($bankRequisites)){
|
||||
// return redirect()->back()->with('error', 'Заполните платежные реквизиты');
|
||||
// }
|
||||
|
||||
$balance = SubscriptionService::calculate(auth()->user()->id);
|
||||
if ($amount > $balance) {
|
||||
return redirect()->back()->with('error', 'Недостаточно средств для вывода');
|
||||
}
|
||||
|
||||
if($user->status == 1 || $user->status == 2){
|
||||
if (!Withdrawal::canRequestWithdrawalPhysical($user->id, $amount)) {
|
||||
return redirect()->back()->with('error', 'Превышен лимит выплат за текущий месяц (12000)');
|
||||
}
|
||||
}else{
|
||||
if (!Withdrawal::canRequestWithdrawalLegal($user->id, $amount)) {
|
||||
return redirect()->back()->with('error', 'Превышен лимит выплат за текущий месяц (150000)');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// $requisites = $bankRequisites->requisites;
|
||||
|
||||
// $detailsDescr[] = 'Тип: по номеру телефона';
|
||||
// $detailsDescr[] = 'Номер телефона: ' . $user->phone;
|
||||
$detailsDescr[] = 'Тип: Банк';
|
||||
// $detailsDescr[] = 'Номер карты: ' . $bankRequisites->number;
|
||||
$detailsDescr = implode(PHP_EOL, $detailsDescr);
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = auth()->user()->id;
|
||||
$point->point = $amount;
|
||||
$point->type = 'Вывод средств (ожидает обработки)'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::EXPENSE();
|
||||
$point->save();
|
||||
|
||||
$withdrawal = new Withdrawal;
|
||||
$withdrawal->point()->associate($point);
|
||||
$withdrawal->user()->associate(auth()->user());
|
||||
$withdrawal->requisites_id = 1;
|
||||
// $withdrawal->requisites()->associate($requisites);
|
||||
$withdrawal->amount = $amount;
|
||||
$withdrawal->history_payment_details = $detailsDescr;
|
||||
$withdrawal->save();
|
||||
|
||||
|
||||
|
||||
return redirect()->back()->with('success', 'Запрос на вывод денег успешно отправлен!');
|
||||
}
|
||||
}
|
||||
221
app/Http/Controllers/MusicsController.php
Executable file
221
app/Http/Controllers/MusicsController.php
Executable file
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Http\Requests\MusicFormRequest;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Domain\Tags\Action\CreateTagAction;
|
||||
use App\Domain\Feeds\Action\CreateFeedAction;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Musics\Action\CreateMusicAction;
|
||||
use App\Domain\Musics\Action\UpdateMusicAction;
|
||||
use App\Domain\Feeds\Service\FeedMediaTransform;
|
||||
use App\Domain\Musics\DataTransferObjects\MusicData;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class MusicsController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid')->except('loadedPlaylist', 'favoritePlaylist', 'show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addType('music')
|
||||
->search(Request::only('search'))
|
||||
->enableAdvertising()
|
||||
->filter($filter)
|
||||
->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('musics.index');
|
||||
return Inertia::render('Music/Feed', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'local_route' => $route,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return Inertia::render('Music/Create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(MusicFormRequest $request)
|
||||
{
|
||||
$action = new CreateFeedAction(
|
||||
new CreateMusicAction(),
|
||||
new CreateTagAction(),
|
||||
);
|
||||
|
||||
$musicData = MusicData::fromRequest($request);
|
||||
$action($musicData);
|
||||
$msg = 'Музыка успешно загружена и находится на модерации!';
|
||||
return Redirect::route('profile.user', auth()->user()->username)->with('success', $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($slug)
|
||||
{
|
||||
$feed = new FeedQueryBuilder();
|
||||
$feed = $feed->selectBy('slug', $slug)->disablePaginate()->transformGet()->first();
|
||||
if(!$feed){
|
||||
abort(404);
|
||||
}
|
||||
return Inertia::render('Music/Show', [
|
||||
'user' => $feed['user'],
|
||||
'feed' => $feed,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($slug)
|
||||
{
|
||||
$feed = Feed::where('slug', $slug)->firstOrFail();
|
||||
|
||||
if (!$feed->user()->is(auth()->user())) {
|
||||
abort(404);
|
||||
}
|
||||
$tags = $feed->tags()->pluck('name')->toArray();
|
||||
|
||||
|
||||
$mediaTransform = (new FeedMediaTransform($feed))->default();
|
||||
$mediaPreview = $mediaTransform->getPreviewObject();
|
||||
|
||||
$mediaTransformCommon = $mediaTransform->spot();
|
||||
$mediaTransformPaid = (new FeedMediaTransform($feed))->paid()->spot();
|
||||
|
||||
return Inertia::render('Music/Edit', [
|
||||
'feed' => $feed,
|
||||
'tags' => $tags,
|
||||
'mediaPreview' => $mediaPreview,
|
||||
'mediasCount' => count($mediaTransformCommon['medias']),
|
||||
'mediasCommon' => $mediaTransformCommon['medias'],
|
||||
'mediasPaid' => $mediaTransformPaid['medias'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(MusicFormRequest $request, Feed $feed)
|
||||
{
|
||||
$oldStatus = $feed->status;
|
||||
if (!$feed->user()->is(auth()->user())) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$action = new CreateFeedAction(
|
||||
new UpdateMusicAction($feed),
|
||||
new CreateTagAction(),
|
||||
);
|
||||
|
||||
$musicData = MusicData::fromRequest($request);
|
||||
$action($musicData);
|
||||
$newStatus = $feed->status;
|
||||
|
||||
$message = 'Аудио файл успешно обновлен!';
|
||||
if($oldStatus === StatusEnum::APPROVED() && $newStatus === StatusEnum::EDITABLE()){
|
||||
$message = 'Аудио файл успешно обновлен и находится на модерации!';
|
||||
}
|
||||
|
||||
return Redirect::back()->with('success', $message);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function loadedPlaylist()
|
||||
{
|
||||
|
||||
$musics = Media::whereHasMorph(
|
||||
'model',
|
||||
[Feed::class],
|
||||
function (Builder $query) {
|
||||
$query->where('user_id', auth()->user()->id)->where('type', 'musics');
|
||||
}
|
||||
)->where('collection_name', '<>', 'preview')->orderBy('id', 'desc')->cursorPaginate(10);
|
||||
$cursor = get_cursor_hash($musics);
|
||||
|
||||
$musics_collection = [];
|
||||
$musics->each(function ($media) use (&$musics_collection) {
|
||||
$musics_collection[] = [
|
||||
'url' => $media->getFullUrl(),
|
||||
'name' => $media->name,
|
||||
'playing' => false,
|
||||
'time' => $media->getCustomProperty('time'),
|
||||
'id' => $media->id,
|
||||
];
|
||||
});
|
||||
return ['collection' => $musics_collection, 'cursor' => $cursor];
|
||||
}
|
||||
|
||||
public function favoritePlaylist()
|
||||
{
|
||||
$audios = auth()->user()->audioLike()->cursorPaginate(10);
|
||||
$cursor = get_cursor_hash($audios);
|
||||
|
||||
$musics_collection = [];
|
||||
$audios->each(function ($media) use (&$musics_collection) {
|
||||
$musics_collection[] = [
|
||||
'url' => $media->getFullUrl(),
|
||||
'name' => $media->name,
|
||||
'playing' => false,
|
||||
'liked' => true,
|
||||
'time' => $media->getCustomProperty('time'),
|
||||
'id' => $media->id,
|
||||
];
|
||||
});
|
||||
return ['collection' => $musics_collection, 'cursor' => $cursor];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
266
app/Http/Controllers/ProfileController.php
Executable file
266
app/Http/Controllers/ProfileController.php
Executable file
@@ -0,0 +1,266 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\User;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Users\Service\ProfileDataService;
|
||||
use App\Domain\Users\DataTransferObjects\UserData;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class ProfileController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
abort_if(Str::contains(request()->url(), 'inner_systemuser_api'), 404);
|
||||
$this->middleware('subs.paid')->except('profile');
|
||||
}
|
||||
|
||||
public function profile($username)
|
||||
{
|
||||
|
||||
$user = User::where('username', $username)->firstOrFail();
|
||||
$authUserActiveSubscription = nova_get_setting('vote_paid_mode') ? SubscriptionService::activeSubscription() : true;
|
||||
|
||||
$packet = null;
|
||||
$packageCompleted = false;
|
||||
|
||||
if($user->private && auth()->user()){
|
||||
$packet = $user->customPackage;
|
||||
if($packet){
|
||||
$check = \DB::table('users_package_customers')
|
||||
->where('user_id', $user->id)
|
||||
->where('customer_id', auth()->user()->id)
|
||||
->where('package_id', $packet->id)
|
||||
->where('time_end', '>', now())
|
||||
->count();
|
||||
$packageCompleted = $check > 0 ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
$userData = UserData::fromModel($user);
|
||||
if($userData->is_auth_user){
|
||||
$feeds = (new FeedQueryBuilder($user->feeds()))->enableAdvertising()->disableActiveFeed()->order()->build();
|
||||
}else{
|
||||
$feeds = (new FeedQueryBuilder($user->feeds()))->enableAdvertising()->order()->build();
|
||||
}
|
||||
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$profileData = ProfileDataService::get($user);
|
||||
// $testPeriod = auth()->user()->testPeriodCheck();
|
||||
if(auth()->user()){
|
||||
$limitLeader = auth()->user()->subscribers()->where('leader', 1)->count() === nova_get_setting('vote_leader_count');
|
||||
}else{
|
||||
$limitLeader = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
return Inertia::render('Profile/Index', [
|
||||
// 'testPeriod' => $testPeriod,
|
||||
'user' => array_merge([
|
||||
'about' => $user->about,
|
||||
'is_sub' => $user->is_sub,
|
||||
], $userData->toArray()),
|
||||
'packet' => $packet,
|
||||
'authUserActiveSubscription' => $authUserActiveSubscription,
|
||||
'packageCompleted' => $packageCompleted,
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
'limitLeader' => $limitLeader,
|
||||
'is_leader' => $profileData->is_leader,
|
||||
'close_account' => $profileData->close_account,
|
||||
'counts' => [
|
||||
'feeds' => $profileData->count_feeds,
|
||||
'subscribers' => $profileData->count_subscribers,
|
||||
'readers' => $profileData->count_readable,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function profileReaders($username)
|
||||
{
|
||||
$user = User::where('username', $username)->firstOrFail();
|
||||
$limitLeader = auth()->user()->subscribers()->where('leader', 1)->count() === nova_get_setting('vote_leader_count');
|
||||
|
||||
$profileData = ProfileDataService::get($user);
|
||||
|
||||
$packageCompleted = false;
|
||||
|
||||
$authUserActiveSubscription = nova_get_setting('vote_paid_mode') ? SubscriptionService::activeSubscription() : true;
|
||||
|
||||
if($user->private){
|
||||
$packet = $user->customPackage;
|
||||
if($packet){
|
||||
$check = \DB::table('users_package_customers')
|
||||
->where('user_id', $user->id)
|
||||
->where('customer_id', auth()->user()->id)
|
||||
->where('package_id', $packet->id)
|
||||
->where('time_end', '>', now())
|
||||
->count();
|
||||
$packageCompleted = $check > 0 ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$myPaidListSubscribeTo = \DB::table('users_package_customers')
|
||||
->latest()
|
||||
->where('customer_id', auth()->user()->id)->get()->groupBy('user_id');
|
||||
|
||||
$myPaidListSubscribeTo = $myPaidListSubscribeTo->map(function($item){
|
||||
$first = $item->first();
|
||||
$first->expired = Carbon::parse($first->time_end) < now();
|
||||
return Carbon::parse($first->time_end) < now();
|
||||
});
|
||||
// dd($myPaidListSubscribeTo);
|
||||
|
||||
|
||||
$leader = Request::get('leader');
|
||||
if($leader === '1'){
|
||||
$readers = $user->subscribersOn();
|
||||
}elseif ($leader === '0') {
|
||||
$readers = $user->subscribersOff();
|
||||
}else{
|
||||
$readers = $user->subscribers();
|
||||
}
|
||||
$readers = $readers->filter(Request::only('search'))
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(User::PAGINATE);
|
||||
$nextCursor = get_cursor_hash($readers);
|
||||
|
||||
$readers->transform(function ($user) {
|
||||
return array_merge([
|
||||
'is_leader' => (boolean) $user->pivot->leader,
|
||||
], UserData::fromModel($user)->toArray());
|
||||
});
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $readers->items(), 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Profile/Readers', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'user' => array_merge([
|
||||
'about' => $user->about,
|
||||
'is_sub' => $user->is_sub,
|
||||
], UserData::fromModel($user)->toArray()),
|
||||
'packageCompleted' => $packageCompleted,
|
||||
'filters' => Request::all('search', 'leader'),
|
||||
'readers' => $readers->items(),
|
||||
'limitLeader' => $limitLeader,
|
||||
'authUserActiveSubscription' => $authUserActiveSubscription,
|
||||
'is_leader' => $profileData->is_leader,
|
||||
'close_account' => $profileData->close_account,
|
||||
'myPaidListSubscribeTo' => $myPaidListSubscribeTo,
|
||||
'counts' => [
|
||||
'feeds' => $profileData->count_feeds,
|
||||
'subscribers' => $profileData->count_subscribers,
|
||||
'readers' => $profileData->count_readable,
|
||||
]
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function profileSubs($username)
|
||||
{
|
||||
$user = User::where('username', $username)->firstOrFail();
|
||||
$limitLeader = auth()->user()->subscribers()->where('leader', 1)->count() === nova_get_setting('vote_leader_count');
|
||||
$profileData = ProfileDataService::get($user);
|
||||
$sub = Request::get('sub');
|
||||
|
||||
$authUserActiveSubscription = nova_get_setting('vote_paid_mode') ? SubscriptionService::activeSubscription() : true;
|
||||
|
||||
|
||||
$packageCompleted = false;
|
||||
|
||||
if($user->private){
|
||||
$packet = $user->customPackage;
|
||||
if($packet){
|
||||
$check = \DB::table('users_package_customers')
|
||||
->where('user_id', $user->id)
|
||||
->where('customer_id', auth()->user()->id)
|
||||
->where('package_id', $packet->id)
|
||||
->where('time_end', '>', now())
|
||||
->count();
|
||||
$packageCompleted = $check > 0 ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($sub !== null){
|
||||
$query = '';
|
||||
$typeSub = $sub === '1' ? '<>' : '=';
|
||||
|
||||
$subscribers = $user->subscriber_reverse()
|
||||
->withCount([
|
||||
'subscriber_reverse as pizda' => function (Builder $builder) use (&$query) {
|
||||
$query = $builder;
|
||||
$query->where('user_id', auth()->user()->id);
|
||||
},
|
||||
])
|
||||
->whereRaw("({$query->toSql()}) {$typeSub} ?", [$user->id, 0])
|
||||
|
||||
->filter(Request::only('search'))
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(User::PAGINATE);
|
||||
$subscribers->transform(function ($user) use ($sub) {
|
||||
return array_merge([
|
||||
'is_sub' => (boolean) $sub,
|
||||
], UserData::fromModel($user)->toArray());
|
||||
});
|
||||
}else{
|
||||
$subscribers = $user->subscriber_reverse()
|
||||
->withCount(['subscriber_reverse as is_sub' => function (Builder $query) {
|
||||
$query->where('user_id', auth()->user()->id);
|
||||
}])
|
||||
->withCasts(['is_sub' => 'boolean'])
|
||||
->filter(Request::only('search'))
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(User::PAGINATE);
|
||||
|
||||
$subscribers->transform(function ($user) {
|
||||
return array_merge([
|
||||
'is_sub' => $user->is_sub,
|
||||
], UserData::fromModel($user)->toArray());
|
||||
});
|
||||
}
|
||||
|
||||
$nextCursor = get_cursor_hash($subscribers);
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $subscribers->items(), 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Profile/Subs', [
|
||||
'user' => array_merge([
|
||||
'about' => $user->about,
|
||||
'is_sub' => $user->is_sub,
|
||||
], UserData::fromModel($user)->toArray()),
|
||||
'packageCompleted' => $packageCompleted,
|
||||
'authUserActiveSubscription' => $authUserActiveSubscription,
|
||||
'filters' => Request::all('search', 'sub'),
|
||||
'limitLeader' => $limitLeader,
|
||||
'is_leader' => $profileData->is_leader,
|
||||
'subscribers' => $subscribers->items(),
|
||||
'close_account' => $profileData->close_account,
|
||||
'counts' => [
|
||||
'feeds' => $profileData->count_feeds,
|
||||
'subscribers' => $profileData->count_subscribers,
|
||||
'readers' => $profileData->count_readable,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
98
app/Http/Controllers/PurchaseController.php
Executable file
98
app/Http/Controllers/PurchaseController.php
Executable file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Feeds\Service\FeedMediaTransform;
|
||||
|
||||
class PurchaseController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$purchases_feeds = new FeedQueryBuilder($user->purchases()->withTrashed());
|
||||
$purchases_feeds = $purchases_feeds->withFeedable()->feed->cursorPaginate(FeedQueryBuilder::PAGINATION_COUNT);
|
||||
$nextCursor = get_cursor_hash($purchases_feeds);
|
||||
|
||||
$feeds = [];
|
||||
foreach ($purchases_feeds as $purchases_feed) {
|
||||
$mediaTransform = (new FeedMediaTransform($purchases_feed))->default();
|
||||
$date = [
|
||||
'price' => $purchases_feed->pivot->amount,
|
||||
'purchase_date' => $purchases_feed->pivot->created_at->format('Y-m-d'),
|
||||
'preview' => $mediaTransform->getPreview(),
|
||||
'id' => $purchases_feed->id,
|
||||
'type' => $purchases_feed->type,
|
||||
];
|
||||
$feeds[] = $date;
|
||||
}
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Settings/SettingsPurchases', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'feeds' => $feeds,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
|
||||
$purchases_feed = new FeedQueryBuilder(auth()->user()->purchases()->withTrashed());
|
||||
$purchases_feed = $purchases_feed->selectByIds($id)->withFeedable()->withUser()->feed->firstOrFail();
|
||||
|
||||
$seller = $purchases_feed->user;
|
||||
$seller->name = $seller->name;
|
||||
|
||||
$mediaTransformCommon = (new FeedMediaTransform($purchases_feed))->default()->spot();
|
||||
$mediaTransformPaid = (new FeedMediaTransform($purchases_feed))->paid()->spot();
|
||||
|
||||
$purchase = [
|
||||
'id' => $purchases_feed->id,
|
||||
'title' => $purchases_feed->title,
|
||||
'body' => $purchases_feed->body,
|
||||
'type' => $purchases_feed->type,
|
||||
'price' => $purchases_feed->pivot->amount,
|
||||
'purchase_date' => $purchases_feed->pivot->created_at->format('Y-m-d'),
|
||||
|
||||
'preview' => $mediaTransformCommon['preview'],
|
||||
'common_medias' => $mediaTransformCommon['medias'],
|
||||
'paid_medias' => $mediaTransformPaid['medias'],
|
||||
];
|
||||
|
||||
return Inertia::render('Settings/SettingsPurchasesFile', [
|
||||
'purchase' => $purchase,
|
||||
'seller' => $seller,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function downloadPurchases($id)
|
||||
{
|
||||
|
||||
$purchases_feed = new FeedQueryBuilder(auth()->user()->purchases()->withTrashed());
|
||||
$purchases_feed = $purchases_feed->selectByIds($id)->withFeedable()->feed->firstOrFail();
|
||||
$mediaTransformPaid = (new FeedMediaTransform($purchases_feed))->getFullPath()->paid()->spot();
|
||||
|
||||
$purchase_date = $purchases_feed->pivot->created_at->format('Y-m-d');
|
||||
|
||||
$zip_file = "purchase-{$purchases_feed->type}-{$purchase_date}.zip";
|
||||
|
||||
|
||||
$zip = new \ZipArchive();
|
||||
$zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);
|
||||
foreach ($mediaTransformPaid['medias'] as $paid_media) {
|
||||
$zip->addFile($paid_media['url'], basename($paid_media['url']));
|
||||
}
|
||||
|
||||
$zip->close();
|
||||
|
||||
//unlink(public_path($zip_file));
|
||||
return response()->download($zip_file);
|
||||
}
|
||||
|
||||
}
|
||||
32
app/Http/Controllers/RequisitesController.php
Executable file
32
app/Http/Controllers/RequisitesController.php
Executable file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Domain\Payments\Models\Requisites;
|
||||
use App\Domain\Payments\Models\BankRequisites;
|
||||
|
||||
class RequisitesController extends Controller
|
||||
{
|
||||
public function updateBank()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$number = request()->number;
|
||||
$bankRequisites = $user->bank_requisites->first();
|
||||
if(!$bankRequisites){
|
||||
$bankRequisites = new BankRequisites;
|
||||
$bankRequisites->user()->associate(auth()->user());
|
||||
$bankRequisites->number = $number;
|
||||
$bankRequisites->save();
|
||||
|
||||
$requisites = new Requisites;
|
||||
$requisites->user()->associate(auth()->user());
|
||||
$bankRequisites->requisites()->save($requisites);
|
||||
}else{
|
||||
$bankRequisites->number = $number;
|
||||
$bankRequisites->save();
|
||||
}
|
||||
|
||||
|
||||
return redirect()->back()->with('success', 'Реквизиты успешно обновлены!');
|
||||
|
||||
}
|
||||
}
|
||||
376
app/Http/Controllers/SettingController.php
Executable file
376
app/Http/Controllers/SettingController.php
Executable file
@@ -0,0 +1,376 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Http\Request as HttpRequest;
|
||||
use App\Domain\Subscriptions\Models\Package;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
|
||||
const NOTIFICATION_THRESHOLD = 20;
|
||||
|
||||
public function index()
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
return Inertia::render('Settings/SettingsProfile', [
|
||||
'user' => [
|
||||
'id' => $user->id,
|
||||
'name' => $user->name,
|
||||
'username' => $user->username,
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
'email' => $user->email,
|
||||
'user_char' => $user->user_char,
|
||||
'color' => $user->color,
|
||||
'sex' => $user->sex,
|
||||
'type' => $user->type,
|
||||
'phone' => $user->phone,
|
||||
'date_of_birth' => $user->date_of_birth,
|
||||
'photo_path' => $user->photo_path,
|
||||
'banner_path' => $user->banner_path,
|
||||
'about' => $user->about,
|
||||
'private' => $user->private,
|
||||
'inn' => $user->inn,
|
||||
'checking_account' => $user->checking_account,
|
||||
'bik' => $user->bik,
|
||||
// 'allow_adult_content' => $user->allow_adult_content,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function notify()
|
||||
{
|
||||
auth()->user()->unreadNotifications()->update(['read_at' => Carbon::now()]);
|
||||
|
||||
$notifications = auth()->user()
|
||||
->notifications()
|
||||
->latest()
|
||||
->take(self::NOTIFICATION_THRESHOLD)
|
||||
->get();
|
||||
|
||||
$notifications_transform = [];
|
||||
foreach ($notifications as $notification) {
|
||||
$d = [];
|
||||
$data = $notification->data;
|
||||
|
||||
if($notification->notifiable_type === User::class){
|
||||
if($notification->type === 'App\Notifications\LikeAdded'){
|
||||
$d['type'] = 'like';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\CommentAdded'){
|
||||
$d['type'] = 'comment';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\Subscribed'){
|
||||
$d['type'] = 'subs';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\LeaderChoice'){
|
||||
$d['type'] = 'leader';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\UserCustomPaidSubscription'){
|
||||
$d['type'] = 'custom-paid-subs';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\PurchaseAdded'){
|
||||
$d['type'] = 'purchase';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\RemoveFeed'){
|
||||
$d['type'] = 'remove-feed';
|
||||
}
|
||||
if($notification->type === 'App\Notifications\BannedMessageFeed'){
|
||||
$d['type'] = 'banned-message-feed';
|
||||
}
|
||||
$user_who = User::find($data['user_id']);
|
||||
if(empty($user_who)){
|
||||
$notification->delete();
|
||||
continue;
|
||||
}
|
||||
|
||||
$d['user'] = [
|
||||
'id' => $user_who->id,
|
||||
'name' => $user_who->name,
|
||||
'username' => $user_who->username,
|
||||
'photo_path' => $user_who->photo_path,
|
||||
'color' => $user_who->color,
|
||||
'user_char' => $user_who->user_char,
|
||||
];
|
||||
|
||||
if(@$data['node_id']){
|
||||
$feed = new FeedQueryBuilder;
|
||||
$d['feed'] = $feed->selectByIds($data['node_id'])->disableActiveFeed()->withTrashed()->transformGet()->first();
|
||||
}else{
|
||||
$d['feed'] = '';
|
||||
}
|
||||
|
||||
$d['data'] = $data;
|
||||
$d['id'] = $notification->id;
|
||||
$d['created_at'] = $notification->created_at->diffForHumans();
|
||||
}
|
||||
$notifications_transform[] = $d;
|
||||
}
|
||||
|
||||
return Inertia::render('Settings/SettingsNotify', [
|
||||
'notifications' => $notifications_transform,
|
||||
]);
|
||||
}
|
||||
|
||||
public function money()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$points = $user
|
||||
->points()
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(User::PAGINATE);
|
||||
|
||||
$nextCursor = get_cursor_hash($points);
|
||||
|
||||
$points->each(function($line){
|
||||
$dt = explode(' ', $line->created_at);
|
||||
$line->date = $dt[0];
|
||||
$line->time = $dt[1];
|
||||
return $line;
|
||||
});
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $points->items(), 'next' => $nextCursor];
|
||||
}
|
||||
return Inertia::render('Settings/SettingsMoney', [
|
||||
'points' => $points->items(),
|
||||
'nextCursor' => $nextCursor,
|
||||
]);
|
||||
}
|
||||
|
||||
public function tarif()
|
||||
{
|
||||
|
||||
$user = auth()->user();
|
||||
$is_active = SubscriptionService::activeSubscription();
|
||||
$user_id = $user->id;
|
||||
$user_autosubscription = $user->autosubscription_site;
|
||||
|
||||
$plans = Package::all();
|
||||
$lastSubscription = $user->subscription->first();
|
||||
|
||||
if ($lastSubscription) {
|
||||
$lastSubscription->setRelation('package', $plans->where('id', $lastSubscription->package_id)->first());
|
||||
$lastSubscription->endDateTime = $lastSubscription->ends_at->format('Y-m-d');
|
||||
}
|
||||
|
||||
return Inertia::render('Settings/SettingsTarif', [
|
||||
'plans' => $plans,
|
||||
'is_active_sub' => $is_active,
|
||||
'user_autosubscription' => $user_autosubscription,
|
||||
'user_id' => $user_id,
|
||||
'lastSubscription' => $lastSubscription,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function likes()
|
||||
{
|
||||
|
||||
$feeds = (new FeedQueryBuilder(auth()->user()->likes()))->order()->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Settings/SettingsLikes', [
|
||||
'feeds' => $feeds,
|
||||
'nextCursor' => $nextCursor,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function payouts()
|
||||
{
|
||||
|
||||
$user = auth()->user();
|
||||
// $requisites = [];
|
||||
// $bankRequisites = $user->bank_requisites->first();
|
||||
// if($bankRequisites){
|
||||
// $requisites['id'] = $bankRequisites->id;
|
||||
// $requisites['number'] = $bankRequisites->number;
|
||||
// }
|
||||
$withdrawals = $user->withdrawals()
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(User::PAGINATE);
|
||||
|
||||
|
||||
$nextCursor = get_cursor_hash($withdrawals);
|
||||
|
||||
$statusCode = [
|
||||
'pending' => 'Запрос отправлен',
|
||||
'success' => 'Запрос выполнен',
|
||||
'cancel' => 'Отмена выплаты',
|
||||
];
|
||||
|
||||
$withdrawals->each(function($line) use($statusCode) {
|
||||
$dt = explode(' ', $line->created_at);
|
||||
$line->datePart = $dt[0];
|
||||
$line->timePart = $dt[1];
|
||||
$line->meta = 'Статус: ' . $statusCode[$line->status];
|
||||
$line->history_payment_details = nl2br($line->history_payment_details);
|
||||
return $line;
|
||||
});
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $withdrawals->items(), 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('Settings/SettingsPayouts', [
|
||||
// 'requisites' => $requisites,
|
||||
'isVerified' => $user->isVerified(),
|
||||
'withdrawals' => $withdrawals->items()
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
public function packet()
|
||||
{
|
||||
$user = auth()->user();
|
||||
$userPackage = $user->customPackage;
|
||||
|
||||
$purchased_subscriptions_by_users = \DB::table('users_package_customers')
|
||||
->where('user_id', auth()->user()->id)->orderBy('customer_id')->orderBy('time_end', 'desc')->get();
|
||||
|
||||
$purchased_subscriptions_by_users = $purchased_subscriptions_by_users->groupBy('customer_id');
|
||||
|
||||
|
||||
|
||||
|
||||
$subscriptions_by_users = \DB::table('users_package_customers')
|
||||
->join('users_subscribers', 'users_package_customers.customer_id', '=', 'users_subscribers.user_id')
|
||||
->select('users_package_customers.*', 'users_subscribers.autosubscription', 'users_subscribers.user_id as usId', 'users_subscribers.subscriber_id as subsId')
|
||||
->where('users_package_customers.customer_id', auth()->user()->id)
|
||||
->orderBy('users_package_customers.user_id')
|
||||
->orderBy('users_package_customers.time_end', 'desc')
|
||||
->get();
|
||||
|
||||
$subscriptions_by_users = $subscriptions_by_users->filter(function ($item) {
|
||||
return $item->user_id === $item->subsId && $item->customer_id === $item->usId;
|
||||
});
|
||||
|
||||
|
||||
// $subscriptions_by_users = \DB::table('users_package_customers')
|
||||
// ->where('customer_id', auth()->user()->id)
|
||||
// ->orderBy('user_id')
|
||||
// ->orderBy('time_end', 'desc')
|
||||
// ->get();
|
||||
|
||||
$subscriptions_by_users = $subscriptions_by_users->groupBy('user_id');
|
||||
|
||||
|
||||
$buyers = $this->getPacketUsers($purchased_subscriptions_by_users);
|
||||
|
||||
$subscriptions = $this->getPacketUsers($subscriptions_by_users);
|
||||
|
||||
|
||||
|
||||
|
||||
return Inertia::render('Settings/SettingsPacket', [
|
||||
'user' => $user,
|
||||
'packet' => $userPackage,
|
||||
'buyers' => $buyers->values()->toArray(),
|
||||
'subscriptions' => $subscriptions->values()->toArray(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
protected function getPacketUsers($subscriptions)
|
||||
{
|
||||
|
||||
$ids_customer = $subscriptions->keys();
|
||||
$users_customer = User::whereIn('id', $ids_customer)->get();
|
||||
|
||||
return $subscriptions->map(function ($items, $id) use($users_customer) {
|
||||
$new = [];
|
||||
$new['active'] = false;
|
||||
$new['autosubscription'] = false;
|
||||
$new['user'] = $users_customer->where('id', $id)->first()
|
||||
->only([
|
||||
'id', 'first_name', 'last_name',
|
||||
'color', 'user_char', 'username', 'photo_path'
|
||||
]);
|
||||
foreach($items as $item){
|
||||
// dd($items);
|
||||
$carbon = \Carbon\Carbon::parse($item->time_end);
|
||||
$active = now() < $carbon;
|
||||
if($active){
|
||||
$new['active'] = $active;
|
||||
}
|
||||
$new['autosubscription'] = $item->autosubscription ?? false;
|
||||
$new['lists'][] = ['time_end' => $carbon->format('d.m.Y'), 'price' => $item->price, 'active' => $active];
|
||||
}
|
||||
return $new;
|
||||
|
||||
});
|
||||
// dd($test);
|
||||
|
||||
// return $subscriptions->map(function ($item) use($users_customer,$type) {
|
||||
// $carbon = \Carbon\Carbon::parse($item->time_end);
|
||||
|
||||
// return [
|
||||
// 'id' => $item->id,
|
||||
// 'price' => $item->price,
|
||||
// 'time_end' => $carbon->format('d.m.Y'),
|
||||
// 'active' => now() < $carbon,
|
||||
// 'user' => $users_customer->first(function ($value) use($item,$type) {
|
||||
// return $value->id == $item->{$type};
|
||||
// })->toArray()
|
||||
// ];
|
||||
// });
|
||||
}
|
||||
|
||||
public function verification(HttpRequest $request)
|
||||
{
|
||||
|
||||
$document = $request->user()->getMedia('documents');
|
||||
|
||||
$first_document = $document->first();
|
||||
$doc_uuid = null;
|
||||
if($first_document){
|
||||
$doc_uuid = $first_document->uuid;
|
||||
}
|
||||
|
||||
$user = auth()->user();
|
||||
$isPhoneVerify = $user->phone_verified;
|
||||
$isPassportVerified = $user->passport_verified;
|
||||
|
||||
if (!empty($user->phone_verify_token) && $user->phone_verify_token_expire && $user->phone_verify_token_expire->gt(now())) {
|
||||
$isToken = true;
|
||||
}else{
|
||||
$isToken = false;
|
||||
}
|
||||
|
||||
return Inertia::render('Settings/SettingsVerification', [
|
||||
'docUuid' => $doc_uuid,
|
||||
'isToken' => $isToken,
|
||||
'isPhoneVerify' => $isPhoneVerify,
|
||||
'isPassportVerified' => $isPassportVerified,
|
||||
'phone' => $request->user()->phone,
|
||||
]);
|
||||
}
|
||||
|
||||
public function writeToUs(HttpRequest $request)
|
||||
{
|
||||
return Inertia::render('Settings/SettingsWriteToUs', [
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
public function documentsInfo()
|
||||
{
|
||||
return Inertia::render('Settings/SettingsDocuments', [
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
134
app/Http/Controllers/StaticController.php
Executable file
134
app/Http/Controllers/StaticController.php
Executable file
@@ -0,0 +1,134 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use League\Glide\ServerFactory;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use League\Glide\Responses\LaravelResponseFactory;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class StaticController extends Controller
|
||||
{
|
||||
|
||||
public function show(Filesystem $filesystem, Request $request, $path)
|
||||
{
|
||||
$server = ServerFactory::create([
|
||||
'response' => new LaravelResponseFactory($request),
|
||||
'source' => $filesystem->getDriver(),
|
||||
'cache' => $filesystem->getDriver(),
|
||||
'cache_path_prefix' => '.glide-cache',
|
||||
'base_url' => 'img',
|
||||
]);
|
||||
|
||||
$server->setPresets([
|
||||
'small' => [
|
||||
'w' => 200,
|
||||
'h' => 200,
|
||||
'fit' => 'crop',
|
||||
],
|
||||
'medium' => [
|
||||
'w' => 500,
|
||||
'h' => 500,
|
||||
'fit' => 'crop',
|
||||
],
|
||||
|
||||
'banner' => [
|
||||
'w' => 500,
|
||||
'fit' => 'crop',
|
||||
],
|
||||
'hero' => [
|
||||
'w' => 1600,
|
||||
'h' => 600,
|
||||
'fit' => 'crop',
|
||||
],
|
||||
]);
|
||||
|
||||
return $server->getImageResponse($path, $request->all());
|
||||
}
|
||||
|
||||
public function avatarRemove(Filesystem $filesystem)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$server = ServerFactory::create([
|
||||
'source' => $filesystem->getDriver(),
|
||||
'cache' => $filesystem->getDriver(),
|
||||
'cache_path_prefix' => '.glide-cache',
|
||||
'base_url' => 'img',
|
||||
]);
|
||||
|
||||
Storage::disk('public')->delete($user->photo_path);
|
||||
$server->deleteCache($user->photo_path);
|
||||
$user->photo_path = null;
|
||||
$user->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Аватар успешно удален!');
|
||||
}
|
||||
|
||||
public function avatar(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
request()->validate([
|
||||
'avatar' => 'required|image|mimes:jpeg,jpg,png|max:1024',
|
||||
]);
|
||||
|
||||
$path = $request->file('avatar')->store('avatars', 'public');
|
||||
$user->photo_path = $path;
|
||||
$user->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Аватар успешно обновлен!');
|
||||
}
|
||||
|
||||
public function banner(Request $request)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
request()->validate([
|
||||
'banner' => 'required|image|mimes:jpeg,jpg,png|max:2048',
|
||||
]);
|
||||
|
||||
$path = $request->file('banner')->store('banners', 'public');
|
||||
$user->banner_path = $path;
|
||||
$user->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Баннер успешно обновлен!');
|
||||
}
|
||||
|
||||
public function bannerRemove(Filesystem $filesystem)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$server = ServerFactory::create([
|
||||
'source' => $filesystem->getDriver(),
|
||||
'cache' => $filesystem->getDriver(),
|
||||
'cache_path_prefix' => '.glide-cache',
|
||||
'base_url' => 'img',
|
||||
]);
|
||||
|
||||
Storage::disk('public')->delete($user->banner_path);
|
||||
$server->deleteCache($user->banner_path);
|
||||
$user->banner_path = null;
|
||||
$user->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Баннер успешно удален!');
|
||||
}
|
||||
|
||||
public function removePreview($id)
|
||||
{
|
||||
$media = Media::findOrFail($id);
|
||||
$feed = $media->model;
|
||||
if (is_a($feed, Feed::class)) {
|
||||
if ($feed->user()->is(auth()->user())) {
|
||||
$media->delete();
|
||||
}
|
||||
}
|
||||
return Redirect::back()->with('success', 'Превью успешно удалено!');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
136
app/Http/Controllers/TagController.php
Executable file
136
app/Http/Controllers/TagController.php
Executable file
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Domain\Tags\Models\Tag;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Http\Request as HttpRequest;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
|
||||
class TagController extends Controller
|
||||
{
|
||||
public function index($tag)
|
||||
{
|
||||
$tag = Tag::where('slug', $tag)->first();
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addTags([$tag->id])
|
||||
->search(Request::only('search'))
|
||||
->filter($filter)
|
||||
->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('feed.tags', $tag->slug);
|
||||
|
||||
return Inertia::render('Tag/Feed', [
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'tag' => $tag,
|
||||
'local_route' => $route,
|
||||
'nextCursor' => $nextCursor,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
public function listImagesTag($tag)
|
||||
{
|
||||
$tag = Tag::where('slug', $tag)->first();
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addTags([$tag->id])
|
||||
->addType('image')
|
||||
->search(Request::only('search'))
|
||||
->filter($filter)
|
||||
->build();
|
||||
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('list.images.tag', $tag->slug);
|
||||
|
||||
return Inertia::render('Image/Index', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'tag' => $tag,
|
||||
'local_route' => $route,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
public function listMusicsTag($tag)
|
||||
{
|
||||
$tag = Tag::where('slug', $tag)->first();
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addTags([$tag->id])
|
||||
->addType('music')
|
||||
->search(Request::only('search'))
|
||||
->filter($filter)
|
||||
->build();
|
||||
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('list.musics.tag', $tag->slug);
|
||||
|
||||
return Inertia::render('Music/Feed', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'tag' => $tag,
|
||||
'local_route' => $route,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
public function listVideosTag($tag)
|
||||
{
|
||||
$tag = Tag::where('slug', $tag)->first();
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addTags([$tag->id])
|
||||
->addType('video')
|
||||
->search(Request::only('search'))
|
||||
->filter($filter)
|
||||
->build();
|
||||
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('list.videos.tag', $tag->slug);
|
||||
|
||||
return Inertia::render('Video/Feed', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'tag' => $tag,
|
||||
'local_route' => $route,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
101
app/Http/Controllers/UserPackageController.php
Executable file
101
app/Http/Controllers/UserPackageController.php
Executable file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
use App\Models\User;
|
||||
use Inertia\Inertia;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Domain\Feeds\Service\LiveFeed;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use App\Domain\Users\Models\UserPackage;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Notifications\UserCustomPaidSubscription;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class UserPackageController extends Controller
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid')->except('show');
|
||||
}
|
||||
|
||||
public function update()
|
||||
{
|
||||
$id_packet = request()->post('id');
|
||||
if($id_packet){
|
||||
$customPackage = UserPackage::find($id_packet);
|
||||
}else{
|
||||
$customPackage = new UserPackage;
|
||||
}
|
||||
|
||||
$customPackage->price = request()->post('price');
|
||||
$customPackage->user_id = auth()->user()->id;
|
||||
$customPackage->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Успешно обновлено');
|
||||
}
|
||||
|
||||
public function subs() {
|
||||
|
||||
$id_packet = request()->post('packet_id');
|
||||
$customPackage = UserPackage::find($id_packet);
|
||||
|
||||
$balance = SubscriptionService::calculate(auth()->user()->id);
|
||||
if ($customPackage->price > $balance) {
|
||||
return Redirect::back()->with('error', 'Недостаточно средств!');
|
||||
}
|
||||
|
||||
\DB::beginTransaction();
|
||||
|
||||
$userPackage = User::find($customPackage->user_id);
|
||||
|
||||
$check = \DB::table('users_subscribers')
|
||||
->where('user_id', auth()->user()->id)
|
||||
->where('subscriber_id', $customPackage->user_id)
|
||||
->first();
|
||||
|
||||
// в буд. по рефакторить, по сути сейчас этот код выполняется один раз
|
||||
// дальше пользователю нужно отписаться, и заново купить подписку!
|
||||
if(empty($check)){
|
||||
auth()->user()->subscribers()->toggle([$userPackage->id]);
|
||||
LiveFeed::addBySub($userPackage);
|
||||
}
|
||||
|
||||
|
||||
\DB::table('users_package_customers')->insert([
|
||||
'user_id' => $customPackage->user_id,
|
||||
'customer_id' => auth()->user()->id,
|
||||
'package_id' => $customPackage->id,
|
||||
'price' => $customPackage->price,
|
||||
// 'time_end' => now()->addMonths(),
|
||||
'time_end' => now()->addMinutes(10),
|
||||
'created_at' => now(),
|
||||
]);
|
||||
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = auth()->user()->id;
|
||||
$point->point = $customPackage->price;
|
||||
$point->type = 'Оформлена подписка на пользователя: ' . $userPackage->name . ' (' . $userPackage->username . ')'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::EXPENSE();
|
||||
$point->save();
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = $userPackage->id;
|
||||
$point->point = $customPackage->price;
|
||||
$point->type = 'Пользователь оформил платную подписку: ' . auth()->user()->name . ' (' . auth()->user()->username . ')'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::COMING();
|
||||
$point->save();
|
||||
|
||||
\DB::commit();
|
||||
|
||||
$message = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'node_id' => null,
|
||||
];
|
||||
$userPackage->notify(new UserCustomPaidSubscription($message));
|
||||
|
||||
return Redirect::back()->with('success', 'Подписка на пользователя успешно оформлена');
|
||||
|
||||
}
|
||||
}
|
||||
494
app/Http/Controllers/UsersController.php
Executable file
494
app/Http/Controllers/UsersController.php
Executable file
@@ -0,0 +1,494 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use DB;
|
||||
use Hash;
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use Inertia\Inertia;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Domain\Tags\Models\Tag;
|
||||
use Illuminate\Validation\Rule;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Notifications\Subscribed;
|
||||
use App\Domain\Points\Models\Point;
|
||||
use App\Notifications\LeaderChoice;
|
||||
use Illuminate\Support\Facades\App;
|
||||
use App\Domain\Feeds\Service\LiveFeed;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use App\Domain\Points\Enums\DirectionEnum;
|
||||
use App\Domain\Votes\Services\VoteService;
|
||||
use Illuminate\Http\Request as HttpRequest;
|
||||
use App\Domain\Subscriptions\Models\Package;
|
||||
use App\Domain\Subscriptions\Models\Subscription;
|
||||
use App\Domain\Users\DataTransferObjects\UserData;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
|
||||
class UsersController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid')->except('update', 'plan', 'postsCount', 'searchUserTag', 'testPaid');
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
|
||||
$users = User::filter(Request::only('search', 'sex'))
|
||||
->where('id', '<>', auth()->user()->id)
|
||||
->where('username', '<>', 'inner_systemuser_api')
|
||||
->withCount(['subscriber_reverse as is_sub' => function (Builder $query) {
|
||||
$query->where('user_id', auth()->user()->id);
|
||||
}])
|
||||
->withCasts(['is_sub' => 'boolean'])
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(User::PAGINATE);
|
||||
|
||||
$nextCursor = get_cursor_hash($users);
|
||||
$users->transform(function ($user) {
|
||||
return array_merge([
|
||||
'is_sub' => $user->is_sub,
|
||||
], UserData::fromModel($user)->toArray());
|
||||
});
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $users->items(), 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
return Inertia::render('User/Index', [
|
||||
'filters' => Request::all('search', 'sex'),
|
||||
'nextCursor' => $nextCursor,
|
||||
'users' => $users->items(),
|
||||
'per_page' => User::PAGINATE,
|
||||
]);
|
||||
}
|
||||
|
||||
public function testing()
|
||||
{
|
||||
|
||||
|
||||
|
||||
// $leaders = collect(SubscriptionService::leaders());
|
||||
$vote = (object) ['procent_site' => 10, 'procent_top' => 60];
|
||||
$t = (new VoteService($vote))->freeMode();
|
||||
dd($t);
|
||||
// $ids = $leaders->pluck('user_id');
|
||||
// $users = User::whereIn('id', $ids)->get();
|
||||
// $leaderUsers = $leaders->map(function($item) use($users) {
|
||||
// $item->user = $users->where('id', $item->user_id)->first()->only(['id', 'first_name', 'last_name', 'username']);
|
||||
// return $item;
|
||||
// });
|
||||
// dd($leaderUsers);
|
||||
|
||||
// dd(Str::uuid());
|
||||
// $user = new \App\Models\User();
|
||||
// $user->password = \Illuminate\Support\Facades\Hash::make('sysSDFGtemuser345345');
|
||||
// $user->email = 'system@systemuser_api.com';
|
||||
// $user->first_name = 'systemuser_api';
|
||||
// $user->username = 'inner_systemuser_api';
|
||||
// $user->save();
|
||||
|
||||
//dd($user);
|
||||
|
||||
// $needArray = [
|
||||
// 1 => ['time' => true],
|
||||
// 2 => ['time' => true],
|
||||
// 3 => ['time' => true],
|
||||
// ];
|
||||
|
||||
// $user = User::find(4);
|
||||
// $plucks = $user->feeds()->pluck('created_at', 'id')->transform(function ($item) {
|
||||
// return ['time' => $item->getTimestamp()];
|
||||
// })->toArray();
|
||||
|
||||
// dd($plucks);
|
||||
// DB::table('videos')->truncate();
|
||||
// DB::table('musics')->truncate();
|
||||
// DB::table('images')->truncate();
|
||||
// DB::table('user_feed_purchase')->truncate();
|
||||
// DB::table('users_feeds_like')->truncate();
|
||||
// DB::table('points')->truncate();
|
||||
// DB::table('notifications')->truncate();
|
||||
// DB::table('feed_tags')->truncate();
|
||||
// DB::table('feeds_comments')->truncate();
|
||||
// DB::table('complaints')->truncate();
|
||||
// DB::table('comments')->truncate();
|
||||
// DB::table('feeds')->truncate();
|
||||
|
||||
//$feeds = Feed::all();
|
||||
//foreach ($feeds as $feed) {
|
||||
// $enity = $feed->feedable;
|
||||
// $uuid = (string) Str::uuid();
|
||||
// $feed->title = $enity->title;
|
||||
// $feed->body = $enity->body;
|
||||
// $feed->price = $enity->price;
|
||||
// $feed->is_paid = $enity->is_paid;
|
||||
// $feed->type = $feed->type;
|
||||
// $feed->slug = $uuid . '_' . $feed->type;
|
||||
// $feed->save();
|
||||
// $medias = $enity->getMedia('common');
|
||||
// $medias_paid = $enity->getMedia('paid');
|
||||
// $medias_preview = $enity->getMedia('preview');
|
||||
|
||||
// foreach ($medias as $media) {
|
||||
// if(file_exists($media->getPath())){
|
||||
// $feed->addMedia($media->getPath())->toMediaCollection('common');
|
||||
// }
|
||||
// }
|
||||
// foreach ($medias_paid as $media) {
|
||||
// if(file_exists($media->getPath())){
|
||||
// $feed->addMedia($media->getPath())->toMediaCollection('paid');
|
||||
// }
|
||||
// }
|
||||
// foreach ($medias_preview as $media) {
|
||||
// if(file_exists($media->getPath())){
|
||||
// $feed->addMedia($media->getPath())->toMediaCollection('preview');
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function update(User $user)
|
||||
{
|
||||
Request::validate([
|
||||
'first_name' => ['required', 'max:80'],
|
||||
'last_name' => ['required', 'max:80'],
|
||||
'username' => ['required', 'max:80', Rule::unique('users')->ignore($user->id)],
|
||||
'email' => ['required', 'max:50', 'email', Rule::unique('users')->ignore($user->id)],
|
||||
'password' => ['nullable'],
|
||||
'phone' => ['nullable'],
|
||||
'date_of_birth' => ['nullable'],
|
||||
'sex' => ['nullable'],
|
||||
'type' => ['nullable'],
|
||||
'private' => ['nullable'],
|
||||
'inn' => ['nullable'],
|
||||
'checking_account' => ['nullable'],
|
||||
'bik' => ['nullable'],
|
||||
// 'allow_adult_content' => ['nullable'],
|
||||
'about' => ['nullable', 'max:180'],
|
||||
]);
|
||||
|
||||
$user->update(Request::only('first_name', 'last_name', 'email', 'username', 'phone', 'date_of_birth', 'sex', 'about', 'private', 'inn', 'checking_account', 'bik', 'type'));
|
||||
|
||||
if (Request::get('password')) {
|
||||
$user->update(['password' => Request::get('password')]);
|
||||
}
|
||||
|
||||
return Redirect::back()->with('success', 'Профиль обновлен!');
|
||||
}
|
||||
|
||||
public function destroy(User $user)
|
||||
{
|
||||
if (App::environment('demo') && $user->isDemoUser()) {
|
||||
return Redirect::back()->with('error', 'Deleting the demo user is not allowed.');
|
||||
}
|
||||
|
||||
$user->delete();
|
||||
|
||||
return Redirect::back()->with('success', 'User deleted.');
|
||||
}
|
||||
|
||||
public function restore(User $user)
|
||||
{
|
||||
$user->restore();
|
||||
|
||||
return Redirect::back()->with('success', 'User restored.');
|
||||
}
|
||||
|
||||
public function subs(User $user)
|
||||
{
|
||||
|
||||
if($user->private){
|
||||
return Redirect::back()->with('error', 'Закрытый аккаунт');
|
||||
}
|
||||
|
||||
$check = \DB::table('users_subscribers')
|
||||
->where('user_id', auth()->user()->id)
|
||||
->where('subscriber_id', $user->id)
|
||||
->first();
|
||||
|
||||
auth()->user()->subscribers()->toggle([$user->id]);
|
||||
|
||||
if(!$check){
|
||||
$message = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'node_id' => null,
|
||||
];
|
||||
$user->notify(new Subscribed($message));
|
||||
LiveFeed::addBySub($user);
|
||||
}else{
|
||||
LiveFeed::removeBySub($user);
|
||||
}
|
||||
|
||||
return Redirect::back()->with('success', 'Success');
|
||||
}
|
||||
|
||||
public function removePaidSubs(User $user)
|
||||
{
|
||||
auth()->user()->subscribers()->toggle([$user->id]);
|
||||
|
||||
DB::table('users_package_customers')
|
||||
->where('user_id', $user->id)
|
||||
->where('customer_id', auth()->user()->id)
|
||||
->delete();
|
||||
|
||||
LiveFeed::removeBySub($user);
|
||||
|
||||
return Redirect::back()->with('success', 'Успешно отписались от пользователя');
|
||||
}
|
||||
|
||||
public function settingsAutoSubsPaidUser(User $user)
|
||||
{
|
||||
DB::table('users_subscribers')
|
||||
->where('user_id', auth()->user()->id)
|
||||
->where('subscriber_id', $user->id)
|
||||
->update(['autosubscription' => DB::raw('NOT autosubscription')]);
|
||||
|
||||
return Redirect::back()->with('success', 'Успешно выполнено');
|
||||
}
|
||||
|
||||
public function settingsAutoSubs(User $user)
|
||||
{
|
||||
$auto = $user->autosubscription_site;
|
||||
|
||||
if($auto){
|
||||
$msg = 'Автоматическое списание отключено!';
|
||||
$user->autosubscription_site = false;
|
||||
}else{
|
||||
$msg = 'Автоматическое списание включено!';
|
||||
$user->autosubscription_site = true;
|
||||
}
|
||||
|
||||
$user->save();
|
||||
|
||||
return Redirect::back()->with('success', $msg);
|
||||
}
|
||||
|
||||
public function vote(User $user, HttpRequest $request)
|
||||
{
|
||||
|
||||
$authUserActiveSubscription = nova_get_setting('vote_paid_mode') ? SubscriptionService::activeSubscription() : true;
|
||||
if(!$authUserActiveSubscription){
|
||||
return Redirect::back()->with('error', 'Только пользователи с подпиской могут выбрать лидера!');
|
||||
}
|
||||
|
||||
$count_leader = nova_get_setting('vote_leader_count');
|
||||
if(!$request->vote && auth()->user()->subscribers()->where('leader', 1)->count() >= $count_leader){
|
||||
return Redirect::back()->with('error', "Можно выбрать {$count_leader} лидеров");
|
||||
}
|
||||
|
||||
if(!$request->vote){
|
||||
$message = [
|
||||
'user_id' => auth()->user()->id,
|
||||
'node_id' => null,
|
||||
];
|
||||
$user->notify(new LeaderChoice($message));
|
||||
}
|
||||
auth()->user()->subscribers()->updateExistingPivot($user->id, [
|
||||
'leader' => ! $request->vote,
|
||||
]);
|
||||
return Redirect::back()->with('success', 'Success Vote!');
|
||||
}
|
||||
|
||||
|
||||
public function plan($plan_id)
|
||||
{
|
||||
$user = auth()->user();
|
||||
|
||||
$active_subscription = SubscriptionService::activeSubscription();
|
||||
if ($active_subscription) {
|
||||
return Redirect::back()->with('error', 'Подписка уже активирована');
|
||||
}
|
||||
$balance = SubscriptionService::calculate($user->id);
|
||||
$plan = Package::findOrFail($plan_id);
|
||||
$plan_type = $plan->type;
|
||||
if ($plan_type === 'month3') {
|
||||
$ends_at = Carbon::now()->addMonths(3);
|
||||
} else {
|
||||
$ends_at = Carbon::now()->addMonths();
|
||||
}
|
||||
$price = $plan->price;
|
||||
if ($price > $balance) {
|
||||
return Redirect::back()->with('error', 'Недостаточно средств!');
|
||||
}
|
||||
|
||||
$sub = new Subscription;
|
||||
$sub->user_id = $user->id;
|
||||
$sub->package_id = $plan->id;
|
||||
$sub->price = $price;
|
||||
$sub->ends_at = $ends_at;
|
||||
$sub->status = 'complete'; //YSV ENUM!
|
||||
$sub->save();
|
||||
|
||||
$point = new Point;
|
||||
$point->user_id = $user->id;
|
||||
$point->point = $price;
|
||||
$point->type = 'Оплата за подписку'; //YSV ENUM!
|
||||
$point->direction = DirectionEnum::EXPENSE();
|
||||
$point->save();
|
||||
|
||||
return Redirect::back()->with('success', 'Вы успешо подписались!');
|
||||
}
|
||||
|
||||
public function testPaid()
|
||||
{
|
||||
// $price = 50;
|
||||
// $user = auth()->user();
|
||||
// $point = new Point;
|
||||
// $point->user_id = $user->id;
|
||||
// $point->point = $price;
|
||||
// $point->type = 'Пополнение баланса по кнопки'; //YSV ENUM!
|
||||
// $point->direction = DirectionEnum::COMING();
|
||||
// $point->save();
|
||||
// return Redirect::back()->with('success', 'Баланс успешно пополнен!');
|
||||
}
|
||||
|
||||
|
||||
public function postsCount($user_id)
|
||||
{
|
||||
$user = User::findOrFail($user_id);
|
||||
return $user->feeds()->count();
|
||||
}
|
||||
|
||||
public function searchUserTag()
|
||||
{
|
||||
|
||||
$search = Request::input('search');
|
||||
if(empty($search)){
|
||||
return [
|
||||
'users' => [],
|
||||
'tags' => [],
|
||||
];
|
||||
}
|
||||
|
||||
$sanitize_search = Str::slug($search);
|
||||
|
||||
$users = User::where('username', '%'.$search.'%')
|
||||
->where('username', '<>', 'inner_systemuser_api')
|
||||
->orWhere('first_name', 'ilike', '%'.$search.'%')
|
||||
->orWhere('last_name', 'ilike', '%'.$search.'%')->get();
|
||||
$users->each(function ($item) {
|
||||
$item->name = $item->name;
|
||||
return $item;
|
||||
});
|
||||
$sanitize_search = '%'.$sanitize_search.'%';
|
||||
$tags = Tag::where('slug', 'ilike', $sanitize_search)->withCount('feeds')->get();
|
||||
|
||||
return [
|
||||
'users' => $users,
|
||||
'tags' => $tags,
|
||||
];
|
||||
}
|
||||
|
||||
public function friend() {
|
||||
$user = auth()->user();
|
||||
$readers = $user->subscribers()->filter(Request::only('search'))
|
||||
->orderBy('id', 'desc')
|
||||
->cursorPaginate(50);
|
||||
|
||||
|
||||
$users = [];
|
||||
$nextCursor = get_cursor_hash($readers);
|
||||
$readers->each(function ($item) use(&$users) {
|
||||
$users[] = UserData::fromModel($item)->toArray();
|
||||
});
|
||||
return ['records' => $users, 'cursor' => $nextCursor];
|
||||
|
||||
}
|
||||
|
||||
public function updatePassword(HttpRequest $request)
|
||||
{
|
||||
# Validation
|
||||
$request->validate([
|
||||
'old_password' => 'required',
|
||||
'new_password' => 'required|string|min:6',
|
||||
]);
|
||||
|
||||
#Match The Old Password
|
||||
if(!Hash::check($request->old_password, auth()->user()->password)){
|
||||
return back()->with("error", "Old Password Doesn't match!");
|
||||
}
|
||||
|
||||
#Update the new Password
|
||||
User::whereId(auth()->user()->id)->update([
|
||||
'password' => Hash::make($request->new_password)
|
||||
]);
|
||||
|
||||
return back()->with("success", "Password changed successfully!");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function addDocument(HttpRequest $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
'docs' => 'required|file|image',
|
||||
]);
|
||||
|
||||
$documents = $request->user()->getMedia('documents');
|
||||
|
||||
if($documents->count()){
|
||||
foreach ($documents as $document) {
|
||||
$document->delete();
|
||||
}
|
||||
}
|
||||
$file = $request->file('docs');
|
||||
|
||||
auth()->user()->addMedia($file)->toMediaCollection('documents', 'local');
|
||||
|
||||
return back()->with("success", "Документ успешно загружен");
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function readDocument(string $uuid)
|
||||
{
|
||||
$media = Media::where('uuid', $uuid)->first();
|
||||
return response()->download($media->getPath(), $media->file_name);
|
||||
}
|
||||
|
||||
public function verifyPhoneRequest(Carbon $now)
|
||||
{
|
||||
$user = auth()->user();
|
||||
if(empty($user->phone)){
|
||||
return back()->with("error", "Нужно ввести телефон");
|
||||
}
|
||||
if (!empty($user->phone_verify_token) && $user->phone_verify_token_expire && $user->phone_verify_token_expire->gt($now)) {
|
||||
return back()->with("error", "Токен уже запрошен.");
|
||||
}
|
||||
|
||||
$user->phone_verified = false;
|
||||
$user->phone_verify_token = (string)random_int(10000, 99999);
|
||||
$user->phone_verify_token_expire = $now->copy()->addSeconds(300);
|
||||
$user->saveOrFail();
|
||||
|
||||
return back()->with("success", "Верификация номера телефона успешно запрошена, ожидайте");
|
||||
}
|
||||
|
||||
public function verifyPhone(HttpRequest $request, Carbon $now)
|
||||
{
|
||||
$user = auth()->user();
|
||||
$token = $request->input('token');
|
||||
if ($token !== $user->phone_verify_token) {
|
||||
return back()->with("error", "Токен уже запрошен.");
|
||||
}
|
||||
if ($user->phone_verify_token_expire->lt($now)) {
|
||||
return back()->with("error", "Срок действия токена истек.");
|
||||
}
|
||||
$user->phone_verified = true;
|
||||
$user->phone_verify_token = null;
|
||||
$user->phone_verify_token_expire = null;
|
||||
$user->saveOrFail();
|
||||
|
||||
return back()->with("success", "Верификация номера телефона успешно завершена");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
172
app/Http/Controllers/VideosController.php
Executable file
172
app/Http/Controllers/VideosController.php
Executable file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Inertia\Inertia;
|
||||
use App\Domain\Feeds\Models\Feed;
|
||||
use App\Domain\Feeds\Enums\StatusEnum;
|
||||
use App\Http\Requests\VideoFormRequest;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use App\Domain\Tags\Action\CreateTagAction;
|
||||
use App\Domain\Feeds\Action\CreateFeedAction;
|
||||
use App\Domain\Feeds\Queries\FeedQueryBuilder;
|
||||
use App\Domain\Videos\Action\CreateVideoAction;
|
||||
use App\Domain\Videos\Action\UpdateVideoAction;
|
||||
use App\Domain\Feeds\Service\FeedMediaTransform;
|
||||
use App\Domain\Videos\DataTransferObjects\VideoData;
|
||||
|
||||
class VideosController extends Controller
|
||||
{
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->middleware('subs.paid')->except('show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
||||
$filter = Request::get('filter');
|
||||
|
||||
$feeds = (new FeedQueryBuilder())
|
||||
->addType('video')
|
||||
->search(Request::only('search'))
|
||||
->filter($filter)
|
||||
->enableAdvertising()
|
||||
->build();
|
||||
$nextCursor = $feeds->nextCursor;
|
||||
$feeds = $feeds->transformData();
|
||||
|
||||
if(request()->wantsJson()){
|
||||
return ['collections' => $feeds, 'next' => $nextCursor];
|
||||
}
|
||||
|
||||
$route = route('videos.index');
|
||||
return Inertia::render('Video/Feed', [
|
||||
'nextCursor' => $nextCursor,
|
||||
'searchFilters' => Request::all('search'),
|
||||
'feeds' => $feeds,
|
||||
'local_route' => $route,
|
||||
'active_filter' => $filter ?? 'new'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return Inertia::render('Video/Create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(VideoFormRequest $request)
|
||||
{
|
||||
|
||||
$action = new CreateFeedAction(
|
||||
new CreateVideoAction(),
|
||||
new CreateTagAction(),
|
||||
);
|
||||
|
||||
$videoData = VideoData::fromRequest($request);
|
||||
$action($videoData);
|
||||
$msg = 'Видео успешно загружено и находится на модерации!';
|
||||
return Redirect::route('profile.user', auth()->user()->username)->with('success', $msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($slug)
|
||||
{
|
||||
$feed = new FeedQueryBuilder();
|
||||
$feed = $feed->selectBy('slug', $slug)->disablePaginate()->transformGet()->first();
|
||||
if(!$feed){
|
||||
abort(404);
|
||||
}
|
||||
return Inertia::render('Video/Show', [
|
||||
'user' => $feed['user'],
|
||||
'feed' => $feed,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($slug)
|
||||
{
|
||||
$feed = Feed::where('slug', $slug)->firstOrFail();
|
||||
|
||||
if (!$feed->user()->is(auth()->user())) {
|
||||
abort(404);
|
||||
}
|
||||
$tags = $feed->tags()->pluck('name')->toArray();
|
||||
|
||||
$mediaTransform = (new FeedMediaTransform($feed))->default();
|
||||
$mediaPreview = $mediaTransform->getPreviewObject();
|
||||
|
||||
$mediaTransformCommon = $mediaTransform->spot();
|
||||
$mediaTransformPaid = (new FeedMediaTransform($feed))->paid()->spot();
|
||||
|
||||
|
||||
return Inertia::render('Video/Edit', [
|
||||
'feed' => $feed,
|
||||
'tags' => $tags,
|
||||
'mediaPreview' => $mediaPreview,
|
||||
'mediasCount' => count($mediaTransformCommon['medias']),
|
||||
'mediasCommon' => $mediaTransformCommon['medias'],
|
||||
'mediasPaid' => $mediaTransformPaid['medias'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(VideoFormRequest $request, Feed $feed)
|
||||
{
|
||||
$oldStatus = $feed->status;
|
||||
if (!$feed->user()->is(auth()->user())) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
$action = new CreateFeedAction(
|
||||
new UpdateVideoAction($feed),
|
||||
new CreateTagAction(),
|
||||
);
|
||||
|
||||
$videoData = VideoData::fromRequest($request);
|
||||
$action($videoData);
|
||||
$newStatus = $feed->status;
|
||||
|
||||
$message = 'Видео успешно обновлено!';
|
||||
if($oldStatus === StatusEnum::APPROVED() && $newStatus === StatusEnum::EDITABLE()){
|
||||
$message = 'Видео успешно обновлено и находится на модерации!';
|
||||
}
|
||||
|
||||
return Redirect::back()->with('success', $message);
|
||||
}
|
||||
|
||||
}
|
||||
71
app/Http/Kernel.php
Executable file
71
app/Http/Kernel.php
Executable file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http;
|
||||
|
||||
|
||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||
|
||||
class Kernel extends HttpKernel
|
||||
{
|
||||
/**
|
||||
* The application's global HTTP middleware stack.
|
||||
*
|
||||
* These middleware are run during every request to your application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Fruitcake\Cors\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
// \App\Http\Middleware\EnsureEmailIsVerified::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\App\Http\Middleware\HandleInertiaRequests::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
'throttle:api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware.
|
||||
*
|
||||
* These middleware may be assigned to groups or used individually.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
'remember' => \Reinink\RememberQueryStrings::class,
|
||||
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'subs.paid' => \App\Http\Middleware\CheckSubscribeUser::class,
|
||||
];
|
||||
}
|
||||
21
app/Http/Middleware/Authenticate.php
Executable file
21
app/Http/Middleware/Authenticate.php
Executable file
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
protected function redirectTo($request)
|
||||
{
|
||||
if (! $request->expectsJson()) {
|
||||
return route('login');
|
||||
}
|
||||
}
|
||||
}
|
||||
43
app/Http/Middleware/CheckSubscribeUser.php
Executable file
43
app/Http/Middleware/CheckSubscribeUser.php
Executable file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
class CheckSubscribeUser
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
|
||||
if (! $request->user() ||
|
||||
($request->user() instanceof MustVerifyEmail &&
|
||||
! $request->user()->hasVerifiedEmail())) {
|
||||
|
||||
return $request->expectsJson()
|
||||
? abort(403, 'Ваш адрес электронной почты не подтвержден.')
|
||||
: Redirect::guest(URL::route('verification.notice'));
|
||||
}
|
||||
|
||||
// if($request->path() === '/' && empty(auth()->user())){
|
||||
// return $next($request);
|
||||
// }
|
||||
|
||||
// abort_if(empty(auth()->user()), 403);
|
||||
|
||||
// if (auth()->user()->checkClosedAccess()) {
|
||||
// return redirect(route('setting.tarif'))->with('error', 'Оплатите подписку!');
|
||||
// }
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/EncryptCookies.php
Executable file
17
app/Http/Middleware/EncryptCookies.php
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||
|
||||
class EncryptCookies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the cookies that should not be encrypted.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
34
app/Http/Middleware/EnsureEmailIsVerified.php
Executable file
34
app/Http/Middleware/EnsureEmailIsVerified.php
Executable file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
|
||||
class EnsureEmailIsVerified
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null $redirectToRoute
|
||||
* @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|null
|
||||
*/
|
||||
public function handle($request, Closure $next, $redirectToRoute = null)
|
||||
{
|
||||
// dd($request);
|
||||
// dd(auth()->user());
|
||||
if(!auth()->user()){
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
if (! auth()->user() ||
|
||||
(auth()->user() instanceof MustVerifyEmail &&
|
||||
! auth()->user()->hasVerifiedEmail())) {
|
||||
return response()->json(['message' => 'Your email address is not verified.'], 409);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
117
app/Http/Middleware/HandleInertiaRequests.php
Executable file
117
app/Http/Middleware/HandleInertiaRequests.php
Executable file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\User;
|
||||
use Inertia\Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Domain\Subscriptions\Service\SubscriptionService;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
class HandleInertiaRequests extends Middleware
|
||||
{
|
||||
/**
|
||||
* The root template that's loaded on the first page visit.
|
||||
*
|
||||
* @see https://inertiajs.com/server-side-setup#root-template
|
||||
* @var string
|
||||
*/
|
||||
protected $rootView = 'app';
|
||||
|
||||
/**
|
||||
* Determines the current asset version.
|
||||
*
|
||||
* @see https://inertiajs.com/asset-versioning
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
public function version(Request $request)
|
||||
{
|
||||
return parent::version($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the props that are shared by default.
|
||||
*
|
||||
* @see https://inertiajs.com/shared-data
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function share(Request $request)
|
||||
{
|
||||
$with_sidebar = 0;
|
||||
|
||||
if ($request->routeIs('*.layoutsidebar.*') || $request->routeIs('feeds.layoutsidebar')) {
|
||||
$with_sidebar = 1;
|
||||
}
|
||||
|
||||
return array_merge(parent::share($request), [
|
||||
'auth' => function () use ($request) {
|
||||
return [
|
||||
'user' => $request->user() ? [
|
||||
'id' => $request->user()->id,
|
||||
'name' => $request->user()->name,
|
||||
'username' => $request->user()->username,
|
||||
'first_name' => $request->user()->first_name,
|
||||
'last_name' => $request->user()->last_name,
|
||||
'email' => $request->user()->email,
|
||||
'user_char' => $request->user()->user_char,
|
||||
'color' => $request->user()->color,
|
||||
'photo_path' => $request->user()->photo_path,
|
||||
'private' => $request->user()->private,
|
||||
'banner_path' => $request->user()->banner_path,
|
||||
] : null,
|
||||
];
|
||||
},
|
||||
'balance' => function () use ($request) {
|
||||
if($request->user()){
|
||||
return SubscriptionService::calculate($request->user()->id);
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
'leaders' => function () use ($with_sidebar) {
|
||||
if( $with_sidebar ){
|
||||
$leaders = collect();
|
||||
if(nova_get_setting('vote_paid_mode')){
|
||||
foreach (SubscriptionService::leaders() as $leader) {
|
||||
if($leader->vote_count){
|
||||
$lUser = User::find($leader->user_id);
|
||||
$lUser->name = $lUser->name;
|
||||
$lUser->countVote = $leader->vote_count;
|
||||
$leaders[] = $lUser;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
$leaders = SubscriptionService::freeLeaders();
|
||||
}
|
||||
return $leaders;
|
||||
}
|
||||
},
|
||||
'is_notify' => function () use ($request) {
|
||||
if($request->user()){
|
||||
return $request->user()->unreadNotifications()->count();
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
'message_reading_count' => function () use ($request) {
|
||||
if($request->user()){
|
||||
return $request->user()->chat_rooms()->whereHas('latestMessage', function (Builder $query) use($request) {
|
||||
$query->where('is_reading', false)->where('user_id', '<>', $request->user()->id);
|
||||
})->count();
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
'sidebar_layout' => $with_sidebar,
|
||||
'paid_mode' => function () {
|
||||
return nova_get_setting('vote_paid_mode');
|
||||
},
|
||||
'flash' => function () use ($request) {
|
||||
return [
|
||||
'success' => $request->session()->get('success'),
|
||||
'error' => $request->session()->get('error'),
|
||||
'status' => $request->session()->get('status'),
|
||||
];
|
||||
},
|
||||
]);
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Executable file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Executable file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
31
app/Http/Middleware/RedirectIfAuthenticated.php
Executable file
31
app/Http/Middleware/RedirectIfAuthenticated.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string[]|null ...$guards
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next, ...$guards)
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
18
app/Http/Middleware/TrimStrings.php
Executable file
18
app/Http/Middleware/TrimStrings.php
Executable file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||
|
||||
class TrimStrings extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Executable file
20
app/Http/Middleware/TrustHosts.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
23
app/Http/Middleware/TrustProxies.php
Executable file
23
app/Http/Middleware/TrustProxies.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $proxies = '**';
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user