This commit is contained in:
2023-11-24 20:49:19 +08:00
parent ca5219cb93
commit be14f5fdb1
65 changed files with 1991 additions and 2214 deletions

View File

@@ -29,17 +29,15 @@ protected function schedule(Schedule $schedule)
private function scheduleCategory(Schedule $schedule, $locale, $categoryName, $taskName)
{
$schedule->call(function () use ($locale, $categoryName) {
$category = Category::where('country_locale_slug', $locale)->where('name', $categoryName)->first();
if (!is_null($category))
{
$task = $category->country_locale_slug . "-" . $category->slug;
if (! is_null($category)) {
$task = $category->country_locale_slug.'-'.$category->slug;
$nextRun = DailyTaskSchedule::where('task', $task)->first();
if (!is_null($nextRun))
{
if (! is_null($nextRun)) {
$currentTime = now();
if ($currentTime->gte($nextRun->next_run_time)) {
@@ -57,11 +55,9 @@ private function scheduleCategory(Schedule $schedule, $locale, $categoryName, $t
$nextRun->next_run_time = now()->addMinutes(rand(1200, 1440));
$nextRun->save();
}
}
else
{
} else {
$nextRun = new DailyTaskSchedule;
$nextRun->task = $category->country_locale_slug . "-" . $category->slug;
$nextRun->task = $category->country_locale_slug.'-'.$category->slug;
$nextRun->next_run_time = now()->addMinutes(rand(0, 1440));
$nextRun->save();
}

View File

@@ -37,10 +37,8 @@ public function register()
return response()->json([
'status' => -1,
], 404);
}
else
{
return redirect()->route('home', [], 301);
} else {
return redirect()->route('home', [], 301);
}
});
}

View File

@@ -0,0 +1,40 @@
<?php
namespace App\Helpers\FirstParty\DFS;
use Exception;
use Http;
class DFSBacklinks
{
public static function backlinksPaginationLive($target, $search_after_token, $value = 1000)
{
$api_url = config('dataforseo.url');
$api_version = config('dataforseo.api_version');
$api_timeout = config('dataforseo.timeout');
$query = [
'target' => $target,
'search_after_token' => $search_after_token,
'value' => $value,
'mode' => 'as_is',
];
try {
$response = Http::timeout($api_timeout)->withBasicAuth(config('dataforseo.login'), config('dataforseo.password'))->withBody(
json_encode([(object) $query])
)->post("{$api_url}{$api_version}backlinks/backlinks/live");
if ($response->successful()) {
return $response->body();
}
} catch (Exception $e) {
return null;
}
return null;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace App\Helpers\FirstParty\DFS;
use Exception;
use Http;
class DFSSerp
{
public static function liveAdvanced($se, $se_type, $keyword, $location_name, $language_code, $depth, $search_param = null)
{
$api_url = config('dataforseo.url');
$api_version = config('dataforseo.api_version');
$api_timeout = config('dataforseo.timeout');
$query = [
'keyword' => $keyword,
'location_name' => $location_name,
'language_code' => $language_code,
];
if (! is_empty($search_param)) {
$query['search_param'] = $search_param;
}
try {
$response = Http::timeout($api_timeout)->withBasicAuth(config('dataforseo.login'), config('dataforseo.password'))->withBody(
json_encode([(object) $query])
)->post("{$api_url}{$api_version}serp/{$se}/{$se_type}/live/advanced");
if ($response->successful()) {
return $response->body();
}
} catch (Exception $e) {
return null;
}
return null;
}
}

View File

@@ -12,7 +12,7 @@ public static function writeProductArticle($excerpt, $photos, $categories)
{
//$excerpt = substr($excerpt, 0, 1500);
$category_str = implode("|", $categories);
$category_str = implode('|', $categories);
$system_prompt = '
You are tasked with writing a product introduction & review article using the provided excerpt. Write as if you are reviewing the product by a third party, avoiding pronouns. Emphasize the product\'s performance, features, and notable aspects. Do not mention marketplace-related information. Return the output as a minified JSON in this format:

View File

@@ -17,7 +17,7 @@ function str_first_sentence($str)
// Return the first part of the array if available
if (isset($sentences[0])) {
return trim($sentences[0]) . ".";
return trim($sentences[0]).'.';
}
// If no sentence ending found, return the whole string

View File

@@ -3,214 +3,12 @@
namespace App\Http\Controllers\Front;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\CountryLocale;
use App\Models\Post;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\SEOTools;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index(Request $request)
{
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
SEOTools::setTitle('Top Product Reviews, Deals & New Launches');
SEOTools::setDescription('Explore ProductAlert for in-depth product reviews and incredible deals. We cover Beauty, Tech, Home Appliances, Health & Fitness, Parenting, and more.');
$country = strtolower($request->session()->get('country'));
return redirect()->route('home.country', ['country' => $country]);
}
public function country(Request $request, $country)
{
$country_locale = CountryLocale::where('slug', $country)->first();
if (! is_null($country_locale)) {
$request->session()->put('view_country_locale', $country_locale);
$featured_posts = Post::select('posts.*')
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
->join('categories', 'post_categories.category_id', '=', 'categories.id')
->whereNotNull('post_categories.id')
->whereNotNull('categories.id')
->where('categories.country_locale_slug', $country_locale->slug)
->where('posts.status', 'publish')
->orderBy('posts.publish_date', 'desc')
->take(3)
->get();
$latest_posts = Post::select('posts.*')
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
->join('categories', 'post_categories.category_id', '=', 'categories.id')
->whereNotNull('post_categories.id')
->whereNotNull('categories.id')
->where('categories.country_locale_slug', $country_locale->slug)
->whereNotIn('posts.id', $featured_posts->pluck('id')->toArray())
->where('posts.status', 'publish')
->orderBy('posts.publish_date', 'desc')
->distinct()
->take(10)
->get();
if ($latest_posts->count() <= 0) {
SEOMeta::setRobots('noindex');
}
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
$country_name = get_country_name_by_iso($country_locale->country_iso);
SEOTools::setTitle("Your {$country_name} Guide to Product Reviews & Top Deals");
SEOTools::setDescription("Discover trusted product reviews and unbeatable deals at ProductAlert {$country_name}, your local guide to smart shopping.");
return view('front.country', compact('country_locale', 'featured_posts', 'latest_posts')
);
}
return redirect()->route('home.country', ['country' => config('platform.general.fallback_country_slug')]);
}
public function countryCategory(Request $request, $country, $category)
{
$country_locale = CountryLocale::where('slug', $country)->first();
if (is_null($country_locale)) {
abort(404);
}
$category = Category::where('slug', $category)->where('enabled', true)->first();
if (is_null($category)) {
abort(404);
}
$request->session()->put('view_country_locale', $country_locale);
$latest_posts = Post::with('post_categories')->select('posts.*')
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
->join('categories', 'post_categories.category_id', '=', 'categories.id')
->whereNotNull('post_categories.id')
->whereNotNull('categories.id')
->where('categories.country_locale_slug', $country_locale->slug)
->where('categories.id', $category->id)
->where('posts.status', 'publish')
->orderBy('posts.publish_date', 'desc')
->distinct()
->paginate(15);
if ($latest_posts->count() <= 0) {
SEOMeta::setRobots('noindex');
}
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
$this_month = now()->format('F Y');
$country_name = get_country_name_by_iso($country_locale->country_iso);
//dd($category->type);
if ($category->type == 'review') {
SEOTools::setTitle("Top {$category->name} Reviews for {$this_month} in {$country_name}");
} elseif ($category->type == 'deals') {
SEOTools::setTitle("{$this_month} Latest Deals, Coupon Codes & Vouchers for {$country_name}");
} elseif ($category->type == 'launch') {
SEOTools::setTitle("New {$this_month} Product Launches in {$country_name}");
}
$category_name = strtolower($category->name);
SEOTools::setDescription($category->description);
return view('front.country_category', compact('country_locale', 'category', 'latest_posts'));
}
public function all(Request $request, $country)
{
$country_locale = CountryLocale::where('slug', $country)->first();
$request->session()->put('view_country_locale', $country_locale);
$latest_posts = Post::with('post_categories')->select('posts.*')
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
->join('categories', 'post_categories.category_id', '=', 'categories.id')
->whereNotNull('post_categories.id')
->whereNotNull('categories.id')
->where('categories.country_locale_slug', $country_locale->slug)
->where('posts.status', 'publish')
->orderBy('posts.publish_date', 'desc')
->distinct()
->paginate(15);
if ($latest_posts->count() <= 0) {
SEOMeta::setRobots('noindex');
}
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
$country_name = get_country_name_by_iso($country_locale->country_iso);
SEOTools::setTitle("Find Product Reviews and Best Deals for {$country_name}");
SEOTools::setDescription("Discover the latest product reviews and unbeatable deals at ProductAlert, your guide to shopping in {$country_name}. Stay on top of fresh product updates.");
return view('front.country_all', compact('country_locale', 'latest_posts'));
}
public function post(Request $request, $country, $post_slug)
{
$post = Post::where('slug', $post_slug)->where('status', 'publish')->first();
if (! is_null($post)) {
$request->session()->put('view_country_locale', $post->post_category->category->country_locale);
SEOMeta::setTitle($post->title);
SEOMeta::setDescription($post->excerpt);
SEOMeta::addMeta('article:published_time', $post->publish_date, 'property');
SEOMeta::addMeta('article:section', $post->post_category->category->name, 'property');
OpenGraph::setDescription($post->excerpt);
OpenGraph::setTitle($post->title);
OpenGraph::setUrl(url()->current());
OpenGraph::addProperty('type', 'article');
OpenGraph::addProperty('locale', $post->post_category->category->country_locale->i18n);
OpenGraph::addImage($post->featured_image);
$jsonld_multi = JsonLdMulti::newJsonLd();
$jsonld_multi->setTitle($post->title)
->setDescription($post->excerpt)
->setType('Article')
->addImage($post->featured_image)
->addValue('author', $post->author->name)
->addValue('datePublished', $post->publish_date->format('Y-m-d'))
->addValue('dateCreated', $post->publish_date->format('Y-m-d'))
->addValue('dateModified', $post->updated_at->format('Y-m-d'))
->addValue('description', $post->excerpt)
->addValue('articleBody', trim(preg_replace('/\s\s+/', ' ', strip_tags($post->html_body))));
return view('front.post', compact('post'));
}
abort(404);
return view('front.home');
}
}

View File

@@ -0,0 +1,194 @@
<?php
namespace App\Http\Controllers\Front;
use App\Http\Controllers\Controller;
use App\Models\Category;
use App\Models\CountryLocale;
use App\Models\Post;
use Artesaos\SEOTools\Facades\JsonLdMulti;
use Artesaos\SEOTools\Facades\OpenGraph;
use Artesaos\SEOTools\Facades\SEOMeta;
use Artesaos\SEOTools\Facades\SEOTools;
use Illuminate\Http\Request;
class OldHomeController extends Controller
{
public function index(Request $request)
{
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
SEOTools::setTitle('Top Product Reviews, Deals & New Launches');
SEOTools::setDescription('Explore ProductAlert for in-depth product reviews and incredible deals. We cover Beauty, Tech, Home Appliances, Health & Fitness, Parenting, and more.');
return redirect()->route('home.country', ['country' => 'global']);
}
public function country(Request $request, $country)
{
$country_locale = CountryLocale::where('slug', $country)->first();
if (! is_null($country_locale)) {
$request->session()->put('view_country_locale', $country_locale);
$featured_posts = collect([]);
$latest_posts = collect([]);
if ($latest_posts->count() <= 0) {
SEOMeta::setRobots('noindex');
}
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
$country_name = get_country_name_by_iso($country_locale->country_iso);
SEOTools::setTitle("Your {$country_name} Guide to Product Reviews & Top Deals");
SEOTools::setDescription("Discover trusted product reviews and unbeatable deals at ProductAlert {$country_name}, your local guide to smart shopping.");
return view('front.country', compact('country_locale', 'featured_posts', 'latest_posts')
);
}
return redirect()->route('home.country', ['country' => config('platform.general.fallback_country_slug')]);
}
public function countryCategory(Request $request, $country, $category)
{
$country_locale = CountryLocale::where('slug', $country)->first();
if (is_null($country_locale)) {
abort(404);
}
$category = Category::where('slug', $category)->where('enabled', true)->first();
if (is_null($category)) {
abort(404);
}
$request->session()->put('view_country_locale', $country_locale);
$latest_posts = Post::with('post_categories')->select('posts.*')
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
->join('categories', 'post_categories.category_id', '=', 'categories.id')
->whereNotNull('post_categories.id')
->whereNotNull('categories.id')
->where('categories.country_locale_slug', $country_locale->slug)
->where('categories.id', $category->id)
->where('posts.status', 'publish')
->orderBy('posts.publish_date', 'desc')
->distinct()
->paginate(15);
if ($latest_posts->count() <= 0) {
SEOMeta::setRobots('noindex');
}
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
$this_month = now()->format('F Y');
$country_name = get_country_name_by_iso($country_locale->country_iso);
//dd($category->type);
if ($category->type == 'review') {
SEOTools::setTitle("Top {$category->name} Reviews for {$this_month} in {$country_name}");
} elseif ($category->type == 'deals') {
SEOTools::setTitle("{$this_month} Latest Deals, Coupon Codes & Vouchers for {$country_name}");
} elseif ($category->type == 'launch') {
SEOTools::setTitle("New {$this_month} Product Launches in {$country_name}");
}
$category_name = strtolower($category->name);
SEOTools::setDescription($category->description);
return view('front.country_category', compact('country_locale', 'category', 'latest_posts'));
}
public function all(Request $request, $country)
{
$country_locale = CountryLocale::where('slug', $country)->first();
$request->session()->put('view_country_locale', $country_locale);
$latest_posts = Post::with('post_categories')->select('posts.*')
->join('post_categories', 'posts.id', '=', 'post_categories.post_id')
->join('categories', 'post_categories.category_id', '=', 'categories.id')
->whereNotNull('post_categories.id')
->whereNotNull('categories.id')
->where('categories.country_locale_slug', $country_locale->slug)
->where('posts.status', 'publish')
->orderBy('posts.publish_date', 'desc')
->distinct()
->paginate(15);
if ($latest_posts->count() <= 0) {
SEOMeta::setRobots('noindex');
}
SEOTools::metatags();
SEOTools::twitter();
SEOTools::opengraph();
SEOTools::jsonLd();
$country_name = get_country_name_by_iso($country_locale->country_iso);
SEOTools::setTitle("Find Product Reviews and Best Deals for {$country_name}");
SEOTools::setDescription("Discover the latest product reviews and unbeatable deals at ProductAlert, your guide to shopping in {$country_name}. Stay on top of fresh product updates.");
return view('front.country_all', compact('country_locale', 'latest_posts'));
}
public function post(Request $request, $country, $post_slug)
{
$post = Post::where('slug', $post_slug)->where('status', 'publish')->first();
if (! is_null($post)) {
$request->session()->put('view_country_locale', $post->post_category->category->country_locale);
SEOMeta::setTitle($post->title);
SEOMeta::setDescription($post->excerpt);
SEOMeta::addMeta('article:published_time', $post->publish_date, 'property');
SEOMeta::addMeta('article:section', $post->post_category->category->name, 'property');
OpenGraph::setDescription($post->excerpt);
OpenGraph::setTitle($post->title);
OpenGraph::setUrl(url()->current());
OpenGraph::addProperty('type', 'article');
OpenGraph::addProperty('locale', $post->post_category->category->country_locale->i18n);
OpenGraph::addImage($post->featured_image);
$jsonld_multi = JsonLdMulti::newJsonLd();
$jsonld_multi->setTitle($post->title)
->setDescription($post->excerpt)
->setType('Article')
->addImage($post->featured_image)
->addValue('author', $post->author->name)
->addValue('datePublished', $post->publish_date->format('Y-m-d'))
->addValue('dateCreated', $post->publish_date->format('Y-m-d'))
->addValue('dateModified', $post->updated_at->format('Y-m-d'))
->addValue('description', $post->excerpt)
->addValue('articleBody', trim(preg_replace('/\s\s+/', ' ', strip_tags($post->html_body))));
return view('front.post', compact('post'));
}
abort(404);
}
}

View File

@@ -2,19 +2,19 @@
namespace App\Jobs\Tasks;
use fivefilters\Readability\Configuration as ReadabilityConfiguration;
use fivefilters\Readability\ParseException as ReadabilityParseException;
use fivefilters\Readability\Readability;
use App\Helpers\FirstParty\OpenAI\OpenAI;
use App\Helpers\FirstParty\OSSUploader\OSSUploader;
use App\Models\AiWriteup;
use App\Models\Category;
use App\Models\Post;
use App\Models\PostCategory;
use App\Models\Category;
use App\Models\ShopeeSellerCategory;
use App\Models\ShopeeSellerScrape;
use App\Models\ShopeeSellerScrapedImage;
use Exception;
use fivefilters\Readability\Configuration as ReadabilityConfiguration;
use fivefilters\Readability\ParseException as ReadabilityParseException;
use fivefilters\Readability\Readability;
use Illuminate\Support\Facades\Log;
use LaravelFreelancerNL\LaravelIndexNow\Facades\IndexNow;
use LaravelGoogleIndexing;
@@ -36,8 +36,6 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
$shopee_task->shopee_seller_scrape = $shopee_seller_scrape;
}
// dd($shopee_task);
// dd($shopee_task->product_task->response);
@@ -57,11 +55,11 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
if (is_null($ai_writeup)) {
$categories = [
'Beauty',
'Technology',
'Home & Living',
'Health',
'Fitness'
'Beauty',
'Technology',
'Home & Living',
'Health',
'Fitness',
];
$ai_output = OpenAI::writeProductArticle($excerpt, $photos, $categories);
@@ -76,11 +74,10 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
throw ($e);
} else {
$picked_category = Category::where('name', $ai_output->category)->where('country_locale_id', $shopee_seller_scrape->category->country_locale_id)->first();
$picked_category = Category::where('name', $ai_output->category)->where('country_locale_id', $shopee_seller_scrape->category->country_locale_id)->first();
if (is_null($picked_category))
{
$picked_category = $shopee_seller_scrape->category;
if (is_null($picked_category)) {
$picked_category = $shopee_seller_scrape->category;
}
// save
@@ -122,13 +119,12 @@ public static function handle(ShopeeSellerScrape $shopee_seller_scrape)
$shopee_seller_scrape->last_ai_written_at = now();
$shopee_seller_scrape->save();
$shopee_seller_category = ShopeeSellerCategory::where('seller', $shopee_seller_scrape->seller)->first();
$shopee_seller_category = ShopeeSellerCategory::where('seller', $shopee_seller_scrape->seller)->first();
if (is_null($shopee_seller_category))
{
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $shopee_seller_scrape->seller;
$shopee_seller_category->category_id = $shopee_seller_scrape->category_id;
if (is_null($shopee_seller_category)) {
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $shopee_seller_scrape->seller;
$shopee_seller_category->category_id = $shopee_seller_scrape->category_id;
}
$shopee_seller_category->last_ai_written_at = $shopee_seller_scrape->last_ai_written_at;
@@ -169,34 +165,33 @@ private static function getProductPricingExcerpt(array $jsonLdData)
foreach ($jsonLdData as $data) {
// Ensure the type is "Product" before proceeding
if (isset($data->{'@type'}) && $data->{'@type'} === 'Product') {
// Extract necessary data
$lowPrice = $data->offers->lowPrice ?? null;
$highPrice = $data->offers->highPrice ?? null;
$price = $data->offers->price ?? null;
$currency = $data->offers->priceCurrency ?? null;
$sellerName = $data->offers->seller->name ?? "online store"; // default to "online store" if name is not set
if (!is_empty($currency))
{
if ($currency == 'MYR')
{
$currency = 'RM';
// Extract necessary data
$lowPrice = $data->offers->lowPrice ?? null;
$highPrice = $data->offers->highPrice ?? null;
$price = $data->offers->price ?? null;
$currency = $data->offers->priceCurrency ?? null;
$sellerName = $data->offers->seller->name ?? 'online store'; // default to "online store" if name is not set
if (! is_empty($currency)) {
if ($currency == 'MYR') {
$currency = 'RM';
}
}
}
// Determine and format pricing sentence
if ($lowPrice && $highPrice) {
$lowPrice = number_format($lowPrice, 0);
$highPrice = number_format($highPrice, 0);
// Determine and format pricing sentence
if ($lowPrice && $highPrice) {
$lowPrice = number_format($lowPrice, 0);
$highPrice = number_format($highPrice, 0);
return "Price Range from {$currency} {$lowPrice} to {$highPrice} in {$sellerName} online store";
} elseif ($price) {
$price = number_format($price, 0);
return "Priced at {$currency} {$price} in {$sellerName} online store";
} else {
return "Price not stated, refer to {$sellerName} online store";
}
return "Price Range from {$currency} {$lowPrice} to {$highPrice} in {$sellerName} online store";
} elseif ($price) {
$price = number_format($price, 0);
return "Priced at {$currency} {$price} in {$sellerName} online store";
} else {
return "Price not stated, refer to {$sellerName} online store";
}
}
}

View File

@@ -7,16 +7,12 @@
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\Facades\Image;
use Symfony\Component\DomCrawler\Crawler;
use Masterminds\HTML5;
class SaveShopeeSellerImagesTask
{
public static function handle($shopee_task)
{
$unblocker_proxy_server = get_smartproxy_unblocker_server();
$rotating_proxy_server = get_smartproxy_rotating_server();
$costs = [];
@@ -174,9 +170,8 @@ private static function getFilteredImages(string $raw_html, string $proxy, strin
continue;
}
if ($height > $width)
{
continue;
if ($height > $width) {
continue;
}
$interventionImage->resize(800, null, function ($constraint) {
@@ -257,9 +252,8 @@ private static function getFilteredImages(string $raw_html, string $proxy, strin
$final_images = [];
foreach ($filteredImages as $image_obj)
{
$final_images[] = (object) $image_obj;
foreach ($filteredImages as $image_obj) {
$final_images[] = (object) $image_obj;
}
return $final_images;

View File

@@ -5,12 +5,9 @@
use App\Helpers\FirstParty\OSSUploader\OSSUploader;
use Exception;
use Illuminate\Support\Facades\Http;
use Intervention\Image\Facades\Image;
use Minifier\TinyMinify;
use Spatie\Browsershot\Browsershot;
use Spatie\Browsershot\Exceptions\UnsuccessfulResponse;
use Symfony\Component\DomCrawler\Crawler;
use thiagoalessio\TesseractOCR\TesseractOCR;
class UrlCrawlerTask
{
@@ -60,8 +57,7 @@ public static function handle(string $url, $directory, $postfix = null, $strip_h
])
->get($cached_url);
if ($response->successful())
{
if ($response->successful()) {
$raw_html = $response->body();
$costs['unblocker'] = calculate_smartproxy_cost(round(strlen($raw_html) / 1024, 2), 'unblocker');
} else {
@@ -195,7 +191,8 @@ private static function minifyAndCleanHtml(string $raw_html)
return $crawler->html();
}
private static function minifyHTML($input) {
private static function minifyHTML($input)
{
// Remove extra white space between HTML tags
$input = preg_replace('/>\s+</', '><', $input);

View File

@@ -11,25 +11,23 @@
/**
* Class DailyTaskSchedule
*
*
* @property int $id
* @property string $task
* @property Carbon $next_run_time
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @package App\Models
*/
class DailyTaskSchedule extends Model
{
protected $table = 'daily_task_schedules';
protected $table = 'daily_task_schedules';
protected $casts = [
'next_run_time' => 'datetime'
];
protected $casts = [
'next_run_time' => 'datetime',
];
protected $fillable = [
'task',
'next_run_time'
];
protected $fillable = [
'task',
'next_run_time',
];
}

View File

@@ -36,4 +36,3 @@ class FailedJob extends Model
'failed_at' => 'datetime',
];
}

View File

@@ -152,36 +152,35 @@ public function getHtmlBodyAttribute()
}
});
// Modify the DOM by wrapping the <img> tags inside a <figure> and adding the desired structure
$crawler->filter('img')->each(function (Crawler $node) {
$imgElement = $node->getNode(0);
// Update the class of the <img>
$existingClasses = $imgElement->getAttribute('class');
$newClasses = 'img-fluid rounded-2 shadow-sm mb-2';
$updatedClasses = ($existingClasses ? $existingClasses.' ' : '').$newClasses;
$imgElement->setAttribute('class', $updatedClasses);
// Create a new <figure> element
$figureElement = new \DOMElement('figure');
$imgElement->parentNode->insertBefore($figureElement, $imgElement);
// Move the <img> inside the <figure>
$figureElement->appendChild($imgElement);
$figureElement->setAttribute('class', 'image');
// Create a new <footer> element inside <figure> without directly setting its content
$footerElement = $imgElement->ownerDocument->createElement('footer');
$figureElement->appendChild($footerElement);
// Add the content to <footer> using createTextNode to ensure special characters are handled
$footerText = $imgElement->ownerDocument->createTextNode($imgElement->getAttribute('alt'));
$footerElement->appendChild($footerText);
// Set the class attribute for <footer>
$footerElement->setAttribute('class', 'image-caption');
});
// Modify the DOM by wrapping the <img> tags inside a <figure> and adding the desired structure
$crawler->filter('img')->each(function (Crawler $node) {
$imgElement = $node->getNode(0);
// Update the class of the <img>
$existingClasses = $imgElement->getAttribute('class');
$newClasses = 'img-fluid rounded-2 shadow-sm mb-2';
$updatedClasses = ($existingClasses ? $existingClasses.' ' : '').$newClasses;
$imgElement->setAttribute('class', $updatedClasses);
// Create a new <figure> element
$figureElement = new \DOMElement('figure');
$imgElement->parentNode->insertBefore($figureElement, $imgElement);
// Move the <img> inside the <figure>
$figureElement->appendChild($imgElement);
$figureElement->setAttribute('class', 'image');
// Create a new <footer> element inside <figure> without directly setting its content
$footerElement = $imgElement->ownerDocument->createElement('footer');
$figureElement->appendChild($footerElement);
// Add the content to <footer> using createTextNode to ensure special characters are handled
$footerText = $imgElement->ownerDocument->createTextNode($imgElement->getAttribute('alt'));
$footerElement->appendChild($footerText);
// Set the class attribute for <footer>
$footerElement->setAttribute('class', 'image-caption');
});
// Add Bootstrap 5 styling to tables
$crawler->filter('table')->each(function (Crawler $node) {

View File

@@ -11,7 +11,7 @@
/**
* Class ShopeeSellerCategory
*
*
* @property int $id
* @property string $seller
* @property int $category_id
@@ -19,30 +19,27 @@
* @property int $write_counts
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*
* @property Category $category
*
* @package App\Models
*/
class ShopeeSellerCategory extends Model
{
protected $table = 'shopee_seller_categories';
protected $table = 'shopee_seller_categories';
protected $casts = [
'category_id' => 'int',
'last_ai_written_at' => 'datetime',
'write_counts' => 'int'
];
protected $casts = [
'category_id' => 'int',
'last_ai_written_at' => 'datetime',
'write_counts' => 'int',
];
protected $fillable = [
'seller',
'category_id',
'last_ai_written_at',
'write_counts'
];
protected $fillable = [
'seller',
'category_id',
'last_ai_written_at',
'write_counts',
];
public function category()
{
return $this->belongsTo(Category::class);
}
public function category()
{
return $this->belongsTo(Category::class);
}
}

View File

@@ -42,7 +42,7 @@ class ShopeeSellerScrape extends Model
'epoch',
'filename',
'last_ai_written_at',
'write_counts'
'write_counts',
];
public function category()

View File

@@ -27,11 +27,11 @@ public function register()
public function boot()
{
// Using class based composers...
View::composer('layouts.front.navigation', CategoryComposer::class);
View::composer('layouts.front.navigation', CountryLocaleComposer::class);
// View::composer('layouts.front.navigation', CategoryComposer::class);
// View::composer('layouts.front.navigation', CountryLocaleComposer::class);
View::composer('layouts.front.footer', CategoryComposer::class);
View::composer('layouts.front.footer', CountryLocaleComposer::class);
// View::composer('layouts.front.footer', CategoryComposer::class);
// View::composer('layouts.front.footer', CountryLocaleComposer::class);
if (auth()->check()) {