Initial commit
This commit is contained in:
24
app/Console/Kernel.php
Normal file
24
app/Console/Kernel.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console;
|
||||
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
/**
|
||||
* Define the application's command schedule.
|
||||
*/
|
||||
protected function schedule(Schedule $schedule): void
|
||||
{
|
||||
// $schedule->command('inspire')->hourly();
|
||||
}
|
||||
/** php artisan words:process */
|
||||
|
||||
protected function commands(): void
|
||||
{
|
||||
$this->load(__DIR__.'/Commands');
|
||||
require base_path('routes/console.php');
|
||||
}
|
||||
}
|
||||
30
app/Exceptions/Handler.php
Normal file
30
app/Exceptions/Handler.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exceptions;
|
||||
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
/**
|
||||
* The list of the inputs that are never flashed to the session on validation exceptions.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
|
||||
/**
|
||||
* Register the exception handling callbacks for the application.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->reportable(function (Throwable $e) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
32
app/Exports/BlogImagesExport.php
Normal file
32
app/Exports/BlogImagesExport.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Exports;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Maatwebsite\Excel\Concerns\FromCollection;
|
||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||
|
||||
class BlogImagesExport implements FromCollection, WithHeadings
|
||||
{
|
||||
protected $data;
|
||||
|
||||
public function __construct(Collection $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function collection()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function headings(): array
|
||||
{
|
||||
return [
|
||||
'Blog ID',
|
||||
'Image Source',
|
||||
'Width',
|
||||
'Height',
|
||||
];
|
||||
}
|
||||
}
|
||||
40
app/Http/Controllers/Api/BlogLast.php
Normal file
40
app/Http/Controllers/Api/BlogLast.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Morilog\Jalali\Jalalian;
|
||||
use Carbon\Carbon;
|
||||
|
||||
class BlogLast extends Controller
|
||||
{
|
||||
public function yesterdayPosts()
|
||||
{
|
||||
try {
|
||||
|
||||
|
||||
$blogs = Blog::where('status' , 1)->orderByDesc('created_at')->get()->take(20);
|
||||
$blogArray = [];
|
||||
foreach ($blogs as $blog) {
|
||||
$tehranTime = Carbon::parse($blog->created_at)->setTimezone('Asia/Tehran');
|
||||
|
||||
$blogArray[] = [
|
||||
'success' => true,
|
||||
'title' => $blog->subject,
|
||||
'published_at' => jalaliDate($tehranTime, '%d %B، %Y'),
|
||||
'published_at_time' => $tehranTime->format('H:i'),
|
||||
'original_time' => $blog->created_at->format('H:i'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'مشکلی در دریافت اطلاعات پیش آمده: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
35
app/Http/Controllers/Api/BlogsController.php
Normal file
35
app/Http/Controllers/Api/BlogsController.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class BlogsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$blogs = Blog::where('notBlog' , null)->where('status' , 1)->orderByDesc('created_at')->get()->take(5);
|
||||
$blogArray= [] ;
|
||||
foreach ($blogs as $key => $blog) {
|
||||
$blogArray []= [
|
||||
'success' => true,
|
||||
'title' => $blog->subject,
|
||||
'published_at' => $blog->created_at,
|
||||
];
|
||||
}
|
||||
return response()->json([
|
||||
'data' => $blogArray ,
|
||||
'message' => 'اطلاعات با موفقیت ارسال شد'
|
||||
], 200);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'مشکلی در دریافت اطلاعات پیش آمده: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
74
app/Http/Controllers/Api/NewsAhrom.php
Normal file
74
app/Http/Controllers/Api/NewsAhrom.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class NewsAhrom extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$news_ahrom = Blog::where('notBlog' , 1)->where('status' , 1)->orderByDesc('created_at')->get()->take(5);
|
||||
$news_ahromArray= [] ;
|
||||
foreach ($news_ahrom as $key => $new) {
|
||||
$check = Category::where('id' , $new['category_array'])->first();
|
||||
if ( $check->slug == 'ahrom') {
|
||||
$news_ahromArray []= [
|
||||
'success' => true,
|
||||
'title' => $blog->subject,
|
||||
'published_at' => $blog->created_at,
|
||||
];
|
||||
}
|
||||
}
|
||||
return response()->json([
|
||||
'data' => $news_ahromArray ,
|
||||
'message' => 'اطلاعات با موفقیت ارسال شد'
|
||||
], 200);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'مشکلی در دریافت اطلاعات پیش آمده: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(string $id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
36
app/Http/Controllers/Api/NewsController.php
Normal file
36
app/Http/Controllers/Api/NewsController.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class NewsController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
try {
|
||||
$news = Blog::where('notBlog' , 1)->where('status' , 1)->orderByDesc('created_at')->get()->take(5);
|
||||
|
||||
$newsArray= [] ;
|
||||
foreach ($news as $key => $new) {
|
||||
$newsArray []= [
|
||||
'success' => true,
|
||||
'title' => $new->subject,
|
||||
'published_at' => $new->created_at,
|
||||
];
|
||||
}
|
||||
return response()->json([
|
||||
'data' => $newsArray ,
|
||||
'message' => 'اطلاعات با موفقیت ارسال شد'
|
||||
], 200);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'مشکلی در دریافت اطلاعات پیش آمده: ' . $e->getMessage()
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
78
app/Http/Controllers/BlogController.php
Normal file
78
app/Http/Controllers/BlogController.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class BlogController extends Controller
|
||||
{
|
||||
public function fixContentIds()
|
||||
{
|
||||
$blogs = Blog::withoutGlobalScope('filtered')->get();
|
||||
$updatedCount = 0;
|
||||
|
||||
foreach ($blogs as $blog) {
|
||||
$oldContent = $blog->content;
|
||||
$oldImage = $blog->image;
|
||||
$contentChanged = false;
|
||||
$imageChanged = false;
|
||||
|
||||
$patterns = [
|
||||
'/https?:\/\/ahrom\.net\/mag\/images\//',
|
||||
'/\/\/ahrom\.net\/mag\/images\//',
|
||||
'/http:\/\/www\.ahrom\.net\/mag\/images\//',
|
||||
'/https:\/\/www\.ahrom\.net\/mag\/images\//',
|
||||
'/ahrom\.net\/mag\/images\//'
|
||||
];
|
||||
|
||||
$newContent = preg_replace(
|
||||
$patterns,
|
||||
'https://ahromstorage.ir/ahrominvest/mag/images/',
|
||||
$oldContent
|
||||
);
|
||||
|
||||
$newContent = preg_replace_callback(
|
||||
'/(https:\/\/ahromstorage\.ir\/ahrominvest\/mag\/images\/.*?)\.webp/i',
|
||||
function($matches) {
|
||||
return str_replace('.webp', '.jpg', $matches[0]);
|
||||
},
|
||||
$newContent
|
||||
);
|
||||
|
||||
$newImage = $oldImage;
|
||||
if (!empty($oldImage) && preg_match('/\.webp$/i', $oldImage)) {
|
||||
$newImage = preg_replace('/\.webp$/i', '.jpg', $oldImage);
|
||||
$imageChanged = true;
|
||||
}
|
||||
|
||||
if ($newContent !== $oldContent) {
|
||||
$contentChanged = true;
|
||||
}
|
||||
|
||||
if ($contentChanged || $imageChanged) {
|
||||
$blog->content = $newContent;
|
||||
if ($imageChanged) {
|
||||
$blog->image = $newImage;
|
||||
}
|
||||
$blog->save();
|
||||
$updatedCount++;
|
||||
|
||||
$changes = [];
|
||||
if ($contentChanged) $changes[] = 'content';
|
||||
if ($imageChanged) $changes[] = 'image';
|
||||
|
||||
Log::info("Updated " . implode(' and ', $changes) . " in blog ID: {$blog->id}");
|
||||
}
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'status' => 'completed',
|
||||
'updated_count' => $updatedCount,
|
||||
'total_blogs' => count($blogs),
|
||||
'message' => $updatedCount > 0
|
||||
? "Successfully updated {$updatedCount} blogs (content and/or image fields)"
|
||||
: 'No matching URLs or webp images found to replace'
|
||||
]);
|
||||
}
|
||||
}
|
||||
8
app/Http/Controllers/Controller.php
Normal file
8
app/Http/Controllers/Controller.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
abstract class Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
149
app/Http/Controllers/SitemapController.php
Normal file
149
app/Http/Controllers/SitemapController.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SitemapController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
ob_clean();
|
||||
$blogs = Blog::query()
|
||||
->where('status', 1)
|
||||
->whereNull('notBlog')
|
||||
->orderBy('published_at', 'desc')
|
||||
->paginate(500, ['*'], 'page', $page ?? 1)
|
||||
->withQueryString();
|
||||
$news = Blog::query()
|
||||
->where('status', 1)
|
||||
->where('notBlog', 1)
|
||||
->orderBy('published_at', 'desc')
|
||||
->paginate(500, ['*'], 'page', $page ?? 1)
|
||||
->withQueryString();
|
||||
$totalPagespost = $blogs->lastPage();
|
||||
$totalPagenews = $news->lastPage();
|
||||
|
||||
return response()->view('sitemap.index' , ['news' => $totalPagenews , 'countNews' => count($news) , 'blogs' => $totalPagespost , 'countBlogs' => count($blogs) ])->header('Content-Type', 'text/xml');
|
||||
}
|
||||
|
||||
|
||||
public function posts($page = null)
|
||||
{
|
||||
if ($page == 1) {
|
||||
return redirect()->route('post.sitemap');
|
||||
}
|
||||
|
||||
ob_clean();
|
||||
$blogs = Blog::query()
|
||||
->where('status', 1)
|
||||
->whereNull('notBlog')
|
||||
->orderBy('published_at', 'desc')
|
||||
->paginate(500, ['*'], 'page', $page ?? 1)
|
||||
->withQueryString();
|
||||
|
||||
|
||||
|
||||
$blogImages = [];
|
||||
|
||||
foreach ($blogs as $blog) {
|
||||
$content = $blog->content;
|
||||
|
||||
if (empty($content)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pattern = '/<img[^>]+src="([^">]+)"/i';
|
||||
preg_match_all($pattern, $content, $matches);
|
||||
|
||||
$extractedImages = $matches[1] ?? [];
|
||||
|
||||
$blogImages[$blog->id] = $extractedImages;
|
||||
}
|
||||
|
||||
|
||||
return response()->view('sitemap.posts', compact('blogs', 'blogImages'))->header('Content-Type', 'text/xml');
|
||||
}
|
||||
|
||||
public function news($page = null)
|
||||
{
|
||||
if ($page == 1) {
|
||||
return redirect()->route('news.sitemap');
|
||||
}
|
||||
|
||||
ob_clean();
|
||||
$news = Blog::query()
|
||||
->where('status', 1)
|
||||
->where('notBlog', 1)
|
||||
->orderBy('published_at', 'desc')
|
||||
->paginate(500, ['*'], 'page', $page ?? 1)
|
||||
->withQueryString();
|
||||
|
||||
$blogImages = [];
|
||||
|
||||
foreach ($news as $blog) {
|
||||
$content = $blog->content;
|
||||
|
||||
if (empty($content)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$pattern = '/<img[^>]+src="([^">]+)"/i';
|
||||
preg_match_all($pattern, $content, $matches);
|
||||
|
||||
$extractedImages = $matches[1] ?? [];
|
||||
|
||||
$blogImages[$blog->id] = $extractedImages;
|
||||
}
|
||||
|
||||
|
||||
return response()->view('sitemap.news', compact('news', 'blogImages'))->header('Content-Type', 'text/xml');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public function page()
|
||||
{
|
||||
ob_clean();
|
||||
|
||||
$blogs = Blog::all();
|
||||
|
||||
$latestTimestamp = null;
|
||||
|
||||
foreach ($blogs as $blog) {
|
||||
$createdTimestamp = strtotime($blog->published_at);
|
||||
$updatedTimestamp = strtotime($blog->updated_at);
|
||||
|
||||
if ($latestTimestamp === null || $createdTimestamp > $latestTimestamp || $updatedTimestamp > $latestTimestamp) {
|
||||
$latestTimestamp = max($createdTimestamp, $updatedTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
$latestCarbon = \Carbon\Carbon::createFromTimestamp($latestTimestamp, 'Asia/Tehran');
|
||||
|
||||
return response()->view('sitemap.page', ['latestTimestamp' => $latestCarbon])->header('Content-Type', 'text/xml');
|
||||
}
|
||||
|
||||
public function postcategory()
|
||||
{
|
||||
ob_clean();
|
||||
|
||||
$categories = Category::where('parent' , null )->get();
|
||||
|
||||
return response()->view('sitemap.postcategory', ['categories' => $categories])->header('Content-Type', 'text/xml');
|
||||
}
|
||||
|
||||
public function newscategory()
|
||||
{
|
||||
ob_clean();
|
||||
|
||||
$categories = Category::all();
|
||||
|
||||
return response()->view('sitemap.newscategory', ['categories' => $categories])->header('Content-Type', 'text/xml');
|
||||
}
|
||||
|
||||
}
|
||||
71
app/Http/Kernel.php
Normal file
71
app/Http/Kernel.php
Normal 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<int, class-string|string>
|
||||
*/
|
||||
protected $middleware = [
|
||||
// \App\Http\Middleware\TrustHosts::class,
|
||||
\App\Http\Middleware\TrustProxies::class,
|
||||
\Illuminate\Http\Middleware\HandleCors::class,
|
||||
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\App\Http\Middleware\TrimStrings::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's route middleware groups.
|
||||
*
|
||||
* @var array<string, array<int, class-string|string>>
|
||||
*/
|
||||
protected $middlewareGroups = [
|
||||
'web' => [
|
||||
\App\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
|
||||
'api' => [
|
||||
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
|
||||
\Illuminate\Routing\Middleware\ThrottleRequests::class.':api',
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* The application's middleware aliases.
|
||||
*
|
||||
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
|
||||
*
|
||||
* @var array<string, class-string|string>
|
||||
*/
|
||||
protected $middlewareAliases = [
|
||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::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,
|
||||
'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class,
|
||||
'signed' => \App\Http\Middleware\ValidateSignature::class,
|
||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||
'detail' => \App\Http\Middleware\DetailMiddleware::class,
|
||||
'ensureslash' =>\App\Http\Middleware\EnsureSlashAtEnd::class,
|
||||
|
||||
];
|
||||
}
|
||||
18
app/Http/Middleware/Authenticate.php
Normal file
18
app/Http/Middleware/Authenticate.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Authenticate extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the path the user should be redirected to when they are not authenticated.
|
||||
*/
|
||||
protected function redirectTo(Request $request): ?string
|
||||
{
|
||||
|
||||
return $request->expectsJson() ? null : route('panel.login');
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal 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<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
50
app/Http/Middleware/EnsureSlashAtEnd.php
Normal file
50
app/Http/Middleware/EnsureSlashAtEnd.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class EnsureSlashAtEnd
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if ($request->ajax()) {
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
$path = $request->path();
|
||||
$query = $request->getQueryString();
|
||||
|
||||
if ($path !== '' && !str_ends_with($request->getRequestUri(), '/')) {
|
||||
$newUrl = $request->getSchemeAndHttpHost().'/'.$path.'/';
|
||||
|
||||
if ($query) {
|
||||
$newUrl .= '?'.$query;
|
||||
}
|
||||
dd(redirect()->to('/'.$newUrl, 301) ,$newUrl );
|
||||
return redirect()->to('/'.$newUrl, 301);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
protected function isLivewireRequest(Request $request): bool
|
||||
{
|
||||
return str_starts_with($request->path(), 'livewire/') ||
|
||||
$request->hasHeader('X-Livewire');
|
||||
}
|
||||
|
||||
protected function isStaticFile(Request $request): bool
|
||||
{
|
||||
$path = $request->getPathInfo();
|
||||
|
||||
return preg_match('/\.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$/', $path);
|
||||
}
|
||||
}
|
||||
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal file
17
app/Http/Middleware/PreventRequestsDuringMaintenance.php
Normal 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<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
//
|
||||
];
|
||||
}
|
||||
30
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
30
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next, string ...$guards): Response
|
||||
{
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?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<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
}
|
||||
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal 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<int, string|null>
|
||||
*/
|
||||
public function hosts(): array
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
||||
28
app/Http/Middleware/TrustProxies.php
Normal file
28
app/Http/Middleware/TrustProxies.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
{
|
||||
/**
|
||||
* The trusted proxies for this application.
|
||||
*
|
||||
* @var array<int, string>|string|null
|
||||
*/
|
||||
protected $proxies;
|
||||
|
||||
/**
|
||||
* The headers that should be used to detect proxies.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers =
|
||||
Request::HEADER_X_FORWARDED_FOR |
|
||||
Request::HEADER_X_FORWARDED_HOST |
|
||||
Request::HEADER_X_FORWARDED_PORT |
|
||||
Request::HEADER_X_FORWARDED_PROTO |
|
||||
Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
}
|
||||
25
app/Http/Middleware/UserHitory.php
Normal file
25
app/Http/Middleware/UserHitory.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\History;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class UserHitory
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
|
||||
History::create(['user_agent' => $request->userAgent(), 'ip' => $request->ip(),'blog_link'=>$request->url()]);
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
22
app/Http/Middleware/ValidateSignature.php
Normal file
22
app/Http/Middleware/ValidateSignature.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Routing\Middleware\ValidateSignature as Middleware;
|
||||
|
||||
class ValidateSignature extends Middleware
|
||||
{
|
||||
/**
|
||||
* The names of the query string parameters that should be ignored.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
// 'fbclid',
|
||||
// 'utm_campaign',
|
||||
// 'utm_content',
|
||||
// 'utm_medium',
|
||||
// 'utm_source',
|
||||
// 'utm_term',
|
||||
];
|
||||
}
|
||||
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
17
app/Http/Middleware/VerifyCsrfToken.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||
|
||||
class VerifyCsrfToken extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be excluded from CSRF verification.
|
||||
*
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $except = [
|
||||
'livewire/*'
|
||||
];
|
||||
}
|
||||
26
app/Http/Middleware/detailMiddleware.php
Normal file
26
app/Http/Middleware/detailMiddleware.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class DetailMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
$slug = $request->slug;
|
||||
|
||||
if ( $slug == 'dictionary' && strpos($slug, 'dictionary') == 0) {
|
||||
return redirect()->route('dictionary.main');
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
514
app/Livewire/CategoryBlog.php
Normal file
514
app/Livewire/CategoryBlog.php
Normal file
@@ -0,0 +1,514 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Support\Str;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
|
||||
class CategoryBlog extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
public $slug;
|
||||
public $title;
|
||||
public $page;
|
||||
public $category;
|
||||
public $is_news = false;
|
||||
public $categories = [];
|
||||
public $categoriesNotBlog = [];
|
||||
public $blogOrNotBlog;
|
||||
|
||||
public $parentCategories = [];
|
||||
public $childCategories = [];
|
||||
public $subChildCategories = [];
|
||||
public $selectedCategoryId = null;
|
||||
public $selectedTopLevelCategoryId = null;
|
||||
public $selectedSecondLevelCategory = null;
|
||||
public $topParent = null;
|
||||
public $selectedUrl;
|
||||
public $allParentsWithChildren;
|
||||
public $selectedThirdLevelCategory;
|
||||
|
||||
|
||||
public function mount($slug = null, $page = 1)
|
||||
{
|
||||
$this->slug = $slug;
|
||||
$this->page = $page;
|
||||
$this->is_news = request()->is('category/news*');
|
||||
|
||||
// گرفتن همه دستههای والد (باکس ۱)
|
||||
if ($this->is_news) {
|
||||
$operation = "!=";
|
||||
} else {
|
||||
$operation = "=";
|
||||
}
|
||||
$this->parentCategories = Category::where('parent_id', $operation, null)
|
||||
->whereNull('parent_below')
|
||||
->where('status', 1)
|
||||
->where('is_news', $this->is_news ? 1 : 0)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
|
||||
if ($this->slug == 'all') {
|
||||
$this->category = [
|
||||
"id" => 0,
|
||||
"title" => "همه",
|
||||
"slug" => "all",
|
||||
"is_news" => 0,
|
||||
"status" => 1,
|
||||
];
|
||||
$this->childCategories = collect();
|
||||
$this->subChildCategories = collect();
|
||||
|
||||
// مقداردهی متغیرهای انتخاب شده
|
||||
$this->selectedCategoryId = null;
|
||||
$this->selectedTopLevelCategoryId = null;
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
} else {
|
||||
$query = Category::query();
|
||||
if ($this->is_news) {
|
||||
$query->where('is_news', 1);
|
||||
} else {
|
||||
$query->where('is_news', 0);
|
||||
}
|
||||
$category = $query->with('parent')->where('slug', $this->slug)->first();
|
||||
if (!$category) {
|
||||
abort(404, 'دستهبندی مورد نظر یافت نشد');
|
||||
}
|
||||
|
||||
$this->category = $category;
|
||||
|
||||
// پیدا کردن والد سطح اول (top-level parent) دسته انتخاب شده
|
||||
$topParent = $category;
|
||||
while ($topParent && ($topParent->parent_id !== null || $topParent->parent_below !== null)) {
|
||||
if ($topParent->parent_id !== null) {
|
||||
$topParent = Category::find($topParent->parent_id);
|
||||
} elseif ($topParent->parent_below !== null) {
|
||||
$topParent = Category::find($topParent->parent_below);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->topParent = $topParent;
|
||||
|
||||
$this->selectedCategoryId = $category->id; // دسته انتخاب شده (باکس سوم یا خودش)
|
||||
$this->selectedTopLevelCategoryId = $topParent ? $topParent->id : null;
|
||||
|
||||
if (!$this->is_news) {
|
||||
// باکس دوم: زیردستههای والد سطح اول
|
||||
if ($topParent) {
|
||||
$this->childCategories = Category::where(function($query) use ($topParent) {
|
||||
$query->where('parent_id', $topParent->id)
|
||||
->orWhere('parent_below', $topParent->id);
|
||||
})
|
||||
->where('status', 1)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
|
||||
if ($category->id == $topParent->id) {
|
||||
// دسته انتخاب شده، دسته والد سطح اول است (باکس سوم خالی)
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
$this->subChildCategories = collect();
|
||||
} elseif ($this->childCategories->contains('id', $category->id)) {
|
||||
// دسته انتخاب شده، یک زیردسته از باکس دوم است
|
||||
$this->selectedSecondLevelCategory = $category;
|
||||
$this->subChildCategories = Category::where(function($query) use ($category) {
|
||||
$query->where('parent_id', $category->id)
|
||||
->orWhere('parent_below', $category->id);
|
||||
})
|
||||
->where('status', 1)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
} else {
|
||||
// دسته انتخاب شده، زیردسته ای از باکس سوم است (یا پایینتر)
|
||||
// باید والد سطح دوم اون دسته رو پیدا کنیم تا باکس سوم درست نمایش داده بشه
|
||||
$secondLevelParent = $category->parent_id ? Category::find($category->parent_id) : Category::find($category->parent_below);
|
||||
if ($secondLevelParent) {
|
||||
$this->selectedSecondLevelCategory = $secondLevelParent;
|
||||
$this->subChildCategories = Category::where(function($query) use ($secondLevelParent) {
|
||||
$query->where('parent_id', $secondLevelParent->id)
|
||||
->orWhere('parent_below', $secondLevelParent->id);
|
||||
})
|
||||
->where('status', 1)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
} else {
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
$this->subChildCategories = collect();
|
||||
}
|
||||
if ($this->selectedSecondLevelCategory && $category->id != $this->selectedSecondLevelCategory->id) {
|
||||
$this->selectedThirdLevelCategory = $category;
|
||||
} else {
|
||||
$this->selectedThirdLevelCategory = null;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
$this->childCategories = collect();
|
||||
$this->subChildCategories = collect();
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
}
|
||||
} else {
|
||||
$this->subChildCategories = collect();
|
||||
$this->childCategories = collect();
|
||||
$this->selectedTopLevelCategoryId = $category->id ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->title = $this->category['title'];
|
||||
$this->loadCategories();
|
||||
//
|
||||
// // اگر دسته انتخاب شده والد است (parent_id و parent_below هر دو null)
|
||||
// if ($category->parent_id === null && $category->parent_below === null) {
|
||||
// // باکس ۲: زیردستههای دسته والد انتخاب شده
|
||||
// $this->childCategories = Category::where(function($query) use ($category) {
|
||||
// $query->where('parent_id', $category->id)
|
||||
// ->orWhere('parent_below', $category->id);
|
||||
// })
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
//
|
||||
// $this->subChildCategories = collect();
|
||||
// } else {
|
||||
// // دسته انتخاب شده زیردسته است
|
||||
// // باکس ۲: زیردستههای دسته والد آن زیردسته (پیدا کردن دسته والد)
|
||||
// $parent = Category::find($category->parent_id ?: $category->parent_below);
|
||||
// if ($parent) {
|
||||
// $this->childCategories = Category::where(function($query) use ($parent) {
|
||||
// $query->where('parent_id', $parent->id)
|
||||
// ->orWhere('parent_below', $parent->id);
|
||||
// })
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
// } else {
|
||||
// $this->childCategories = collect();
|
||||
// }
|
||||
//
|
||||
// // باکس ۳: زیردستههای زیردسته انتخاب شده
|
||||
// $this->subChildCategories = Category::where(function($query) use ($category) {
|
||||
// $query->where('parent_id', $category->id)
|
||||
// ->orWhere('parent_below', $category->id);
|
||||
// })
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
// }
|
||||
// }
|
||||
|
||||
// $this->title = $this->category['title'];
|
||||
// $this->loadCategories();
|
||||
}
|
||||
|
||||
protected function loadCategories()
|
||||
{
|
||||
// if ($this->category['slug'] == 'news') {
|
||||
//
|
||||
// $this->categories = Category::where('is_news', ($this->is_news ? 1 : 0))
|
||||
// ->where('parent_id' , '!=' , null)
|
||||
// ->whereNull('parent_below')
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
// }elseif($this->category['slug'] == 'all'){
|
||||
// $this->categories = Category::where('is_news', ($this->is_news ? 1 : 0))
|
||||
// ->whereNull('parent_id')
|
||||
// ->whereNull('parent_below')
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
// } else {
|
||||
//// $this->categories = collect([$this->category]);
|
||||
// if ($this->is_news) {
|
||||
// $operation = "!=";
|
||||
// } else {
|
||||
// $operation = "=";
|
||||
// }
|
||||
// $this->categories = Category::with('parent')->where('is_news', ($this->is_news ? 1 : 0))
|
||||
// ->where('parent_id', $operation, null)
|
||||
// ->whereNull('parent_below')
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
//
|
||||
// $this->categoriesNotBlog = Category::where(function($query) {
|
||||
// $query->where('parent_id', $this->category['id'])
|
||||
// ->orWhere('parent_below', $this->category['id']);
|
||||
// })
|
||||
// ->where('status', 1)
|
||||
// ->orderBy('title')
|
||||
// ->get();
|
||||
// }
|
||||
}
|
||||
|
||||
public function goToCategory($catId, $is_news)
|
||||
{
|
||||
$this->slug = null;
|
||||
if (!$is_news && $catId == 0) {
|
||||
$this->slug = 'all';
|
||||
} elseif ($is_news && $catId == 0) {
|
||||
$this->slug = 'news';
|
||||
} else {
|
||||
$SSCategory = Category::findOrFail($catId);
|
||||
$this->slug = $SSCategory->slug;
|
||||
}
|
||||
$this->page = 1;
|
||||
$this->is_news = $is_news;
|
||||
// گرفتن همه دستههای والد (باکس ۱)
|
||||
if ($this->is_news) {
|
||||
$operation = "!=";
|
||||
} else {
|
||||
$operation = "=";
|
||||
}
|
||||
$this->parentCategories = Category::where('parent_id', $operation, null)
|
||||
->whereNull('parent_below')
|
||||
->where('status', 1)
|
||||
->where('is_news', $this->is_news ? 1 : 0)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
|
||||
$allParentsWithChildren = Category::where('parent_id', $operation, null)
|
||||
->whereNull('parent_below')
|
||||
->where('status', 1)
|
||||
->where('is_news', $this->is_news ? 1 : 0)
|
||||
->orderBy('title')
|
||||
->with('childrenRecursive')
|
||||
->get();
|
||||
|
||||
if ($this->slug == 'all') {
|
||||
$this->category = collect([
|
||||
"id" => 0,
|
||||
"title" => "همه",
|
||||
"slug" => "all",
|
||||
"is_news" => 0,
|
||||
"status" => 1,
|
||||
]);
|
||||
$this->childCategories = collect();
|
||||
$this->subChildCategories = collect();
|
||||
|
||||
// مقداردهی متغیرهای انتخاب شده
|
||||
$this->selectedCategoryId = null;
|
||||
$this->selectedTopLevelCategoryId = null;
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
} else {
|
||||
$query = Category::query();
|
||||
if ($this->is_news) {
|
||||
$query->where('is_news', 1);
|
||||
} else {
|
||||
$query->where('is_news', 0);
|
||||
}
|
||||
$category = $query->with('parent')->where('slug', $this->slug)->first();
|
||||
if (!$category) {
|
||||
abort(404, 'دستهبندی مورد نظر یافت نشد');
|
||||
}
|
||||
|
||||
$this->category = $category;
|
||||
|
||||
// پیدا کردن والد سطح اول (top-level parent) دسته انتخاب شده
|
||||
$topParent = $category;
|
||||
while ($topParent && ($topParent->parent_id !== null || $topParent->parent_below !== null)) {
|
||||
if ($topParent->parent_id !== null) {
|
||||
$topParent = Category::find($topParent->parent_id);
|
||||
} elseif ($topParent->parent_below !== null) {
|
||||
$topParent = Category::find($topParent->parent_below);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
$this->topParent = $topParent;
|
||||
|
||||
$this->selectedCategoryId = $category->id; // دسته انتخاب شده (باکس سوم یا خودش)
|
||||
$this->selectedTopLevelCategoryId = $topParent ? $topParent->id : null;
|
||||
|
||||
if (!$this->is_news) {
|
||||
// باکس دوم: زیردستههای والد سطح اول
|
||||
if ($topParent) {
|
||||
$this->childCategories = Category::where(function($query) use ($topParent) {
|
||||
$query->where('parent_id', $topParent->id)
|
||||
->orWhere('parent_below', $topParent->id);
|
||||
})
|
||||
->where('status', 1)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
|
||||
if ($category->id == $topParent->id) {
|
||||
// دسته انتخاب شده، دسته والد سطح اول است (باکس سوم خالی)
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
$this->subChildCategories = collect();
|
||||
} elseif ($this->childCategories->contains('id', $category->id)) {
|
||||
// دسته انتخاب شده، یک زیردسته از باکس دوم است
|
||||
$this->selectedSecondLevelCategory = $category;
|
||||
$this->subChildCategories = Category::where(function($query) use ($category) {
|
||||
$query->where('parent_id', $category->id)
|
||||
->orWhere('parent_below', $category->id);
|
||||
})
|
||||
->where('status', 1)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
} else {
|
||||
// دسته انتخاب شده، زیردسته ای از باکس سوم است (یا پایینتر)
|
||||
// باید والد سطح دوم اون دسته رو پیدا کنیم تا باکس سوم درست نمایش داده بشه
|
||||
$secondLevelParent = $category->parent_id ? Category::find($category->parent_id) : Category::find($category->parent_below);
|
||||
if ($secondLevelParent) {
|
||||
$this->selectedSecondLevelCategory = $secondLevelParent;
|
||||
$this->subChildCategories = Category::where(function($query) use ($secondLevelParent) {
|
||||
$query->where('parent_id', $secondLevelParent->id)
|
||||
->orWhere('parent_below', $secondLevelParent->id);
|
||||
})
|
||||
->where('status', 1)
|
||||
->orderBy('title')
|
||||
->get();
|
||||
} else {
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
$this->subChildCategories = collect();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$this->childCategories = collect();
|
||||
$this->subChildCategories = collect();
|
||||
$this->selectedSecondLevelCategory = null;
|
||||
}
|
||||
} else {
|
||||
$this->subChildCategories = collect();
|
||||
$this->childCategories = collect();
|
||||
$this->selectedTopLevelCategoryId = $category->id ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
$this->title = $this->category['title'];
|
||||
$this->loadCategories();
|
||||
return true;
|
||||
}
|
||||
|
||||
public function loadCategoriesAndChilds ()
|
||||
{
|
||||
if ($this->is_news) {
|
||||
$operation = "!=";
|
||||
} else {
|
||||
$operation = "=";
|
||||
}
|
||||
$allParentsWithChildren = Category::where('parent_id', $operation, null)
|
||||
->whereNull('parent_below')
|
||||
->where('status', 1)
|
||||
->where('is_news', $this->is_news ? 1 : 0)
|
||||
->orderBy('title')
|
||||
->with('childrenRecursive')
|
||||
->get();
|
||||
return response()->json($allParentsWithChildren);
|
||||
}
|
||||
|
||||
public function generateSlugAndNavigate($catId, $isNews)
|
||||
{
|
||||
$slug = null;
|
||||
|
||||
if (!$isNews && $catId == 0) {
|
||||
$slug = 'all';
|
||||
} elseif ($isNews && $catId == 0) {
|
||||
$slug = 'news';
|
||||
} else {
|
||||
$category = Category::findOrFail($catId);
|
||||
$slug = $category->slug;
|
||||
}
|
||||
|
||||
// Generate the target URL
|
||||
$url = $isNews
|
||||
? $slug != 'news' ? route('NewsCategory.show', ['slug' => $slug]) . "/" : route('NewsCategory.index').'/'
|
||||
: route('CategoryBlog.index', ['slug' => $slug]) . "/";
|
||||
|
||||
// Emit event to frontend for Livewire navigate
|
||||
$this->dispatch('navigate-to', $url);
|
||||
return;
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
public function render()
|
||||
{
|
||||
if ($this->page == 1 && str_contains(URL::current(), '/page/1')) {
|
||||
if ($this->is_news) {
|
||||
return redirect()->route('NewsCategory.index', ['slug' => $this->slug]);
|
||||
} else {
|
||||
return redirect()->route('CategoryBlog.index', ['slug' => $this->slug]);
|
||||
}
|
||||
}
|
||||
|
||||
$categoryIds = [];
|
||||
|
||||
if ($this->slug == 'all') {
|
||||
$this->blogOrNotBlog = 'blog';
|
||||
$blogs = Blog::query()
|
||||
->where('status', 1)
|
||||
->whereNull('notBlog')
|
||||
->orderByDesc('published_at')
|
||||
->paginate(18, ['*'], 'page', $this->page);
|
||||
} else {
|
||||
$category = $this->category;
|
||||
|
||||
if ($category instanceof Category) {
|
||||
$categoryIds = $category->getAllDescendantIds();
|
||||
$categoryIds[] = $category->id;
|
||||
} else {
|
||||
$categoryIds = [$category['id']];
|
||||
}
|
||||
|
||||
if ($this->is_news) {
|
||||
$this->blogOrNotBlog = 'notblog';
|
||||
$blogs = Blog::query()
|
||||
->where('status', 1)
|
||||
->where('notBlog', 1)
|
||||
->where(function ($query) use ($categoryIds) {
|
||||
$query->where(function ($q) use ($categoryIds) {
|
||||
foreach ($categoryIds as $categoryId) {
|
||||
$q->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
}
|
||||
});
|
||||
})
|
||||
->orderByDesc('published_at')
|
||||
->paginate(18, ['*'], 'page', $this->page);
|
||||
} else {
|
||||
$this->blogOrNotBlog = 'blog';
|
||||
$blogs = Blog::query()
|
||||
->where('status', 1)
|
||||
->whereNull('notBlog')
|
||||
->where(function ($query) use ($categoryIds) {
|
||||
$query->where(function ($q) use ($categoryIds) {
|
||||
foreach ($categoryIds as $categoryId) {
|
||||
$q->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
}
|
||||
});
|
||||
})
|
||||
->orderByDesc('published_at')
|
||||
->paginate(18, ['*'], 'page', $this->page);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->is_news && isset($this->category['slug']) && $this->category['slug'] == 'news') {
|
||||
$this->blogOrNotBlog = 'notblog';
|
||||
$blogs = Blog::query()
|
||||
->where('status', 1)
|
||||
->where('notBlog', 1)
|
||||
->orderByDesc('published_at')
|
||||
->paginate(18, ['*'], 'page', $this->page);
|
||||
}
|
||||
|
||||
$blogs->setPageName('page');
|
||||
if ($this->is_news) {
|
||||
$blogs->setPath(route('NewsCategory.index', ['slug' => $this->slug]));
|
||||
} else {
|
||||
$blogs->setPath(route('CategoryBlog.index', ['slug' => $this->slug]));
|
||||
}
|
||||
|
||||
Paginator::defaultView('custom-pagination');
|
||||
|
||||
return view('livewire.category-blog', [
|
||||
'blogs' => $blogs,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
13
app/Livewire/CreatePost.php
Normal file
13
app/Livewire/CreatePost.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class CreatePost extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.create-post');
|
||||
}
|
||||
}
|
||||
19
app/Livewire/Dictionary.php
Normal file
19
app/Livewire/Dictionary.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Layout;
|
||||
use App\Models\Dictionary as ModelDirection;
|
||||
|
||||
class Dictionary extends Component
|
||||
{
|
||||
public $dictionareis;
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
public function render()
|
||||
{
|
||||
$this->dictionareis = ModelDirection::orderBy('id', 'desc')->get();
|
||||
return view('livewire.dictionary');
|
||||
}
|
||||
}
|
||||
118
app/Livewire/Home.php
Normal file
118
app/Livewire/Home.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class Home extends Component
|
||||
{
|
||||
public $image;
|
||||
public $blogs;
|
||||
public $news;
|
||||
public $blogs2;
|
||||
public $blog_array = [];
|
||||
public $news_array = [];
|
||||
public $categories = [];
|
||||
public $categorieNews = [];
|
||||
public $lastNewsPosts = [];
|
||||
public $lastNewsArticles = [];
|
||||
public $lightmags = [];
|
||||
public $lightnews = [];
|
||||
|
||||
public $selectedCategoryPosts = null;
|
||||
public $selectedCategoryNews = null;
|
||||
public $selectedRoutePosts = null;
|
||||
public $selectedRouteNews = null;
|
||||
|
||||
public function mount(Request $request)
|
||||
{
|
||||
$allBlogs = Blog::where('status', 1)->orderBy('published_at', 'desc')->get();
|
||||
|
||||
$this->lightmags = $allBlogs->whereNull('notBlog')->take(50);
|
||||
|
||||
$this->lightnews = $allBlogs->where('notBlog', 1)->take(50);
|
||||
|
||||
$allCategroyBuilder = Category::where('status', 1);
|
||||
$allCategroyNewsBuilder = Category::where('status', 1);
|
||||
$this->blogs2 = Blog::where('status', 1)->where('notBlog', null)->where('chosen', 1)->orderBy('created_at', 'desc')->get()->take(5);
|
||||
|
||||
$this->lastNewsPosts = $allBlogs->whereNull('notBlog')->take(4);
|
||||
$this->lastNewsArticles = $allBlogs->where('notBlog', 1)->take(4);
|
||||
|
||||
$this->blogs = $allBlogs->where('chosen', 0)->where('notBlog', null);
|
||||
$this->news = $allBlogs->where('chosen', 0)->where('notBlog', 1);
|
||||
$this->categories = $allCategroyBuilder->with(['blogs' => function ($q) {
|
||||
$q->where('status', 1);
|
||||
}])->where('parent_below', null)->where('parent_id', null)->where('parent', null)->get();
|
||||
$this->categorieNews = $allCategroyNewsBuilder->where('is_news', 1)->where('parent_below', null)->where('parent_id', '!=', null)->where('parent', null)->get();
|
||||
}
|
||||
|
||||
public function selectCategory($categoryId, $type = 'posts')
|
||||
{
|
||||
$category = Category::find($categoryId);
|
||||
if ($type === 'posts') {
|
||||
$this->selectedCategoryPosts = $categoryId;
|
||||
if (isset($category)) {
|
||||
$this->selectedRoutePosts = route('CategoryBlog.index', ['slug' => $category->slug]) . "/";
|
||||
}
|
||||
} else {
|
||||
$this->selectedCategoryNews = $categoryId;
|
||||
if (isset($category)) {
|
||||
$this->selectedRouteNews = route('NewsCategory.show', ['slug' => $category->slug]) . "/";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function resetCategory($type = 'posts')
|
||||
{
|
||||
$this->selectedRoutePosts = null;
|
||||
$this->selectedRouteNews = null;
|
||||
if ($type === 'posts') {
|
||||
$this->selectedCategoryPosts = null;
|
||||
} else {
|
||||
$this->selectedCategoryNews = null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getCategoryItems($categoryId = null, $type = 'posts')
|
||||
{
|
||||
if ($type === 'posts') {
|
||||
$query = Blog::where('status', 1)->whereNull('notBlog');
|
||||
|
||||
if ($categoryId) {
|
||||
$query->where(function($q) use ($categoryId) {
|
||||
$q->where('category_id', $categoryId)
|
||||
->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->orderByDesc('published_at')
|
||||
->take(4)
|
||||
->get();
|
||||
} else {
|
||||
$query = Blog::where('status', 1)->where('notBlog', 1);
|
||||
|
||||
if ($categoryId) {
|
||||
$query->where(function($q) use ($categoryId) {
|
||||
$q->where('category_id', $categoryId)
|
||||
->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->orderByDesc('published_at')
|
||||
->take(4)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.home');
|
||||
}
|
||||
}
|
||||
BIN
app/Livewire/Home/0.tar.gz
Normal file
BIN
app/Livewire/Home/0.tar.gz
Normal file
Binary file not shown.
13
app/Livewire/Home/Auth/LoginPage.php
Normal file
13
app/Livewire/Home/Auth/LoginPage.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Home\Auth;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class LoginPage extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.home.auth.login-page');
|
||||
}
|
||||
}
|
||||
195
app/Livewire/Home/DetailNoBlog.php
Normal file
195
app/Livewire/Home/DetailNoBlog.php
Normal file
@@ -0,0 +1,195 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Home;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Comment;
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Attributes\Rule;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
|
||||
class DetailNoBlog extends Component
|
||||
{
|
||||
public $categoryparentslug;
|
||||
public $categoryunderparentslug;
|
||||
public $slug;
|
||||
|
||||
public $blog;
|
||||
public $blog_id;
|
||||
|
||||
public $like_status;
|
||||
public $comments;
|
||||
public $comment_name = 'کاربر';
|
||||
#[Rule('required')]
|
||||
public $comment_message;
|
||||
public $comment_name_reply = 'کاربر';
|
||||
public $comment_message_reply;
|
||||
public $lastNews;
|
||||
public $lastNews2;
|
||||
public $specialNews;
|
||||
public $questions = [];
|
||||
public $breadcrumbs = [];
|
||||
|
||||
public $cookie;
|
||||
public $pendingComments = [];
|
||||
|
||||
public function mount($categoryparentslug = null, $categoryunderparentslug = null, $slug = null)
|
||||
{
|
||||
$this->categoryparentslug = $categoryparentslug;
|
||||
$this->categoryunderparentslug = $categoryunderparentslug;
|
||||
$this->slug = $slug;
|
||||
if (is_null($this->categoryparentslug) || is_null($this->categoryunderparentslug) || is_null($this->slug)) {
|
||||
return abort('404');
|
||||
}
|
||||
if (Blog::where('slug', $this->slug)->first()) {
|
||||
$this->blog = Blog::where('slug', $this->slug)->where('status', 1)->first();
|
||||
|
||||
if (is_null($this->blog)) {
|
||||
$softDeletedBlog = Blog::withTrashed()->where('slug', $slug)->whereNotNull('deleted_at')->first();
|
||||
if (!is_null($softDeletedBlog)) {
|
||||
return abort(410);
|
||||
} else {
|
||||
return abort(404);
|
||||
}
|
||||
}
|
||||
$this->blog_id = $this->blog->id;
|
||||
} else {
|
||||
return abort('404');
|
||||
}
|
||||
$this->categoryunderparentslug = Category::where('slug', $this->categoryunderparentslug)->first();
|
||||
|
||||
$this->blog->increment('views');
|
||||
$this->slug = $slug;
|
||||
$this->blog_id = $this->blog->id;
|
||||
|
||||
$this->lastNews = Blog::query()->where('status', 1)->where('notBlog', null)->orderBy('created_at', 'desc')->get()->take(5);
|
||||
$this->lastNews2 = Blog::query()->where('status', 1)->where('notBlog', 1)->orderBy('created_at', 'desc')->get()->take(5);
|
||||
$this->specialNews = Blog::query()->where('status', 1)->where('notBlog', null)->where('chosen', 1)->orderBy('created_at', 'desc')->get()->take(5);
|
||||
}
|
||||
|
||||
#[Rule('required')]
|
||||
public $image_url;
|
||||
|
||||
public function comment()
|
||||
{
|
||||
$this->validate();
|
||||
$comment_id = Comment::create(['name' => $this->comment_name, 'message' => $this->comment_message, 'blog_id' => $this->blog_id, 'ip' => request()->ip(), 'user_agent' => request()->userAgent(), 'image_url' => $this->image_url]);
|
||||
$this->comment_message = null;
|
||||
$this->comment_name = 'کاربر';
|
||||
$this->dispatch('reset');
|
||||
$newComment = Comment::find($comment_id->id);
|
||||
$this->storeCommentInCookie($newComment->toArray());
|
||||
}
|
||||
|
||||
public function reply($id, $parent_id)
|
||||
{
|
||||
if ($this->comment_message_reply) {
|
||||
$comment_id = Comment::create(['name' => $this->comment_name_reply, 'message' => $this->comment_message_reply, 'blog_id' => $this->blog_id, 'ip' => request()->ip(), 'user_agent' => request()->userAgent(), 'parent_id' => $id, 'type' => 2, 'image_url' => $this->image_url]);
|
||||
Comment::where('id', $id)->increment('reply');
|
||||
$this->comment_message_reply = null;
|
||||
$this->comment_name_reply = 'کاربر';
|
||||
$this->dispatch('reset');
|
||||
|
||||
$this->storeCommentInCookie($comment_id->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
private function storeCommentInCookie($comment)
|
||||
{
|
||||
$comments = json_decode(Cookie::get('pending_comments', '[]'), true);
|
||||
$comments[] = $comment;
|
||||
Cookie::queue('pending_comments', json_encode($comments), 60 * 24 * 7);
|
||||
}
|
||||
|
||||
public $loadedimage;
|
||||
public $loadedtitle;
|
||||
public $loadedslug;
|
||||
public $loadedpreview;
|
||||
public $loadedContent;
|
||||
public $isLoading = false;
|
||||
|
||||
#[On('loadBlogContent')]
|
||||
public function loadBlogContent($slug)
|
||||
{
|
||||
$this->isLoading = true;
|
||||
$blog = Blog::where('slug', $slug)->first();
|
||||
if ($blog) {
|
||||
$this->loadedContent = $blog->subject;
|
||||
$this->loadedslug = $slug;
|
||||
$this->loadedtitle = $blog->subject;
|
||||
$this->loadedimage = $blog->image;
|
||||
$this->loadedpreview = $blog->preview;
|
||||
|
||||
$this->dispatch('blogContentLoaded', [
|
||||
'slug' => $slug,
|
||||
'title' => $blog->subject,
|
||||
'image' => $blog->image,
|
||||
'preview' => $blog->preview,
|
||||
]);
|
||||
} else {
|
||||
$this->loadedContent = 'محتوا یافت نشد.';
|
||||
}
|
||||
$this->isLoading = false;
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
public function render()
|
||||
{
|
||||
$this->comments = Comment::query()
|
||||
->where('blog_id', $this->blog_id)
|
||||
->where('status', 1)
|
||||
->where('type', 0)
|
||||
->whereHas('blog', function ($q) {
|
||||
$q->where('status', 1);
|
||||
})
|
||||
->get();
|
||||
|
||||
$this->like_status = session()->get('blog-' . $this->blog_id);
|
||||
|
||||
$this->pendingComments = json_decode(Cookie::get('pending_comments', '[]'), true);
|
||||
|
||||
foreach ($this->pendingComments as $key => $comment) {
|
||||
if ($this->blog->id != $comment['blog_id']) {
|
||||
unset($this->pendingComments[$key]);
|
||||
} else {
|
||||
$checkCookie = Comment::where('id', $comment['id'])->first();
|
||||
|
||||
if (!is_null($checkCookie)) {
|
||||
if ($checkCookie->status == 1 || $checkCookie->status == 2) {
|
||||
Cookie::queue(Cookie::forget('pending_comments'));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$pendingCommentsCollection = collect($this->pendingComments)->map(function ($comment) {
|
||||
if (!isset($comment['id'])) {
|
||||
$comment['id'] = 'temp_' . uniqid();
|
||||
}
|
||||
|
||||
$model = new Comment();
|
||||
$model->forceFill($comment);
|
||||
|
||||
return $model;
|
||||
});
|
||||
|
||||
$combinedCollection = $this->comments->merge($pendingCommentsCollection);
|
||||
|
||||
$flattenedArray = $combinedCollection
|
||||
->map(function ($comment) {
|
||||
return $comment->toArray();
|
||||
})
|
||||
->all();
|
||||
|
||||
usort($flattenedArray, function ($a, $b) {
|
||||
return $a['id'] <=> $b['id'];
|
||||
});
|
||||
|
||||
$this->comments = $flattenedArray;
|
||||
|
||||
return view('livewire.home.detail-no-blog');
|
||||
}
|
||||
}
|
||||
233
app/Livewire/Home/DetailPage.php
Normal file
233
app/Livewire/Home/DetailPage.php
Normal file
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Home;
|
||||
|
||||
use App\Models\Ads;
|
||||
use App\Models\Blog;
|
||||
use App\Models\Page;
|
||||
use App\Models\Comment;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Attributes\Rule;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Session;
|
||||
use Illuminate\Support\Facades\Cookie;
|
||||
|
||||
class DetailPage extends Component
|
||||
{
|
||||
public $blog;
|
||||
public $slug;
|
||||
public $blog_id;
|
||||
|
||||
public $like_status;
|
||||
public $comments;
|
||||
public $comment_name = 'کاربر';
|
||||
#[Rule('required')]
|
||||
public $comment_message;
|
||||
public $comment_name_reply = 'کاربر';
|
||||
public $comment_message_reply;
|
||||
public $lastNews;
|
||||
public $lastNews2;
|
||||
public $specialNews;
|
||||
public $questions = [];
|
||||
public $breadcrumbs = [];
|
||||
public $allComments = [];
|
||||
|
||||
#[Rule('required')]
|
||||
public $image_url;
|
||||
|
||||
public $cookie;
|
||||
public $pendingComments = [];
|
||||
public $ads = [];
|
||||
public $ip = '';
|
||||
public $adscount = [];
|
||||
|
||||
public function mount($slug)
|
||||
{
|
||||
$this->blog = Blog::with('questions') ->where('slug', $slug) ->where('status', 1) ->first();
|
||||
|
||||
if (is_null($this->blog)) {
|
||||
$softDeletedBlog = Blog::withTrashed()->where('slug', $slug)->whereNotNull('deleted_at')->first();
|
||||
if (!is_null($softDeletedBlog)) {
|
||||
return abort(410);
|
||||
}
|
||||
return abort(404);
|
||||
}
|
||||
|
||||
$this->blog->increment('views');
|
||||
$this->slug = $slug;
|
||||
$this->blog_id = $this->blog->id;
|
||||
$this->questions = $this->blog->questions;
|
||||
|
||||
$allBlogs = Blog::where('status', 1)->orderBy('published_at', 'desc')->get();
|
||||
|
||||
$this->lastNews = $allBlogs->whereNull('notBlog')->take(5);
|
||||
$this->lastNews2 = $allBlogs->where('notBlog', 1)->take(5);
|
||||
$this->specialNews = $allBlogs->whereNull('notBlog')->where('chosen', 1)->take(5);
|
||||
|
||||
$this->loadAds($slug);
|
||||
}
|
||||
|
||||
protected function loadAds($currentBlogSlug)
|
||||
{
|
||||
$allAds = Ads::where('status', 1)
|
||||
->whereJsonContains('pages', (string)1)
|
||||
->orderBy('orders', 'desc')
|
||||
->get();
|
||||
|
||||
$sidebarAds = $allAds->filter(function($ad) {
|
||||
return collect([9, 10])->contains(function($subcat) use ($ad) {
|
||||
return in_array($subcat, $ad->subcategories ?? []);
|
||||
});
|
||||
});
|
||||
|
||||
$contentAds = $allAds->filter(function($ad) {
|
||||
return collect([13, 14])->contains(function($subcat) use ($ad) {
|
||||
return in_array($subcat, $ad->subcategories ?? []);
|
||||
});
|
||||
});
|
||||
|
||||
$sidebarAds = $this->filterUnauthorizedAds($sidebarAds, $currentBlogSlug);
|
||||
$contentAds = $this->filterUnauthorizedAds($contentAds, $currentBlogSlug);
|
||||
|
||||
$this->ads = [
|
||||
'sidebar' => $sidebarAds->first(),
|
||||
'content' => $contentAds->take(5)
|
||||
];
|
||||
|
||||
$this->adscount = $contentAds->count() + ($sidebarAds->count() > 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
protected function filterUnauthorizedAds($ads, $currentBlogSlug)
|
||||
{
|
||||
return $ads->reject(function ($ad) use ($currentBlogSlug) {
|
||||
if (empty($ad->unauthorized)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$unauthorizedSlugs = $ad->unauthorized;
|
||||
|
||||
if (is_array($unauthorizedSlugs)) {
|
||||
return collect($unauthorizedSlugs)->contains(function ($item) use ($currentBlogSlug) {
|
||||
return (is_array($item) && isset($item['unauthorize']) && $item['unauthorize'] === $currentBlogSlug) ||
|
||||
($item === $currentBlogSlug);
|
||||
});
|
||||
}
|
||||
|
||||
return is_string($unauthorizedSlugs) && $unauthorizedSlugs === $currentBlogSlug;
|
||||
});
|
||||
}
|
||||
|
||||
public function comment()
|
||||
{
|
||||
$this->validate();
|
||||
$comment = Comment::create([
|
||||
'name' => $this->comment_name,
|
||||
'message' => $this->comment_message,
|
||||
'blog_id' => $this->blog_id,
|
||||
'ip' => request()->ip(),
|
||||
'user_agent' => request()->userAgent(),
|
||||
'image_url' => $this->image_url
|
||||
]);
|
||||
|
||||
$this->reset(['comment_message', 'comment_name']);
|
||||
$this->dispatch('reset');
|
||||
$this->storeCommentInCookie($comment->toArray());
|
||||
}
|
||||
|
||||
public function reply($id, $parent_id)
|
||||
{
|
||||
if ($this->comment_message_reply) {
|
||||
$comment = Comment::create([
|
||||
'name' => $this->comment_name_reply,
|
||||
'message' => $this->comment_message_reply,
|
||||
'blog_id' => $this->blog_id,
|
||||
'ip' => request()->ip(),
|
||||
'user_agent' => request()->userAgent(),
|
||||
'parent_id' => $id,
|
||||
'type' => 2,
|
||||
'image_url' => $this->image_url
|
||||
]);
|
||||
|
||||
Comment::where('id', $id)->increment('reply');
|
||||
$this->reset(['comment_message_reply', 'comment_name_reply']);
|
||||
$this->dispatch('reset');
|
||||
$this->storeCommentInCookie($comment->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
private function storeCommentInCookie($comment)
|
||||
{
|
||||
$comments = json_decode(Cookie::get('pending_comments', '[]'), true);
|
||||
$comments[] = $comment;
|
||||
Cookie::queue('pending_comments', json_encode($comments), 60 * 24 * 7);
|
||||
}
|
||||
|
||||
public $loadedimage;
|
||||
public $loadedtitle;
|
||||
public $loadedslug;
|
||||
public $loadedpreview;
|
||||
public $loadedContent;
|
||||
public $isLoading = false;
|
||||
|
||||
#[On('loadBlogContent')]
|
||||
public function loadBlogContent($slug)
|
||||
{
|
||||
$this->isLoading = true;
|
||||
$blog = Blog::where('slug', $slug)->first();
|
||||
|
||||
if ($blog) {
|
||||
$this->loadedContent = $blog->subject;
|
||||
$this->loadedslug = $slug;
|
||||
$this->loadedtitle = $blog->subject;
|
||||
$this->loadedimage = $blog->image;
|
||||
$this->loadedpreview = $blog->preview;
|
||||
|
||||
$this->dispatch('blogContentLoaded', [
|
||||
'slug' => $slug,
|
||||
'title' => $blog->subject,
|
||||
'image' => $blog->image,
|
||||
'preview' => $blog->preview,
|
||||
]);
|
||||
} else {
|
||||
$this->loadedContent = 'محتوا یافت نشد.';
|
||||
}
|
||||
|
||||
$this->isLoading = false;
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
public function render()
|
||||
{
|
||||
$approvedComments = Comment::with('blog')
|
||||
->where('blog_id', $this->blog_id)
|
||||
->where('status', 1)
|
||||
->where('type', 0)
|
||||
->whereHas('blog', fn($q) => $q->where('status', 1))
|
||||
->get();
|
||||
|
||||
$this->pendingComments = collect(json_decode(Cookie::get('pending_comments', '[]'), true))
|
||||
->filter(fn($comment) => $this->blog->id == $comment['blog_id'])
|
||||
->each(function ($comment) {
|
||||
if (isset($comment['id']) && $check = Comment::find($comment['id'])) {
|
||||
if ($check->status == 1 || $check->status == 2) {
|
||||
Cookie::queue(Cookie::forget('pending_comments'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$this->comments = $approvedComments
|
||||
->merge($this->pendingComments->map(function ($comment) {
|
||||
$model = new Comment();
|
||||
$model->forceFill($comment + ['id' => $comment['id'] ?? 'temp_' . uniqid()]);
|
||||
return $model;
|
||||
}))
|
||||
->sortBy('id')
|
||||
->values()
|
||||
->toArray();
|
||||
|
||||
$this->like_status = session()->get('blog-' . $this->blog_id);
|
||||
|
||||
return view('livewire.home.detail-page');
|
||||
}
|
||||
}
|
||||
26
app/Livewire/Home/Dictionary.php
Normal file
26
app/Livewire/Home/Dictionary.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Home;
|
||||
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Layout;
|
||||
use App\Models\Dictionary as ModelDirection;
|
||||
|
||||
class Dictionary extends Component
|
||||
{
|
||||
public $dictionary;
|
||||
|
||||
public function mount($id)
|
||||
{
|
||||
$this->dictionary = ModelDirection::where('id', $id)->first();
|
||||
if (is_null($this->dictionary)) {
|
||||
return abort('404');
|
||||
}
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.app')]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.home.dictionary');
|
||||
}
|
||||
}
|
||||
56
app/Livewire/Home/IndexPage.php
Normal file
56
app/Livewire/Home/IndexPage.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Home;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Category;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Session;
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
|
||||
#[Layout('components.layouts.home.master')]
|
||||
class IndexPage extends Component
|
||||
{
|
||||
public $blogs;
|
||||
public $categories;
|
||||
public $like_status;
|
||||
|
||||
public function mount()
|
||||
{
|
||||
// استفاده از Cache برای کاهش Query های سنگین
|
||||
$this->blogs = Cache::remember('home_blogs', 60, function() {
|
||||
return Blog::query()
|
||||
->where('status', 1)
|
||||
->where('notBlog', null)
|
||||
->whereHas('category', function ($q) {
|
||||
$q->where('status', 1);
|
||||
})
|
||||
->paginate(10); // 10 مطلب در هر صفحه
|
||||
});
|
||||
|
||||
$this->categories = Category::where('status', 1)->get();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
// دیگر نیازی به اجرای دوباره Query در render نیست
|
||||
return view('livewire.home.index-page', [
|
||||
'blogs' => $this->blogs
|
||||
]);
|
||||
}
|
||||
|
||||
public function like($id)
|
||||
{
|
||||
$this->like_status = session()->get('blog-' . $id);
|
||||
|
||||
if ($this->like_status == 'dislike') {
|
||||
Blog::where('id', $id)->increment('likes');
|
||||
} else {
|
||||
Blog::where('id', $id)->decrement('likes');
|
||||
}
|
||||
|
||||
$sesion_value = $this->like_status == 'like' ? 'dislike' : 'like';
|
||||
session()->put('blog-' . $id, $sesion_value);
|
||||
}
|
||||
}
|
||||
118
app/Livewire/Home2.php
Normal file
118
app/Livewire/Home2.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Illuminate\Http\Request;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class Home2 extends Component
|
||||
{
|
||||
|
||||
|
||||
public $image;
|
||||
public $blogs;
|
||||
public $news;
|
||||
public $blogs2;
|
||||
public $blog_array = [];
|
||||
public $news_array = [];
|
||||
public $categories = [];
|
||||
public $categorieNews = [];
|
||||
public $lastNewsPosts = [];
|
||||
public $lastNewsArticles = [];
|
||||
public $lightmags = [];
|
||||
public $lightnews = [];
|
||||
|
||||
public $selectedCategoryPosts = null;
|
||||
public $selectedCategoryNews = null;
|
||||
public $selectedRoutePosts = null;
|
||||
public $selectedRouteNews = null;
|
||||
|
||||
public function mount(Request $request)
|
||||
{
|
||||
$allBlogs = Blog::where('status', 1)->orderBy('published_at', 'desc')->get();
|
||||
|
||||
$this->lightmags = $allBlogs->whereNull('notBlog')->take(50);
|
||||
|
||||
$this->lightnews = $allBlogs->where('notBlog', 1)->take(50);
|
||||
$allCategroy = Category::where('status', 1)->get();
|
||||
$this->blogs2 = Blog::where('status', 1)->where('notBlog', null)->where('chosen', 1)->orderBy('created_at', 'desc')->get()->take(5);
|
||||
|
||||
$this->lastNewsPosts = $allBlogs->whereNull('notBlog')->take(4);
|
||||
$this->lastNewsArticles = $allBlogs->where('notBlog', 1)->take(4);
|
||||
|
||||
$this->blogs = $allBlogs->where('chosen', 0)->where('notBlog', null);
|
||||
$this->news = $allBlogs->where('chosen', 0)->where('notBlog', 1);
|
||||
$this->categories = $allCategroy->where('parent_below', null)->where('parent_id', null)->where('parent', null);
|
||||
$this->categorieNews = $allCategroy->where('is_news', 1)->where('parent_below', null)->where('parent_id', '!=', null)->where('parent', null);
|
||||
}
|
||||
|
||||
public function selectCategory($categoryId, $type = 'posts')
|
||||
{
|
||||
$this->selectedCategoryPosts = $categoryId;
|
||||
$category = Category::find($categoryId);
|
||||
if (isset($category)) {
|
||||
$this->selectedRoutePosts = route('CategoryBlog.index', ['slug' => $category->slug]) . "/";
|
||||
}
|
||||
}
|
||||
public function selectCategoryNews($categoryId, $type = 'news')
|
||||
{
|
||||
$this->selectedCategoryNews = $categoryId;
|
||||
$category = Category::find($categoryId);
|
||||
if (isset($category)) {
|
||||
$this->selectedRouteNews = route('NewsCategory.show', ['slug' => $category->slug]) . "/";
|
||||
}
|
||||
}
|
||||
|
||||
public function resetCategory($type = 'posts')
|
||||
{
|
||||
$this->selectedRoutePosts = null;
|
||||
$this->selectedCategoryPosts = null;
|
||||
}
|
||||
|
||||
public function resetCategoryNews($type = 'news')
|
||||
{
|
||||
$this->selectedRouteNews = null;
|
||||
$this->selectedCategoryNews = null;
|
||||
}
|
||||
|
||||
public function getCategoryItems($categoryId = null, $type = 'posts')
|
||||
{
|
||||
if ($type === 'posts') {
|
||||
$query = Blog::where('status', 1)->whereNull('notBlog');
|
||||
|
||||
if ($categoryId) {
|
||||
$query->where(function($q) use ($categoryId) {
|
||||
$q->where('category_id', $categoryId)
|
||||
->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->orderByDesc('published_at')
|
||||
->take(4)
|
||||
->get();
|
||||
} else {
|
||||
$query = Blog::where('status', 1)->where('notBlog', 1);
|
||||
|
||||
if ($categoryId) {
|
||||
$query->where(function($q) use ($categoryId) {
|
||||
$q->where('category_id', $categoryId)
|
||||
->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
});
|
||||
}
|
||||
|
||||
return $query->orderByDesc('published_at')
|
||||
->take(4)
|
||||
->get();
|
||||
}
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.app2')]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.home2');
|
||||
}
|
||||
}
|
||||
68
app/Livewire/Images.php
Normal file
68
app/Livewire/Images.php
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Image;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class Images extends Component
|
||||
{
|
||||
public $images = [];
|
||||
public $imagesblog = [];
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$blogs = Blog::all();
|
||||
foreach ($blogs as $blog) {
|
||||
$this->checkImageMountForBlog($blog->id);
|
||||
}
|
||||
$this->images = $this->imagesblog;
|
||||
}
|
||||
|
||||
public function checkImageMountForBlog($blogId)
|
||||
{
|
||||
$blog = Blog::find($blogId);
|
||||
|
||||
if (!$blog) {
|
||||
return;
|
||||
}
|
||||
|
||||
$imageName = $blog->image;
|
||||
|
||||
$content = $blog->content;
|
||||
|
||||
if (empty($content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pattern = '/<img[^>]+src="([^">]+)"/i';
|
||||
preg_match_all($pattern, $content, $matches);
|
||||
$extractedImages = $matches[1] ?? [];
|
||||
|
||||
$extractedImages = array_map(function ($imageUrl) {
|
||||
$parts = explode('/images/', $imageUrl);
|
||||
return end($parts);
|
||||
}, $extractedImages);
|
||||
|
||||
$extractedImages = array_filter($extractedImages, function ($image) {
|
||||
return Storage::disk('public')->exists($image);
|
||||
});
|
||||
if ($imageName) {
|
||||
if (Storage::disk('public')->exists($imageName)) {
|
||||
$this->imagesblog[] = $imageName;
|
||||
}
|
||||
}
|
||||
foreach ($extractedImages as $image) {
|
||||
$this->imagesblog[] = $image;
|
||||
}
|
||||
}
|
||||
|
||||
#[Layout('components.layouts.panel.master')]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.images');
|
||||
}
|
||||
}
|
||||
43
app/Livewire/Partials/Form.php
Normal file
43
app/Livewire/Partials/Form.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Partials;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Models\UserCounselingRequests;
|
||||
|
||||
class Form extends Component
|
||||
{
|
||||
public $full_name;
|
||||
public $phone_number;
|
||||
public $description;
|
||||
public $textSuccess = '';
|
||||
|
||||
public function counselingRequest()
|
||||
{
|
||||
if (is_null($this->full_name) && is_null($this->phone_number) && is_null($this->description)) {
|
||||
return [
|
||||
'status' => 'error',
|
||||
'message' => 'اطلاعات را به صورت کامل تکمیل کنید.',
|
||||
];
|
||||
}
|
||||
$phone = convertPersianToEnglishNumber($this->phone_number);
|
||||
$phone = ltrim($phone, '0');
|
||||
$phone = substr($phone, 0, 2) == '98' ? substr($phone, 2) : $phone;
|
||||
$phone = str_replace('+98', '', $phone);
|
||||
$phone = '0' . $phone;
|
||||
|
||||
UserCounselingRequests::create([
|
||||
'full_name' => $this->full_name,
|
||||
'phone_number' => $phone,
|
||||
'counseling_text' => $this->description,
|
||||
]);
|
||||
|
||||
$this->textSuccess = 'پیام شما با موفقیت دریافت شد.';
|
||||
return $this->dispatch('ticket_ok');
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.partials.form');
|
||||
}
|
||||
}
|
||||
191
app/Livewire/Partials/Header.php
Normal file
191
app/Livewire/Partials/Header.php
Normal file
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Partials;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Category;
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class Header extends Component
|
||||
{
|
||||
public $search = '';
|
||||
public $showMenu = false;
|
||||
public $activeTab = 'posts';
|
||||
public $selectedCategory = null;
|
||||
public $blogsSearchs = [];
|
||||
public $expandedCategory = null;
|
||||
public $categoryBlogs = [];
|
||||
public $loadedCategories = [];
|
||||
public $loadingStates = [];
|
||||
public $dynamicBlogs = [];
|
||||
public $lastNewsPosts2 = [];
|
||||
|
||||
// دادههای اصلی
|
||||
public $blogs;
|
||||
public $categories;
|
||||
|
||||
protected $cacheKey = 'header_all_data_v4';
|
||||
protected $cacheExpiration = 60; // 1 دقیقه
|
||||
|
||||
public function mount()
|
||||
{
|
||||
$this->loadAllData();
|
||||
}
|
||||
|
||||
protected function loadAllData()
|
||||
{
|
||||
$data = Cache::remember($this->cacheKey, $this->cacheExpiration, function () {
|
||||
return $this->fetchAllData();
|
||||
});
|
||||
|
||||
$this->blogs = $data['blogs'];
|
||||
$this->categories = $data['categories_full'];
|
||||
$this->lastNewsPosts2 = $data['lastNewsPosts2'];
|
||||
}
|
||||
|
||||
protected function fetchAllData(): array
|
||||
{
|
||||
// فقط 10 پست کافی است
|
||||
$blogs = Blog::where('status', 1)
|
||||
->select('id', 'subject', 'slug', 'image', 'published_at', 'category_id', 'notBlog', 'category_array')
|
||||
->orderByDesc('published_at')
|
||||
->take(10)
|
||||
->get();
|
||||
|
||||
$categories = Category::where('status', 1)
|
||||
->with(['children' => fn($q) => $q->orderByDesc('priority')])
|
||||
->orderByDesc('priority')
|
||||
->get();
|
||||
|
||||
$posts = $blogs->whereNull('notBlog');
|
||||
$articles = $blogs->where('notBlog', 1);
|
||||
|
||||
return [
|
||||
'blogs' => $blogs,
|
||||
'lastNewsPosts2' => $posts->take(10),
|
||||
'categories_full' => $categories,
|
||||
'categoriesNotBlog' => $categories->whereNotNull('parent_id')->whereNull('parent'),
|
||||
'categoriesNotBlogM' => $categories->where('is_news', 1)->whereNull('parent_below')->whereNotNull('parent_id'),
|
||||
];
|
||||
}
|
||||
|
||||
public function loadCategoryData($categoryId)
|
||||
{
|
||||
if (isset($this->categoryBlogs[$categoryId])) {
|
||||
$this->expandedCategory = $categoryId;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->expandedCategory = $categoryId;
|
||||
$this->loadingStates[$categoryId] = true;
|
||||
$this->dynamicBlogs[$categoryId] = [];
|
||||
|
||||
if (!in_array($categoryId, $this->loadedCategories)) {
|
||||
$this->loadedCategories[] = $categoryId;
|
||||
}
|
||||
|
||||
$blogs = Cache::remember("category_blogs_{$categoryId}", 300, function () use ($categoryId) {
|
||||
return Blog::where('status', 1)
|
||||
->select('id', 'subject', 'slug', 'image', 'published_at')
|
||||
->where(function ($q) use ($categoryId) {
|
||||
$q->where('category_id', $categoryId)
|
||||
->orWhereJsonContains('category_array', (string)$categoryId);
|
||||
})
|
||||
->orderByDesc('published_at')
|
||||
->take(4)
|
||||
->get();
|
||||
});
|
||||
|
||||
$this->categoryBlogs[$categoryId] = $blogs;
|
||||
$this->dynamicBlogs[$categoryId] = $blogs->toArray();
|
||||
$this->loadingStates[$categoryId] = false;
|
||||
}
|
||||
|
||||
public function getLastNewsPosts($notBlog)
|
||||
{
|
||||
$this->activeTab = $notBlog ? 'news' : 'posts';
|
||||
$this->selectedCategory = null;
|
||||
|
||||
$source = $notBlog
|
||||
? $this->blogs->where('notBlog', 1)
|
||||
: $this->blogs->whereNull('notBlog');
|
||||
|
||||
$this->lastNewsPosts2 = $source->take(10);
|
||||
}
|
||||
|
||||
public function searchBox()
|
||||
{
|
||||
if (empty($this->search)) {
|
||||
$this->showMenu = false;
|
||||
$this->blogsSearchs = [];
|
||||
return;
|
||||
}
|
||||
|
||||
$search = str_replace(['', ' '], ' ', $this->search);
|
||||
$searchVariants = [$search, str_replace(' ', '***', $search)];
|
||||
|
||||
$source = $this->activeTab === 'posts'
|
||||
? $this->blogs->whereNull('notBlog')
|
||||
: $this->blogs->where('notBlog', 1);
|
||||
|
||||
if ($this->selectedCategory) {
|
||||
$source = $source->filter(fn($b) =>
|
||||
$b->category_id == $this->selectedCategory ||
|
||||
in_array($this->selectedCategory, $b->category_array ?? [])
|
||||
);
|
||||
}
|
||||
|
||||
$this->blogsSearchs = $source->filter(function ($blog) use ($searchVariants) {
|
||||
$subject = $blog->subject;
|
||||
$excerpt = $blog->excerpt ?? '';
|
||||
|
||||
foreach ($searchVariants as $variant) {
|
||||
if (str_contains($subject, $variant) || str_contains($excerpt, $variant)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
})
|
||||
->sortByDesc(function ($blog) use ($searchVariants) {
|
||||
foreach ($searchVariants as $i => $variant) {
|
||||
if (str_contains($blog->subject, $variant)) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
return 10;
|
||||
})
|
||||
->take(10)
|
||||
->values();
|
||||
|
||||
$this->showMenu = $this->blogsSearchs->isNotEmpty();
|
||||
}
|
||||
|
||||
public function selectCategory($categoryId = null)
|
||||
{
|
||||
$this->selectedCategory = $categoryId;
|
||||
$this->searchBox();
|
||||
}
|
||||
|
||||
public function resetCategory()
|
||||
{
|
||||
$this->selectedCategory = null;
|
||||
$this->searchBox();
|
||||
}
|
||||
|
||||
public function refreshsearch()
|
||||
{
|
||||
$this->reset('blogsSearchs');
|
||||
$this->searchBox();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.partials.header', [
|
||||
'rootCategories' => $this->categories->whereNull('parent_id')->whereNull('parent_below')->where('is_news', 0),
|
||||
'lastNewsPosts' => $this->blogs->whereNull('notBlog')->take(10),
|
||||
]);
|
||||
}
|
||||
}
|
||||
20
app/Livewire/Partials/ThreeCol.php
Normal file
20
app/Livewire/Partials/ThreeCol.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Partials;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Livewire\Attributes\Lazy;
|
||||
|
||||
class ThreeCol extends Component
|
||||
{
|
||||
public $category = [] ;
|
||||
|
||||
|
||||
|
||||
#[Lazy]
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.partials.three-col');
|
||||
}
|
||||
}
|
||||
13
app/Livewire/Reateost.php
Normal file
13
app/Livewire/Reateost.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Reateost extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.reateost');
|
||||
}
|
||||
}
|
||||
32
app/Livewire/Search.php
Normal file
32
app/Livewire/Search.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\Post;
|
||||
use Livewire\Component;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\WithPagination;
|
||||
use Livewire\WithoutUrlPagination;
|
||||
|
||||
class Search extends Component
|
||||
{
|
||||
use WithPagination, WithoutUrlPagination;
|
||||
|
||||
public $search = '';
|
||||
|
||||
public $showMenu = false;
|
||||
|
||||
public function refreshsearch()
|
||||
{
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
$kName = htmlspecialchars_decode($this->search, ENT_QUOTES);
|
||||
$search = str_replace('', '***', $kName);
|
||||
$this->showMenu = true;
|
||||
return view('livewire.search', ['blogsSearchs' => Blog::where('content', 'like', '%' . $search . '%')->paginate(5)]);
|
||||
}
|
||||
}
|
||||
13
app/Livewire/Tools/Coments.php
Normal file
13
app/Livewire/Tools/Coments.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Tools;
|
||||
|
||||
use Livewire\Component;
|
||||
|
||||
class Coments extends Component
|
||||
{
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.tools.coments');
|
||||
}
|
||||
}
|
||||
50
app/Livewire/Tools/HomeComments.php
Normal file
50
app/Livewire/Tools/HomeComments.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Tools;
|
||||
|
||||
use App\Models\Comment;
|
||||
use Livewire\Attributes\Rule;
|
||||
use Livewire\Component;
|
||||
|
||||
class HomeComments extends Component
|
||||
{
|
||||
|
||||
|
||||
public Comment $comments;
|
||||
public Comment $comment;
|
||||
|
||||
#[Rule('required')]
|
||||
public $comment_name;
|
||||
#[Rule('required')]
|
||||
public $comment_message;
|
||||
public $comment_name_reply;
|
||||
public $comment_message_reply;
|
||||
|
||||
public $blog_id;
|
||||
public $comment_id;
|
||||
|
||||
public function mount($comments,$comment,$blog_id)
|
||||
{
|
||||
$this->comments = $comments;
|
||||
$this->comment = $comment;
|
||||
$this->blog_id = $blog_id;
|
||||
// dd($this->comment);
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.tools.home-comments');
|
||||
}
|
||||
|
||||
public function reply($id,$parent_id)
|
||||
{
|
||||
if ($this->comment_message_reply && $this->comment_name_reply){
|
||||
|
||||
Comment::create(['name'=>$this->comment_name_reply,'message'=>$this->comment_message_reply,'blog_id'=>$this->blog_id,'ip'=>request()->ip(),'user_agent'=>request()->userAgent(),'parent_id'=>$id,'type'=>2]);
|
||||
Comment::where('id',$parent_id)->increment('reply');
|
||||
$this->comment_message_reply=null;
|
||||
$this->comment_name_reply=null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
19
app/Models/AdCategory.php
Normal file
19
app/Models/AdCategory.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\AdSubcategory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class AdCategory extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = ['name', 'slug'];
|
||||
|
||||
public function subcategories()
|
||||
{
|
||||
return $this->hasMany(AdSubcategory::class);
|
||||
}
|
||||
}
|
||||
19
app/Models/AdSubcategory.php
Normal file
19
app/Models/AdSubcategory.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\AdCategory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class AdSubcategory extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $fillable = ['ad_category_id', 'name', 'slug'];
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(AdCategory::class);
|
||||
}
|
||||
}
|
||||
24
app/Models/Address.php
Normal file
24
app/Models/Address.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\Province;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Address extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = "address";
|
||||
protected $guarded = [];
|
||||
|
||||
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
}
|
||||
30
app/Models/Ads.php
Normal file
30
app/Models/Ads.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\AdSubcategory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Ads extends Model
|
||||
{
|
||||
use HasFactory, SoftDeletes;
|
||||
|
||||
protected $table = 'ads';
|
||||
protected $guarded = [];
|
||||
|
||||
protected $casts = [
|
||||
'pages' => 'array',
|
||||
'subcategories' => 'array',
|
||||
'unauthorized' => 'array',
|
||||
'status' => 'boolean'
|
||||
];
|
||||
|
||||
public function getSubcategoryNamesAttribute()
|
||||
{
|
||||
if (empty($this->subcategories)) {
|
||||
return collect();
|
||||
}
|
||||
return AdSubcategory::whereIn('id', $this->subcategories) ->get() ->pluck('name');
|
||||
}
|
||||
}
|
||||
15
app/Models/BlockedWord.php
Normal file
15
app/Models/BlockedWord.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class BlockedWord extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'blocked_words';
|
||||
protected $guarded = [];
|
||||
|
||||
}
|
||||
251
app/Models/Blog.php
Normal file
251
app/Models/Blog.php
Normal file
@@ -0,0 +1,251 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Image;
|
||||
use App\Models\Heading;
|
||||
use App\Models\Question;
|
||||
use App\Models\CommonWord;
|
||||
use App\Models\BlogSetObject;
|
||||
use App\Models\CommonWordBlog;
|
||||
use App\Models\Blog as ModelBlog;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Blog extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $table = 'blogs';
|
||||
protected $fillable = [
|
||||
'content',
|
||||
'preview',
|
||||
'changefreq',
|
||||
'priority',
|
||||
'image',
|
||||
'status',
|
||||
'subject',
|
||||
'description',
|
||||
'reed_time',
|
||||
'views',
|
||||
'category_array',
|
||||
'category_id',
|
||||
'chosen',
|
||||
'slug',
|
||||
'user_id', 'imageCheck', 'headingCheck', 'notBlog', 'content_id', 'published_at', 'grade', 'content_errors'];
|
||||
|
||||
protected $casts = [
|
||||
'category_array' => 'array',
|
||||
'published_at' => 'datetime',
|
||||
];
|
||||
|
||||
protected $appends = ['computed_published_at'];
|
||||
|
||||
protected static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::addGlobalScope('filtered', function ($query) {
|
||||
$query->where(function ($query) {
|
||||
$query
|
||||
->whereNotNull('content_id')
|
||||
->where('blogs.id', function ($subQuery) {
|
||||
$subQuery->selectRaw('MAX(id)')->from('blogs as blog_edits')->whereColumn('blog_edits.content_id', 'blogs.content_id');
|
||||
})
|
||||
->orWhere(function ($query) {
|
||||
$query->whereNull('content_id')->whereNotIn('blogs.id', function ($subQuery) {
|
||||
$subQuery->select('content_id')->from('blogs')->whereNotNull('content_id');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public function getComputedPublishedAtAttribute()
|
||||
{
|
||||
if ($this->published_at) {
|
||||
return $this->published_at;
|
||||
}
|
||||
|
||||
if (!is_null($this->content_id)) {
|
||||
$blog = DB::table('blogs')->where('id', $this->content_id)->first();
|
||||
if ($blog->published_at == null) {
|
||||
$blog->published_at = $blog->created_at;
|
||||
}
|
||||
return $blog->published_at ?? '2021-08-02 12:05:01';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getPublishAtAttribute()
|
||||
{
|
||||
if ($this->published_at) {
|
||||
return $this->published_at;
|
||||
}
|
||||
|
||||
if (!is_null($this->content_id)) {
|
||||
$blog = DB::table('blogs')->where('id', $this->content_id)->first();
|
||||
if ($blog->published_at == null) {
|
||||
$blog->published_at = $blog->created_at;
|
||||
}
|
||||
return $blog->published_at ?? '2021-08-02 12:05:01';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public function parent()
|
||||
{
|
||||
return $this->belongsTo(ModelBlog::class, 'content_id', 'id');
|
||||
}
|
||||
|
||||
public function children()
|
||||
{
|
||||
return $this->hasMany(ModelBlog::class, 'content_id', 'id');
|
||||
}
|
||||
|
||||
public function headers()
|
||||
{
|
||||
return $this->hasMany(Heading::class);
|
||||
}
|
||||
|
||||
public function headings()
|
||||
{
|
||||
return $this->hasMany(Heading::class);
|
||||
}
|
||||
|
||||
public function images()
|
||||
{
|
||||
return $this->hasMany(Image::class);
|
||||
}
|
||||
|
||||
public function latestChild()
|
||||
{
|
||||
return $this->children()->orderBy('created_at', 'desc')->first();
|
||||
}
|
||||
|
||||
public function editsAsContent()
|
||||
{
|
||||
return $this->hasMany(Blog::class, 'content_id', 'id');
|
||||
}
|
||||
|
||||
public function latestVersion()
|
||||
{
|
||||
return $this->hasMany(ModelBlog::class, 'content_id', 'id')->orderBy('created_at', 'desc')->limit(1);
|
||||
}
|
||||
|
||||
public function categories()
|
||||
{
|
||||
return Category::whereIn('id', $this->category_array)->get();
|
||||
}
|
||||
|
||||
|
||||
public function commonWords()
|
||||
{
|
||||
return $this->belongsToMany(CommonWord::class, 'common_word_blog')
|
||||
->using(CommonWordBlog::class)
|
||||
->withPivot('count')
|
||||
->withTimestamps();
|
||||
}
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
|
||||
public function opinions()
|
||||
{
|
||||
return $this->hasMany(UserOpinion::class, 'blog_id', 'id');
|
||||
}
|
||||
|
||||
public function comments()
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'blog_id', 'id');
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function getStatusClassAttribute()
|
||||
{
|
||||
return $this->status == 0 ? 'bg-orange-500' : 'bg-ahrom';
|
||||
}
|
||||
|
||||
public function getStatusTextAttribute()
|
||||
{
|
||||
return $this->status == 0 ? 'پیشنویس' : 'انتشار';
|
||||
}
|
||||
|
||||
public function getStatusImageAttribute()
|
||||
{
|
||||
if ($this->imageCheck == 1) {
|
||||
return 'bg-[#FFA500]';
|
||||
} elseif ($this->imageCheck == 2) {
|
||||
return 'bg-green-500';
|
||||
} else {
|
||||
return 'bg-slate-500';
|
||||
}
|
||||
}
|
||||
|
||||
public function getStatusHeadAttribute()
|
||||
{
|
||||
if ($this->headingCheck == 1) {
|
||||
return 'bg-[#FFA500]';
|
||||
} elseif ($this->headingCheck == 2) {
|
||||
return 'bg-green-500';
|
||||
} else {
|
||||
return 'bg-slate-500';
|
||||
}
|
||||
}
|
||||
|
||||
public function questions()
|
||||
{
|
||||
return $this->hasMany(Question::class);
|
||||
}
|
||||
|
||||
public function getContentAttribute($value)
|
||||
{
|
||||
return str_replace('***', '‌', $value);
|
||||
}
|
||||
|
||||
public function getPreviewAttribute($value)
|
||||
{
|
||||
return str_replace('***', '‌', $value);
|
||||
}
|
||||
|
||||
public function setContentAttribute($value)
|
||||
{
|
||||
$this->attributes['content'] = str_replace('‌', '***', $value);
|
||||
}
|
||||
|
||||
public function setPreviewAttribute($value)
|
||||
{
|
||||
$this->attributes['preview'] = str_replace('‌', '***', $value);
|
||||
}
|
||||
|
||||
public function scopeOrderByPublished($query, $direction = 'desc')
|
||||
{
|
||||
return $query->orderBy('computed_published_at', $direction);
|
||||
}
|
||||
|
||||
public function setObjects()
|
||||
{
|
||||
return $this->hasMany(BlogSetObject::class, 'blog_id', 'id');
|
||||
}
|
||||
|
||||
public function sectionImages()
|
||||
{
|
||||
return $this->hasMany(BlogSectionImage::class);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
35
app/Models/BlogSectionImage.php
Normal file
35
app/Models/BlogSectionImage.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class BlogSectionImage extends Model
|
||||
{
|
||||
use HasFactory, softDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'blog_id',
|
||||
'h2_text',
|
||||
'image_src',
|
||||
'status',
|
||||
'reason',
|
||||
];
|
||||
|
||||
public function blog()
|
||||
{
|
||||
return $this->belongsTo(Blog::class);
|
||||
}
|
||||
|
||||
public function approve(): void
|
||||
{
|
||||
$this->update(['status' => 'approved']);
|
||||
}
|
||||
|
||||
public function reject($reason = null): void
|
||||
{
|
||||
$this->update(['status' => 'reject', 'reason' => $reason]);
|
||||
}
|
||||
}
|
||||
29
app/Models/BlogSetObject.php
Normal file
29
app/Models/BlogSetObject.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\CategoryObject;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class BlogSetObject extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'blog_id',
|
||||
'category_object_id',
|
||||
'title',
|
||||
'content',
|
||||
'order'
|
||||
];
|
||||
|
||||
public function blog(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Blog::class);
|
||||
}
|
||||
|
||||
public function categoryObject(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(CategoryObject::class);
|
||||
}
|
||||
}
|
||||
231
app/Models/Category.php
Normal file
231
app/Models/Category.php
Normal file
@@ -0,0 +1,231 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\CategoryObject;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Models\Category as Modelcategory;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = [
|
||||
'title',
|
||||
'slug',
|
||||
'image_url',
|
||||
'status',
|
||||
'is_news',
|
||||
'parent_id',
|
||||
'parent_below',
|
||||
'color',
|
||||
'priority',
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'is_news' => 'boolean',
|
||||
'status' => 'boolean'
|
||||
];
|
||||
|
||||
|
||||
public function getAllDescendantIds(): array
|
||||
{
|
||||
$ids = collect([$this->id]);
|
||||
|
||||
$children = Category::where('parent_id', $this->id)->get();
|
||||
foreach ($children as $child) {
|
||||
$ids = $ids->merge($child->getAllDescendantIds());
|
||||
}
|
||||
|
||||
$subcategories = Category::where('parent_below', $this->id)->get();
|
||||
foreach ($subcategories as $subcategory) {
|
||||
$ids = $ids->merge($subcategory->getAllDescendantIds());
|
||||
}
|
||||
|
||||
return $ids->unique()->all();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function getHierarchicalCategoriesForFilter()
|
||||
{
|
||||
$allCategories = [];
|
||||
$rootCategories = self::whereNull('parent_id')
|
||||
->whereNull('parent_below')
|
||||
->with(['children', 'subcategories'])
|
||||
->orderBy('is_news', 'desc')
|
||||
->orderBy('title')->get();
|
||||
|
||||
foreach ($rootCategories as $item) {
|
||||
self::addCategoryToHierarchyList($item, 0, $allCategories);
|
||||
}
|
||||
return $allCategories;
|
||||
}
|
||||
|
||||
private static function addCategoryToHierarchyList(Category $category, int $level, array &$list)
|
||||
{
|
||||
$category->level = $level;
|
||||
$list[] = $category;
|
||||
|
||||
$descendants = $category->children->merge($category->subcategories)->sortBy('title');
|
||||
|
||||
foreach ($descendants as $descendant) {
|
||||
self::addCategoryToHierarchyList($descendant, $level + 1, $list);
|
||||
}
|
||||
}
|
||||
|
||||
public function blogs()
|
||||
{
|
||||
return $this->hasMany(Blog::class);
|
||||
}
|
||||
|
||||
public function mag_news($categoryId = null)
|
||||
{
|
||||
$id = $categoryId ?? $this->id;
|
||||
return Blog::query()
|
||||
->where('status', 1)
|
||||
->where('notBlog', 1)
|
||||
->where('category_array', 'like', '%"' . $id . '"%')
|
||||
->orderByDesc('published_at')
|
||||
->get()->take(4);
|
||||
}
|
||||
|
||||
public function mag_blogs($limit = 4)
|
||||
{
|
||||
return Blog::query()
|
||||
->where('status', 1)
|
||||
->whereNull('notBlog')
|
||||
->where(function($query) {
|
||||
$query->where('category_id', $this->id)
|
||||
->orWhereJsonContains('category_array', (string)$this->id);
|
||||
})
|
||||
->orderByDesc('published_at')
|
||||
->take($limit)
|
||||
->get();
|
||||
}
|
||||
|
||||
public function hasBlogs()
|
||||
{
|
||||
return Blog::where('status', 1)
|
||||
->whereNull('notBlog')
|
||||
->where(function($query) {
|
||||
$query->where('category_id', $this->id)
|
||||
->orWhereJsonContains('category_array', (string)$this->id);
|
||||
})
|
||||
->exists();
|
||||
}
|
||||
|
||||
|
||||
public function blog_category()
|
||||
{
|
||||
$blogs = Blog::where('notBlog', 1)->orderBy('created_at', 'desc') ->get();
|
||||
return $blogs->filter(function($blog) {
|
||||
$categoryArray = $blog->category_array ;
|
||||
return isset($categoryArray[0]) && $categoryArray[0] == $this->id;
|
||||
});
|
||||
}
|
||||
|
||||
public function child()
|
||||
{
|
||||
return $this->hasOne(Modelcategory::class , 'parent_id' , 'id');
|
||||
}
|
||||
|
||||
public function isRoot(): bool
|
||||
{
|
||||
return is_null($this->parent_id) && is_null($this->parent_below);
|
||||
}
|
||||
|
||||
public static function getNewsRootCategories()
|
||||
{
|
||||
return self::where('is_news', true)
|
||||
->whereNull('parent_id')
|
||||
->whereNull('parent_below')
|
||||
->get();
|
||||
}
|
||||
|
||||
public static function getArticleRootCategories()
|
||||
{
|
||||
return self::where('is_news', false)
|
||||
->whereNull('parent_id')
|
||||
->whereNull('parent_below')
|
||||
->get();
|
||||
}
|
||||
|
||||
public function getFullHierarchy()
|
||||
{
|
||||
$hierarchy = collect([$this]);
|
||||
if ($this->parent()->exists()) {
|
||||
$hierarchy = $this->parent()->first()->getFullHierarchy()->merge($hierarchy);
|
||||
}
|
||||
if ($this->mainCategory()->exists()) {
|
||||
$hierarchy = $this->mainCategory()->first()->getFullHierarchy()->merge($hierarchy);
|
||||
}
|
||||
return $hierarchy->unique('id');
|
||||
}
|
||||
|
||||
public function children(): HasMany
|
||||
{
|
||||
return $this->hasMany(Category::class, 'parent_id')->orderByDesc('priority');
|
||||
}
|
||||
|
||||
// Recursive relation to load all descendants infinitely
|
||||
public function childrenRecursive()
|
||||
{
|
||||
return $this->children()->with('childrenRecursive');
|
||||
}
|
||||
|
||||
public function subcategories(): HasMany
|
||||
{
|
||||
return $this->hasMany(Category::class, 'parent_below')->orderByDesc('priority');
|
||||
}
|
||||
|
||||
|
||||
public function parent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function fparent(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class, 'parent_id');
|
||||
}
|
||||
|
||||
|
||||
public function mainCategory(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class, 'parent_below');
|
||||
}
|
||||
|
||||
|
||||
public function getBreadcrumbAttribute(): string
|
||||
{
|
||||
$breadcrumbs = [];
|
||||
|
||||
if ($this->parent_id) {
|
||||
$parent = $this->parent ?? Category::find($this->parent_id);
|
||||
if ($parent) {
|
||||
$breadcrumbs[] = $parent->breadcrumb;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->parent_below) {
|
||||
$mainCategory = $this->mainCategory ?? Category::find($this->parent_below);
|
||||
if ($mainCategory) {
|
||||
$breadcrumbs[] = $mainCategory->breadcrumb;
|
||||
}
|
||||
}
|
||||
|
||||
$breadcrumbs[] = $this->title;
|
||||
|
||||
return implode(' > ', array_unique($breadcrumbs));
|
||||
}
|
||||
|
||||
public function categoryObjects(): HasMany
|
||||
{
|
||||
return $this->hasMany(CategoryObject::class);
|
||||
}
|
||||
}
|
||||
|
||||
20
app/Models/CategoryObject.php
Normal file
20
app/Models/CategoryObject.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Category;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class CategoryObject extends Model
|
||||
{
|
||||
protected $fillable = [
|
||||
'category_id',
|
||||
'subject'
|
||||
];
|
||||
|
||||
public function category(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Category::class);
|
||||
}
|
||||
}
|
||||
101
app/Models/Comment.php
Normal file
101
app/Models/Comment.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Blog;
|
||||
use App\Models\User;
|
||||
use App\Models\Comment as Modelself;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
use SoftDeletes;
|
||||
|
||||
protected $fillable = ['message', 'ip', 'user_agent', 'status', 'name', 'blog_id', 'seen', 'parent_id', 'type', 'likes', 'admin' , 'image_url'];
|
||||
|
||||
public function blog()
|
||||
{
|
||||
return $this->belongsTo(Blog::class);
|
||||
}
|
||||
|
||||
public function admin()
|
||||
{
|
||||
return $this->belongsTo(User::class, 'admin', 'id');
|
||||
}
|
||||
|
||||
protected $appends = [
|
||||
'sub_comments',
|
||||
];
|
||||
|
||||
public function getSubCommentsAttribute()
|
||||
{
|
||||
return $this->other()->get();
|
||||
}
|
||||
|
||||
public function other()
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'parent_id', 'id');
|
||||
}
|
||||
|
||||
public function hasPendingReplies()
|
||||
{
|
||||
foreach ($this->other as $reply) {
|
||||
if ($reply->status === 0 || $reply->hasPendingReplies()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function scopeParent(Builder $query): void
|
||||
{
|
||||
$query->where('type', 0);
|
||||
}
|
||||
|
||||
public function scopeAnswer(Builder $query): void
|
||||
{
|
||||
$query->where('type', 1);
|
||||
}
|
||||
|
||||
public function scopeReply(Builder $query): void
|
||||
{
|
||||
$query->where('type', 2);
|
||||
}
|
||||
|
||||
public function getTypeCheckAttribute()
|
||||
{
|
||||
if ($this->type == 0) {
|
||||
return 'کامنت';
|
||||
} else if ($this->type == 1) {
|
||||
return 'جواب';
|
||||
} else if ($this->type == 2) {
|
||||
return 'ریپلای';
|
||||
}
|
||||
return 'نامشخص';
|
||||
}
|
||||
|
||||
public function getTypeStatusAttribute()
|
||||
{
|
||||
if ($this->status == 0) {
|
||||
return 'در انتظار بررسی';
|
||||
} else if ($this->status == 1) {
|
||||
return 'تایید';
|
||||
} else if ($this->status == 2) {
|
||||
return 'رد';
|
||||
}
|
||||
return 'نا مشخص';
|
||||
}
|
||||
public function getTypeStatuscolorAttribute()
|
||||
{
|
||||
if ($this->status == 0) {
|
||||
return 'text-slate-400';
|
||||
} else if ($this->status == 1) {
|
||||
return ' text-green-500';
|
||||
} else if ($this->status == 2) {
|
||||
return 'text-red-500';
|
||||
}
|
||||
return 'text-blue-400';
|
||||
}
|
||||
}
|
||||
85
app/Models/CommonWord.php
Normal file
85
app/Models/CommonWord.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class CommonWord extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'commonwords';
|
||||
protected $guarded = [];
|
||||
|
||||
const TYPE_SINGLE = 1;
|
||||
const TYPE_DOUBLE = 2;
|
||||
const TYPE_TRIPLE = 3;
|
||||
const TYPE_QUAD = 4;
|
||||
|
||||
const STATUS_ACTIVE = 1;
|
||||
const STATUS_BLOCKED = 0;
|
||||
|
||||
protected $appends = ['article_count', 'is_blocked'];
|
||||
|
||||
public function blogs()
|
||||
{
|
||||
return $this->belongsToMany(Blog::class, 'common_word_blog')
|
||||
->using(CommonWordBlog::class)
|
||||
->withPivot(['count', 'is_linked'])
|
||||
->withTimestamps()
|
||||
->withoutGlobalScopes();
|
||||
}
|
||||
|
||||
public function blockedWords()
|
||||
{
|
||||
return $this->hasOne(BlockedWord::class, 'word', 'title');
|
||||
}
|
||||
|
||||
public function getArticleCountAttribute()
|
||||
{
|
||||
return $this->blogs()->count();
|
||||
}
|
||||
|
||||
public function getIsBlockedAttribute()
|
||||
{
|
||||
return $this->status == self::STATUS_BLOCKED;
|
||||
}
|
||||
|
||||
public function getLinkedArticlesCountAttribute()
|
||||
{
|
||||
return $this->blogs()
|
||||
->wherePivot('is_linked', true)
|
||||
->count();
|
||||
}
|
||||
|
||||
public function scopeSingleWords($query)
|
||||
{
|
||||
return $query->where('word_type', self::TYPE_SINGLE);
|
||||
}
|
||||
|
||||
public function scopeDoubleWords($query)
|
||||
{
|
||||
return $query->where('word_type', self::TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
public function scopeTripleWords($query)
|
||||
{
|
||||
return $query->where('word_type', self::TYPE_TRIPLE);
|
||||
}
|
||||
|
||||
public function scopeQuadWords($query)
|
||||
{
|
||||
return $query->where('word_type', self::TYPE_QUAD);
|
||||
}
|
||||
|
||||
public function scopeActive($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_ACTIVE);
|
||||
}
|
||||
|
||||
public function scopeBlocked($query)
|
||||
{
|
||||
return $query->where('status', self::STATUS_BLOCKED);
|
||||
}
|
||||
}
|
||||
49
app/Models/CommonWordBlog.php
Normal file
49
app/Models/CommonWordBlog.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||
|
||||
class CommonWordBlog extends Pivot
|
||||
{
|
||||
protected $table = 'common_word_blog';
|
||||
|
||||
protected $fillable = [
|
||||
'common_word_id',
|
||||
'blog_id',
|
||||
'count',
|
||||
'is_linked',
|
||||
];
|
||||
|
||||
public $timestamps = true;
|
||||
|
||||
protected $casts = [
|
||||
'count' => 'integer',
|
||||
'is_linked' => 'boolean',
|
||||
];
|
||||
|
||||
public function commonWord()
|
||||
{
|
||||
return $this->belongsTo(CommonWord::class);
|
||||
}
|
||||
|
||||
public function blog()
|
||||
{
|
||||
return $this->belongsTo(Blog::class);
|
||||
}
|
||||
|
||||
public function scopeLinked($query)
|
||||
{
|
||||
return $query->where('is_linked', true);
|
||||
}
|
||||
|
||||
public function scopeNotLinked($query)
|
||||
{
|
||||
return $query->where('is_linked', false);
|
||||
}
|
||||
|
||||
public function scopeWithHighFrequency($query, $minCount = 5)
|
||||
{
|
||||
return $query->where('count', '>=', $minCount);
|
||||
}
|
||||
}
|
||||
18
app/Models/Dictionary.php
Normal file
18
app/Models/Dictionary.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Dictionary extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = "Dictionary";
|
||||
protected $guarded = [];
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
23
app/Models/FinancialInfo.php
Normal file
23
app/Models/FinancialInfo.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class FinancialInfo extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'financial_infos';
|
||||
|
||||
protected $fillable = [
|
||||
'user_id', 'confirm'
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
}
|
||||
15
app/Models/Frequently_asked.php
Normal file
15
app/Models/Frequently_asked.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Frequently_asked extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = "frequently_asked _uestions";
|
||||
protected $guarded = [];
|
||||
|
||||
}
|
||||
26
app/Models/Heading.php
Normal file
26
app/Models/Heading.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Heading extends Model
|
||||
{
|
||||
use HasFactory ;
|
||||
|
||||
protected $table = "headings";
|
||||
protected $guarded = [];
|
||||
|
||||
protected $casts = [
|
||||
'content_expert_message' => 'array',
|
||||
];
|
||||
|
||||
|
||||
public function blog()
|
||||
{
|
||||
return $this->belongsTo(Blog::class);
|
||||
}
|
||||
|
||||
}
|
||||
10
app/Models/History.php
Normal file
10
app/Models/History.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class History extends Model
|
||||
{
|
||||
protected $fillable=['user_agent','ip','blog_link','opened_at','user_id','blog_id'];
|
||||
}
|
||||
24
app/Models/Image.php
Normal file
24
app/Models/Image.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Models\Blog;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Image extends Model
|
||||
{
|
||||
use HasFactory , SoftDeletes;
|
||||
|
||||
protected $table = "images";
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
|
||||
public function blog()
|
||||
{
|
||||
return $this->belongsTo(Blog::class);
|
||||
}
|
||||
|
||||
}
|
||||
358
app/Models/IndexPage.php
Normal file
358
app/Models/IndexPage.php
Normal file
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
|
||||
namespace App\Livewire\Panel;
|
||||
|
||||
use DOMXPath;
|
||||
use DOMDocument;
|
||||
use App\Models\Blog;
|
||||
use App\Models\Image;
|
||||
use App\Models\Heading;
|
||||
use Livewire\Component;
|
||||
use App\Models\Category;
|
||||
use Carbon\Carbon;
|
||||
use Livewire\Attributes\On;
|
||||
use Livewire\Attributes\Layout;
|
||||
use Livewire\Attributes\Url;
|
||||
use Livewire\WithPagination;
|
||||
use Livewire\WithoutUrlPagination;
|
||||
use Illuminate\Database\Eloquent\JsonEncodingException;
|
||||
|
||||
class IndexPage extends Component
|
||||
{
|
||||
|
||||
|
||||
use WithPagination, WithoutUrlPagination;
|
||||
|
||||
public $blogs = [];
|
||||
public $categories;
|
||||
public $headings;
|
||||
public $comment_message = [];
|
||||
public $currentCategory = 'all';
|
||||
|
||||
public function checkHeadingMount()
|
||||
{
|
||||
$blogs = Blog::orderBy('id', 'Desc')->get();
|
||||
|
||||
foreach ($blogs as $blog) {
|
||||
$existingHeading = Heading::where('blog_id', $blog->id)->first();
|
||||
|
||||
if ($existingHeading) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$htmlContent = $blog->content;
|
||||
|
||||
$dom = new DOMDocument();
|
||||
@$dom->loadHTML(mb_convert_encoding($htmlContent, 'HTML-ENTITIES', 'UTF-8'));
|
||||
|
||||
$xpath = new DOMXPath($dom);
|
||||
|
||||
$headings = $xpath->query('//h1 | //h2 | //h3 | //h4 | //h5 | //h6');
|
||||
|
||||
foreach ($headings as $heading) {
|
||||
$headingText = $heading->nodeValue;
|
||||
$tagType = $heading->nodeName;
|
||||
|
||||
$nextNode = $heading->nextSibling;
|
||||
while ($nextNode && !in_array($nextNode->nodeName, ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'])) {
|
||||
$nextNode = $nextNode->nextSibling;
|
||||
}
|
||||
if(strlen($headingText) > 3){
|
||||
Heading::create([
|
||||
'blog_id' => $blog->id,
|
||||
'content' => $headingText ,
|
||||
'typeTag' => $tagType,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function approveHeading($headingId)
|
||||
{
|
||||
$heading = Heading::find($headingId);
|
||||
$heading->update(['status' => 1]);
|
||||
// ...
|
||||
}
|
||||
|
||||
public function rejectHeading($headingId)
|
||||
{
|
||||
$heading = Heading::find($headingId);
|
||||
$heading->update(['status' => 2]);
|
||||
// ...
|
||||
}
|
||||
|
||||
public function approveHeadingexpert($headingId)
|
||||
{
|
||||
$heading = Heading::find($headingId);
|
||||
$heading->update(['content_expert_status' => 1]);
|
||||
// ...
|
||||
}
|
||||
|
||||
public function rejectHeadingexpert($headingId)
|
||||
{
|
||||
$heading = Heading::find($headingId);
|
||||
$heading->update(['content_expert_status' => 2]);
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
public function makeMessage($headingId, $key)
|
||||
{
|
||||
$heading = Heading::find($headingId);
|
||||
|
||||
if ($heading) {
|
||||
$textmessage = $this->comment_message[$key] ?? null;
|
||||
|
||||
if ($textmessage) {
|
||||
if (!mb_check_encoding($textmessage, 'UTF-8')) {
|
||||
$textmessage = utf8_encode($textmessage);
|
||||
}
|
||||
|
||||
$time = Carbon::now();
|
||||
|
||||
$headingMessageBefore = $heading->content_expert_message;
|
||||
|
||||
if (empty($headingMessageBefore)) {
|
||||
$headingMessageBefore = [];
|
||||
} elseif (!is_array($headingMessageBefore)) {
|
||||
$headingMessageBefore = [$headingMessageBefore];
|
||||
}
|
||||
|
||||
$headingMessageBefore[] = ['message' => $textmessage, 'time' => $time];
|
||||
|
||||
$headingMessageBefore = array_map(function ($message) {
|
||||
if (!mb_check_encoding($message['message'], 'UTF-8')) {
|
||||
$message['message'] = utf8_encode($message['message']);
|
||||
}
|
||||
return $message;
|
||||
}, $headingMessageBefore);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function headingStatus( $value, $value2)
|
||||
{
|
||||
$blog = Blog::find($value);
|
||||
if(!is_null($blog)){
|
||||
|
||||
$blog->update([
|
||||
'headingCheck' => $value2 ,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public function imageStatus($value , $value2)
|
||||
{
|
||||
$blog = Blog::find($value);
|
||||
if(!is_null($blog)){
|
||||
|
||||
$blog->update([
|
||||
'imageCheck' => $value2 ,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public $imagesblog = [];
|
||||
public $wModalsOpened = [];
|
||||
public $loadedBlogs = [];
|
||||
|
||||
public function checkImageMountForBlog($blogId, $modalid)
|
||||
{
|
||||
if (isset($this->loadedBlogs[$blogId])) {
|
||||
$this->wModalsOpened[] = $modalid;
|
||||
$this->dispatch('openthemodal', $modalid);
|
||||
return;
|
||||
}
|
||||
|
||||
$blog = Blog::find($blogId);
|
||||
if (!$blog) {
|
||||
return;
|
||||
}
|
||||
|
||||
$imageName = $blog->image;
|
||||
$existingImage = Image::where('blog_id', $blogId)
|
||||
->where('imagePath', $imageName)
|
||||
->first();
|
||||
|
||||
if (is_null($existingImage)) {
|
||||
Image::create([
|
||||
'blog_id' => $blogId,
|
||||
'imagePath' => $imageName,
|
||||
'status' => 0
|
||||
]);
|
||||
}
|
||||
|
||||
$content = $blog->content;
|
||||
if (empty($content)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$pattern = '/<img[^>]+src="([^">]+)"/i';
|
||||
preg_match_all($pattern, $content, $matches);
|
||||
$extractedImages = $matches[1] ?? [];
|
||||
|
||||
$extractedImages = array_map(function ($imageUrl) {
|
||||
$parts = explode('/images/', $imageUrl);
|
||||
return end($parts);
|
||||
}, $extractedImages);
|
||||
|
||||
$existingImages = Image::where('blog_id', $blogId)->get();
|
||||
$existingImagePaths = $existingImages->pluck('imagePath')->toArray();
|
||||
|
||||
$imagesToDelete = array_diff($existingImagePaths, $extractedImages);
|
||||
if (!empty($imagesToDelete)) {
|
||||
Image::where('blog_id', $blogId)
|
||||
->whereIn('imagePath', $imagesToDelete)
|
||||
->delete();
|
||||
}
|
||||
|
||||
foreach ($extractedImages as $imagePath) {
|
||||
$existingImage = Image::where('blog_id', $blogId)
|
||||
->where('imagePath', $imagePath)
|
||||
->first();
|
||||
if (is_null($existingImage)) {
|
||||
Image::create([
|
||||
'blog_id' => $blogId,
|
||||
'imagePath' => $imagePath,
|
||||
'status' => 0
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$this->loadedBlogs[$blogId] = true;
|
||||
|
||||
$this->wModalsOpened[] = $modalid;
|
||||
$this->imagesblog = $blog->images;
|
||||
$this->dispatch('openthemodal', $modalid);
|
||||
}
|
||||
|
||||
|
||||
public function approveImage($imageId)
|
||||
{
|
||||
$image = Image::find($imageId);
|
||||
$image->update(['status' => 1]);
|
||||
|
||||
}
|
||||
|
||||
public function rejectImage($imageId)
|
||||
{
|
||||
$image = Image::find($imageId);
|
||||
$image->update(['status' => 2]);
|
||||
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
{
|
||||
$blog = Blog::where("id", $id)->first();
|
||||
if($blog){
|
||||
$blog->delete();
|
||||
}
|
||||
}
|
||||
|
||||
public function status($id , $likey = false)
|
||||
{
|
||||
|
||||
$blog= Blog::find($id);
|
||||
if($blog->status==1){
|
||||
$blog->update(["status"=>0]);
|
||||
}else{
|
||||
$blog->update(["status"=>1]);
|
||||
}
|
||||
}
|
||||
|
||||
public function setCategory($category)
|
||||
{
|
||||
$this->currentCategory = $category;
|
||||
$this->resetPage();
|
||||
}
|
||||
|
||||
|
||||
public function refactor($id)
|
||||
{
|
||||
$blog = Blog::withTrashed()->find($id);
|
||||
|
||||
if ($blog && $blog->trashed()) {
|
||||
$blog->restore();
|
||||
return response()->json(['message' => 'Blog restored successfully!']);
|
||||
} else {
|
||||
return response()->json(['message' => 'Blog not found or is not soft deleted'], 404);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function mount(){
|
||||
$this->checkHeadingMount();
|
||||
}
|
||||
|
||||
|
||||
#[Layout('components.layouts.panel.master')]
|
||||
public function render()
|
||||
{
|
||||
$query = Blog::orderBy('created_at', 'Desc');
|
||||
|
||||
|
||||
|
||||
|
||||
if ($this->currentCategory == 'publish') {
|
||||
$query->where('status', 1);
|
||||
} elseif ($this->currentCategory == 'draft') {
|
||||
$query->where('status', 0);
|
||||
} elseif ($this->currentCategory == 'justtrashedlaravel') {
|
||||
$query->onlyTrashed();
|
||||
} elseif ($this->currentCategory !== 'all') {
|
||||
$query->whereHas('category', function ($q) {
|
||||
$q->where('id', $this->currentCategory);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$paginatedBlogs = $query->paginate(10);
|
||||
|
||||
|
||||
$this->categories = Category::all();
|
||||
|
||||
|
||||
|
||||
$headings = Heading::all();
|
||||
|
||||
|
||||
$blogHeadingsMap = [];
|
||||
|
||||
foreach ($paginatedBlogs as $blog) {
|
||||
if (!isset($blogHeadingsMap[$blog->id])) {
|
||||
$blogHeadingsMap[$blog->id] = [
|
||||
'blog' => $blog,
|
||||
'headings' => [],
|
||||
'images' => []
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($headings as $head) {
|
||||
if (isset($blogHeadingsMap[$head->blog_id])) {
|
||||
$blogHeadingsMap[$head->blog_id]['headings'][] = $head;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$this->blogs = array_values($blogHeadingsMap);
|
||||
dd($this->blogs);
|
||||
return view('livewire.panel.index-page', [
|
||||
'blogs' => $this->blogs,
|
||||
'paginatedBlogs' => $paginatedBlogs,
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
19
app/Models/Keyword.php
Normal file
19
app/Models/Keyword.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Keyword extends Model
|
||||
{
|
||||
use HasFactory , SoftDeletes;
|
||||
protected $table = 'keywords';
|
||||
|
||||
protected $fillable=['name', 'status' , 'slug' ,'blogs' ];
|
||||
protected $casts = [
|
||||
'blogs' => 'array',
|
||||
];
|
||||
|
||||
}
|
||||
19
app/Models/NameList.php
Normal file
19
app/Models/NameList.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class NameList extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'name_lists';
|
||||
|
||||
protected $fillable = [
|
||||
'name'
|
||||
];
|
||||
|
||||
public $timestamps = false;
|
||||
}
|
||||
|
||||
16
app/Models/NationalCodeCityName.php
Normal file
16
app/Models/NationalCodeCityName.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class NationalCodeCityName extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'national_code_city_names';
|
||||
|
||||
protected $fillable = [
|
||||
'code', 'city'
|
||||
];
|
||||
}
|
||||
16
app/Models/Newslist.php
Normal file
16
app/Models/Newslist.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Newslist extends Model
|
||||
{
|
||||
protected $table = "news_list";
|
||||
protected $guarded = [];
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
}
|
||||
|
||||
17
app/Models/Page.php
Normal file
17
app/Models/Page.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class Page extends Model
|
||||
{
|
||||
use HasFactory , SoftDeletes;
|
||||
protected $table = 'pages';
|
||||
protected $guarded = [];
|
||||
|
||||
|
||||
|
||||
}
|
||||
15
app/Models/PriceDataHistoryLt.php
Normal file
15
app/Models/PriceDataHistoryLt.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
class PriceDataHistoryLt extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = "price_data_history_lt";
|
||||
protected $guarded = [];
|
||||
|
||||
}
|
||||
14
app/Models/Question.php
Normal file
14
app/Models/Question.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Question extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = "questions";
|
||||
protected $guarded = [];
|
||||
}
|
||||
76
app/Models/User.php
Normal file
76
app/Models/User.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
// use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use App\Models\Role;
|
||||
use App\Models\Address;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
|
||||
class User extends Authenticatable
|
||||
{
|
||||
/** @use HasFactory<\Database\Factories\UserFactory> */
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'phone_number', 'token', 'invite_code', 'mobile_verified_at', 'national_code',
|
||||
'issue_place', 'confirm_national_code', 'confirm', 'info_status', 'full_confirm',
|
||||
'is_real', 'joined_from' , 'first_name' , 'last_name' , 'father_name' ,'birth_day' ,
|
||||
'full_name' , 'picture'
|
||||
];
|
||||
|
||||
// روابط
|
||||
public function financialInfo()
|
||||
{
|
||||
return $this->hasOne(FinancialInfo::class);
|
||||
}
|
||||
|
||||
public function address()
|
||||
{
|
||||
return $this->belongsTo(Address::class);
|
||||
}
|
||||
public function role()
|
||||
{
|
||||
return $this->belongsTo(Role::class);
|
||||
}
|
||||
|
||||
public function scoreUser()
|
||||
{
|
||||
return $this->hasOne(ScoreUser::class);
|
||||
}
|
||||
|
||||
public function scoreTransactions()
|
||||
{
|
||||
return $this->hasMany(ScoreTransaction::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for serialization.
|
||||
*
|
||||
* @var list<string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get the attributes that should be cast.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
protected function casts(): array
|
||||
{
|
||||
return [
|
||||
'email_verified_at' => 'datetime',
|
||||
'password' => 'hashed',
|
||||
];
|
||||
}
|
||||
}
|
||||
12
app/Models/UserOpinion.php
Normal file
12
app/Models/UserOpinion.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class UserOpinion extends Model
|
||||
{
|
||||
protected $table = 'user_opinions';
|
||||
|
||||
protected $fillable = ['like','user_agent','ip','blog_id','user_id'];
|
||||
}
|
||||
24
app/Providers/AppServiceProvider.php
Normal file
24
app/Providers/AppServiceProvider.php
Normal file
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
26
app/Providers/AuthServiceProvider.php
Normal file
26
app/Providers/AuthServiceProvider.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
// use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The model to policy mappings for the application.
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
//
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
19
app/Providers/BroadcastServiceProvider.php
Normal file
19
app/Providers/BroadcastServiceProvider.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\Facades\Broadcast;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class BroadcastServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap any application services.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
Broadcast::routes();
|
||||
|
||||
require base_path('routes/channels.php');
|
||||
}
|
||||
}
|
||||
38
app/Providers/EventServiceProvider.php
Normal file
38
app/Providers/EventServiceProvider.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Auth\Events\Registered;
|
||||
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
|
||||
class EventServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The event to listener mappings for the application.
|
||||
*
|
||||
* @var array<class-string, array<int, class-string>>
|
||||
*/
|
||||
protected $listen = [
|
||||
Registered::class => [
|
||||
SendEmailVerificationNotification::class,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Register any events for your application.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if events and listeners should be automatically discovered.
|
||||
*/
|
||||
public function shouldDiscoverEvents(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
40
app/Providers/RouteServiceProvider.php
Normal file
40
app/Providers/RouteServiceProvider.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to your application's "home" route.
|
||||
*
|
||||
* Typically, users are redirected here after authentication.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, and other route configuration.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
}
|
||||
467
app/helper.php
Normal file
467
app/helper.php
Normal file
@@ -0,0 +1,467 @@
|
||||
<?php
|
||||
|
||||
use Carbon\Carbon;
|
||||
use App\Models\User;
|
||||
use App\Models\Package;
|
||||
use App\Models\Setting;
|
||||
use App\Models\Inventory;
|
||||
use App\Models\Discountcode;
|
||||
use App\Models\SignedDocument;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Process;
|
||||
use Morilog\Jalali\Jalalian;
|
||||
|
||||
if (!function_exists('generateRandomToken')) {
|
||||
function generateRandomToken($length = 64)
|
||||
{
|
||||
if ($length % 2 != 0) {
|
||||
$length++;
|
||||
}
|
||||
|
||||
$bytes = openssl_random_pseudo_bytes($length / 2);
|
||||
|
||||
$token = bin2hex($bytes);
|
||||
|
||||
return $token;
|
||||
};
|
||||
}
|
||||
|
||||
if (!function_exists('convertPersianToEnglishNumber')) {
|
||||
function convertPersianToEnglishNumber($number)
|
||||
{
|
||||
$number = str_replace('۰', '0', $number);
|
||||
$number = str_replace('۱', '1', $number);
|
||||
$number = str_replace('۲', '2', $number);
|
||||
$number = str_replace('۳', '3', $number);
|
||||
$number = str_replace('۴', '4', $number);
|
||||
$number = str_replace('۵', '5', $number);
|
||||
$number = str_replace('۶', '6', $number);
|
||||
$number = str_replace('۷', '7', $number);
|
||||
$number = str_replace('۸', '8', $number);
|
||||
$number = str_replace('۹', '9', $number);
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function convertEnglishToPersianNumber($number)
|
||||
{
|
||||
$number = str_replace('0', '۰', $number);
|
||||
$number = str_replace('1', '۱', $number);
|
||||
$number = str_replace('2', '۲', $number);
|
||||
$number = str_replace('3', '۳', $number);
|
||||
$number = str_replace('4', '۴', $number);
|
||||
$number = str_replace('5', '۵', $number);
|
||||
$number = str_replace('6', '۶', $number);
|
||||
$number = str_replace('7', '۷', $number);
|
||||
$number = str_replace('8', '۸', $number);
|
||||
$number = str_replace('9', '۹', $number);
|
||||
|
||||
return $number;
|
||||
}
|
||||
|
||||
function priceFormat($price)
|
||||
{
|
||||
$price = number_format($price, 0, '.', ','); // 1,000,000/00
|
||||
$price = convertEnglishToPersianNumber($price);
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('generatefilename')) {
|
||||
function generatefilename($name)
|
||||
{
|
||||
$year = Carbon::now()->year;
|
||||
$month = Carbon::now()->month;
|
||||
$day = Carbon::now()->day;
|
||||
$hour = Carbon::now()->hour;
|
||||
$minute = Carbon::now()->minute;
|
||||
$second = Carbon::now()->second;
|
||||
$microsecond = Carbon::now()->microsecond;
|
||||
|
||||
return $year . '_' . $month . '_' . $day . '_' . $hour . '_' . $minute . '_' . $second . '_' . $microsecond . '_' . $name;
|
||||
};
|
||||
}
|
||||
|
||||
if(!function_exists('priceFormat')){
|
||||
function priceFormat($price)
|
||||
{
|
||||
$price = number_format($price, 0, '.', ','); // 1,000,000/00
|
||||
$price = convertEnglishToPersianNumber($price);
|
||||
return $price;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!function_exists('last_of_route_name')){
|
||||
function last_of_route_name($route_name)
|
||||
{
|
||||
$route=explode('.',$route_name);
|
||||
return end($route);
|
||||
}}
|
||||
|
||||
if(!function_exists('image_name')){
|
||||
function image_name($original_name)
|
||||
{
|
||||
return time().str_shuffle(random_int(1000000000000000,9999999999999999).str()->random(16)).'_'.$original_name;
|
||||
}}
|
||||
|
||||
if(!function_exists('runPython')){
|
||||
function runPython($file_name,$input)
|
||||
{
|
||||
// code with laravel process
|
||||
$process = Process::input($input)->env( ['SYSTEMROOT' => getenv('SYSTEMROOT'),'PATH' => getenv("PATH")])->run('python '.base_path('Python/'.$file_name));
|
||||
$process->exitCode();
|
||||
if (!$process->successful()){
|
||||
return -1;
|
||||
// $error=$process->errorOutput();
|
||||
// dd($error);
|
||||
}
|
||||
return $process->output();
|
||||
|
||||
}}
|
||||
|
||||
if(!function_exists('status')){
|
||||
function status($status)
|
||||
{
|
||||
if($status==1){
|
||||
return '<span class="text-red-500">ناموفق</span>';
|
||||
}
|
||||
if($status==2){
|
||||
return '<span class="text-green-500">موفق</span>';
|
||||
}
|
||||
if($status==0){
|
||||
return '<span style="color: #facc15 !important;">نامشخص</span>';
|
||||
}
|
||||
return '';
|
||||
}}
|
||||
|
||||
if(!function_exists('jalaliDate')){
|
||||
function jalaliDate($date, $format = '%A - %Y/%m/%d',$fa=true)
|
||||
{
|
||||
$result = Jalalian::forge($date)->format($format);
|
||||
if(!$fa){
|
||||
return $result;
|
||||
}
|
||||
return convertEnglishToPersianNumber($result);
|
||||
}}
|
||||
|
||||
if(!function_exists('convertPersianToEnglishNumber')){
|
||||
function convertPersianToEnglishNumber($number)
|
||||
{
|
||||
$number = str_replace('۰', '0', $number);
|
||||
$number = str_replace('۱', '1', $number);
|
||||
$number = str_replace('۲', '2', $number);
|
||||
$number = str_replace('۳', '3', $number);
|
||||
$number = str_replace('۴', '4', $number);
|
||||
$number = str_replace('۵', '5', $number);
|
||||
$number = str_replace('۶', '6', $number);
|
||||
$number = str_replace('۷', '7', $number);
|
||||
$number = str_replace('۸', '8', $number);
|
||||
$number = str_replace('۹', '9', $number);
|
||||
|
||||
return $number;
|
||||
}}
|
||||
|
||||
if(!function_exists('convertArabicToEnglishNumber')){
|
||||
function convertArabicToEnglishNumber($number)
|
||||
{
|
||||
$number = str_replace('۰', '0', $number);
|
||||
$number = str_replace('۱', '1', $number);
|
||||
$number = str_replace('۲', '2', $number);
|
||||
$number = str_replace('۳', '3', $number);
|
||||
$number = str_replace('۴', '4', $number);
|
||||
$number = str_replace('۵', '5', $number);
|
||||
$number = str_replace('۶', '6', $number);
|
||||
$number = str_replace('۷', '7', $number);
|
||||
$number = str_replace('۸', '8', $number);
|
||||
$number = str_replace('۹', '9', $number);
|
||||
|
||||
return $number;
|
||||
}}
|
||||
|
||||
if(!function_exists('convertEnglishToPersianNumber')){
|
||||
function convertEnglishToPersianNumber($number)
|
||||
{
|
||||
$number = str_replace('0', '۰', $number);
|
||||
$number = str_replace('1', '۱', $number);
|
||||
$number = str_replace('2', '۲', $number);
|
||||
$number = str_replace('3', '۳', $number);
|
||||
$number = str_replace('4', '۴', $number);
|
||||
$number = str_replace('5', '۵', $number);
|
||||
$number = str_replace('6', '۶', $number);
|
||||
$number = str_replace('7', '۷', $number);
|
||||
$number = str_replace('8', '۸', $number);
|
||||
$number = str_replace('9', '۹', $number);
|
||||
|
||||
return $number;
|
||||
}}
|
||||
|
||||
if(!function_exists('priceFormat')){
|
||||
function priceFormat($price)
|
||||
{
|
||||
$price = number_format($price, 0, '/', ','); // 1,000,000/00
|
||||
$price = convertEnglishToPersianNumber($price);
|
||||
return $price;
|
||||
}}
|
||||
|
||||
if(!function_exists('fa2en')){
|
||||
function fa2en($str) {
|
||||
return strtr($str, array('۰'=>'0', '۱'=>'1', '۲'=>'2', '۳'=>'3', '۴'=>'4', '۵'=>'5', '۶'=>'6', '۷'=>'7', '۸'=>'8', '۹'=>'9'));
|
||||
}}
|
||||
|
||||
if(!function_exists('home_comments')){
|
||||
function home_comments($comments,$comment,$blog_id)
|
||||
{
|
||||
$result=null;
|
||||
|
||||
|
||||
foreach ($comments->other as $other_comment) {
|
||||
$result .= '
|
||||
<div style="margin-right: 40px" class="mr-10 relative" >
|
||||
<div class="" >
|
||||
';
|
||||
if ($other_comment->status==1) {
|
||||
$result.='
|
||||
|
||||
<div class="">
|
||||
<div >
|
||||
<div class=" flex flex-col gap-3 m-3">
|
||||
<div x-data="{reply_id:0}">
|
||||
<div class="relative rounded-xl p-5 flex gap-4 ">
|
||||
<div class="flex ">
|
||||
|
||||
<img style="width: 40px; height: 40px" wire:ignore alt="" class="size-10 rounded-full"
|
||||
src="' . profile($other_comment->type == 1) . '">
|
||||
</div>
|
||||
<div class="flex flex-col gap-5">
|
||||
|
||||
<div class="flex gap-1">
|
||||
<span class=" text_class font-bold text-[#E1EAF9]"> '.$other_comment->name.'</span>
|
||||
<span class=" text_class font-bold text-[#E1EAF9]"> |</span>
|
||||
<span class=" text_class font-bold text-[#E1EAF9]"> '.how_long($other_comment->created_at).'</span>
|
||||
|
||||
</div>
|
||||
<p class="text-[#B4BBC7]"> ' . $other_comment->message . '</p>
|
||||
|
||||
<div class="flex gap-10">
|
||||
|
||||
<div class="flex flex-col justify-end">
|
||||
|
||||
<button type="button" @click="reply_id=' . $other_comment->id . '">
|
||||
<div class="flex gap-1 items-center content-center">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="16"
|
||||
viewBox="0 0 16.000000 16.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,16.000000) scale(0.100000,-0.100000)"
|
||||
fill="#E1EAF9" stroke="none">
|
||||
<path d="M131 123 c-2 -29 -27 -53 -56 -53 -18 0 -23 4 -18 16 8 21 -16 14
|
||||
-31 -8 -7 -12 -6 -21 3 -32 17 -20 32 -21 25 -1 -5 12 2 15 29 15 42 0 60 19
|
||||
54 57 -3 21 -4 22 -6 6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="text-xs text-[#E1EAF9]">پاسخ</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div wire:ignore.self x-data="{like_color:like_color_session(\''.session()->get('comment-'.$other_comment->id).'\')}" class="flex flex-col justify-end">
|
||||
|
||||
<button @click="like_color=comment_like_color(like_color)" wire:click="like_comment(' . $other_comment->id . ')" type="button" >
|
||||
<div class="flex gap-1 items-center content-center">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="12" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
:fill="like_color" fill="#E1EAF9" stroke="none">
|
||||
<path d="M1262 4830 c-319 -40 -586 -171 -812 -399 -203 -204 -325 -420 -395
|
||||
-701 -124 -487 -34 -967 264 -1418 191 -289 438 -554 891 -958 288 -257 1167
|
||||
-1007 1210 -1032 40 -24 55 -27 140 -27 85 0 100 3 140 27 43 25 924 776 1210
|
||||
1032 455 406 700 670 891 958 298 451 388 931 264 1418 -70 281 -192 497 -395
|
||||
701 -202 203 -418 320 -701 380 -142 30 -404 33 -528 5 -346 -75 -611 -248
|
||||
-853 -556 l-28 -35 -27 35 c-239 302 -500 475 -833 551 -99 23 -327 33 -438
|
||||
19z m334 -305 c284 -50 529 -214 723 -485 33 -47 74 -103 90 -126 74 -104 228
|
||||
-104 302 0 16 23 57 79 90 126 265 370 634 544 1036 489 446 -61 794 -373 927
|
||||
-832 105 -363 59 -744 -132 -1087 -160 -287 -427 -588 -892 -1005 -225 -201
|
||||
-1171 -1015 -1180 -1015 -10 0 -952 811 -1180 1015 -715 641 -997 1041 -1065
|
||||
1510 -44 303 19 629 172 886 230 387 678 599 1109 524z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<span :style="`color:${like_color}`" class="text-xs text-[#E1EAF9] ">پسندیدم</span>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="absolute top-1/2 left-2 flex gap-1 items-center content-center">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="12" viewBox="0 0 512.000000 512.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
|
||||
<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
|
||||
fill="#E1EAF9" stroke="none">
|
||||
<path d="M1262 4830 c-319 -40 -586 -171 -812 -399 -203 -204 -325 -420 -395
|
||||
-701 -124 -487 -34 -967 264 -1418 191 -289 438 -554 891 -958 288 -257 1167
|
||||
-1007 1210 -1032 40 -24 55 -27 140 -27 85 0 100 3 140 27 43 25 924 776 1210
|
||||
1032 455 406 700 670 891 958 298 451 388 931 264 1418 -70 281 -192 497 -395
|
||||
701 -202 203 -418 320 -701 380 -142 30 -404 33 -528 5 -346 -75 -611 -248
|
||||
-853 -556 l-28 -35 -27 35 c-239 302 -500 475 -833 551 -99 23 -327 33 -438
|
||||
19z m334 -305 c284 -50 529 -214 723 -485 33 -47 74 -103 90 -126 74 -104 228
|
||||
-104 302 0 16 23 57 79 90 126 265 370 634 544 1036 489 446 -61 794 -373 927
|
||||
-832 105 -363 59 -744 -132 -1087 -160 -287 -427 -588 -892 -1005 -225 -201
|
||||
-1171 -1015 -1180 -1015 -10 0 -952 811 -1180 1015 -715 641 -997 1041 -1065
|
||||
1510 -44 303 19 629 172 886 230 387 678 599 1109 524z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="text-[#E1EAF9]">' . $other_comment->likes . '</span>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div x-cloak @click.outside="reply_id=0" x-show="reply_id==' . $other_comment->id . '" class="mt-5">
|
||||
<form >
|
||||
<div class="border-2 border-black flex flex-col h-60 p-3 rounded-xl">
|
||||
<input style="border-color: transparent; box-shadow: none;" x-model="name_reply" wire:model="comment_name_reply" class="bg-transparent border border-black focus-ring focus:outline-none focus:ring-0 my-3 p-3 resize-none ring-0 rounded-2xl text-black "
|
||||
placeholder="نام شما">
|
||||
<textarea style="border-color: transparent; box-shadow: none;" x-model="message_reply" wire:model="comment_message_reply"
|
||||
class="bg-transparent border border-black focus-ring focus:outline-none focus:ring-0 my-3 p-3 resize-none ring-0 rounded-2xl text-black"
|
||||
placeholder="نظر شما"></textarea>
|
||||
<div class="flex justify-end gap-3">
|
||||
|
||||
|
||||
<button @click="reply_id=0"
|
||||
type="button"
|
||||
class="text-white p-2 px-4 w-max text-sm rounded"> لغو پاسخ
|
||||
</button>
|
||||
|
||||
<button @click="show_notif(name_reply.length>0 && message_reply.length>0),reply_id=0"
|
||||
wire:click="reply(' . $other_comment->id . ',' . $comment->id . ')"
|
||||
:disabled="!(name_reply.length>0 && message_reply.length>0)"
|
||||
class="bg-[#F47A53] p-2 text-white text-sm px-4 w-max rounded-xl"> ارسال نظر
|
||||
</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
';
|
||||
}
|
||||
$result.='
|
||||
</div>';
|
||||
|
||||
if ($other_comment->status==1) {
|
||||
$result.='<hr>';
|
||||
}
|
||||
|
||||
$result.='
|
||||
|
||||
<div>
|
||||
|
||||
|
||||
'.home_comments($other_comment,$comment,$blog_id).'
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
';
|
||||
}
|
||||
return $result;
|
||||
}}
|
||||
|
||||
|
||||
if (!function_exists('panel_comments')) {
|
||||
function panel_comments($comments, $comment, $blog_id) {
|
||||
$result = '';
|
||||
|
||||
foreach ($comments->other as $another_comment) {
|
||||
$result .= '
|
||||
<div class="mx-10 relative ">
|
||||
<div class="before:h-full before:absolute before:right-[-10px] before:top-[0] before:z-0 before:w-[3px] before:bg-gray-500 before:block ">
|
||||
<div class="p-5 rounded ' . ($another_comment->type == 1 ? 'bg-gray-400' : 'bg-gray-200') . ' flex flex-col gap-3 m-3">
|
||||
<div>
|
||||
<h4> اسم : ' . $another_comment->name . '</h4>
|
||||
<p> پیام : ' . $another_comment->message . '</p>
|
||||
<p> نوع : ' . $another_comment->type_check . '</p>
|
||||
'
|
||||
;
|
||||
|
||||
|
||||
|
||||
$result .= '
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<a @click="modalshow2 = true , id = {{ $comment->id }} , $wire.id = {{ $comment->id }} , $wire.blog_id = {{ $comment->blog->id }} " class=" w-[140px] text-center bg-gray-500 text-white rounded-xl px-4 py-1"> تایین وضعیت</a>
|
||||
<a @click="modalshow = true , id = {{ $comment->id }} , $wire.id = {{ $comment->id }} , $wire.blog_id = {{ $comment->blog->id }} " class=" w-[120px] text-center bg-blue-500 text-white rounded-xl px-4 py-1">کامنت گذاری</a>
|
||||
|
||||
';
|
||||
|
||||
|
||||
|
||||
$result .= '
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ps-3 ">
|
||||
' . panel_comments($another_comment, $comment, $blog_id) . '
|
||||
</div>
|
||||
</div>';
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
if(!function_exists('profile')){
|
||||
function profile($admin=false)
|
||||
{
|
||||
|
||||
if($admin){
|
||||
return asset('images/profile/admin.png');
|
||||
|
||||
}
|
||||
$num=random_int(1,7);
|
||||
return asset('images/profile/'.$num.'.png');
|
||||
}}
|
||||
|
||||
if(!function_exists('how_long')){
|
||||
function how_long($time)
|
||||
{
|
||||
Carbon::setLocale('fa');
|
||||
$res=Carbon::parse($time)->diffForHumans();
|
||||
return $res;
|
||||
}}
|
||||
|
||||
if (!function_exists('cleanRouteUrl')) {
|
||||
function cleanRouteUrl($routeName, $parameters = [], $absolute = true)
|
||||
{
|
||||
$url = route($routeName, $parameters, $absolute);
|
||||
$url = preg_replace('/([^:])\/\//', '$1/', $url);
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user