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()) {

14
config/dataforseo.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
return [
'login' => env('DATAFORSEO_LOGIN', 'login'),
'password' => env('DATAFORSEO_PASSWORD', 'password'),
'timeout' => 120,
'api_version' => '/v3/',
'url' => 'https://api.dataforseo.com',
];

View File

@@ -9,9 +9,9 @@
* The default configurations to be used by the meta generator.
*/
'defaults' => [
'title' => 'ProductAlert', // set false to total remove
'title' => 'AI Buddy Tools', // set false to total remove
'titleBefore' => false, // Put defaults.title before page title, like 'It's Over 9000! - Dashboard'
'description' => 'Find top-rated product reviews at ProductAlert. Discover the latest trends, best brands, and right prices. Your guide to making the best purchase decisions!', // set false to total remove
'description' => 'The leading AI tools directory and search engine, Discover the best AI tools, apps and services list and take your business to the next level.', // set false to total remove
'separator' => ' - ',
'keywords' => [],
'canonical' => 'full', // Set to null or 'full' to use Url::full(), set to 'current' to use Url::current(), set false to total remove
@@ -36,8 +36,8 @@
* The default configurations to be used by the opengraph generator.
*/
'defaults' => [
'title' => 'ProductAlert', // set false to total remove
'description' => 'Find top-rated product reviews at ProductAlert. Discover the latest trends, best brands, and right prices. Your guide to making the best purchase decisions!', // set false to total remove
'title' => 'AI Buddy Tools', // set false to total remove
'description' => 'The leading AI tools directory and search engine, Discover the best AI tools, apps and services list and take your business to the next level.', // set false to total remove
'url' => false, // Set null for using Url::current(), set false to total remove
'type' => false,
'site_name' => false,
@@ -58,8 +58,8 @@
* The default configurations to be used by the json-ld generator.
*/
'defaults' => [
'title' => 'ProductAlert', // set false to total remove
'description' => 'Find top-rated product reviews at ProductAlert. Discover the latest trends, best brands, and right prices. Your guide to making the best purchase decisions!', // set false to total remove
'title' => 'AI Buddy Tools', // set false to total remove
'description' => 'The leading AI tools directory and search engine, Discover the best AI tools, apps and services list and take your business to the next level.', // set false to total remove
'url' => false, // Set to null or 'full' to use Url::full(), set to 'current' to use Url::current(), set false to total remove
'type' => 'WebPage',
'images' => [],

View File

@@ -16,6 +16,8 @@ public function up(): void
$table->string('name');
$table->string('slug')->unique();
$table->string('i18n')->unique();
$table->string('country_iso');
$table->string('lang');
$table->boolean('enabled')->default(false);
$table->softDeletes();
$table->timestamps();

View File

@@ -1,6 +1,5 @@
<?php
use App\Models\CountryLocale;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
@@ -14,10 +13,13 @@ public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(CountryLocale::class);
$table->enum('type', ['review', 'launch', 'deals'])->default('review');
$table->foreignId('country_locale_id');
$table->string('country_locale_slug')->default('my');
$table->string('name')->nullable();
$table->string('short_name')->nullable();
$table->string('slug')->nullable();
$table->mediumText('description')->nullable();
$table->boolean('enabled')->default(true);
$table->boolean('is_top')->default(true);
$table->nestedSet();
@@ -25,6 +27,8 @@ public function up(): void
$table->timestamps();
$table->foreign('country_locale_id')->references('id')->on('country_locales');
$table->foreign('country_locale_slug')->references('slug')->on('country_locales');
});
}

View File

@@ -1,29 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->string('country_locale_slug')->after('country_locale_id')->default('my');
$table->foreign('country_locale_slug')->references('slug')->on('country_locales');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->dropColumn('country_locale_slug');
});
}
};

View File

@@ -1,30 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('country_locales', function (Blueprint $table) {
$table->string('country_iso')->after('i18n');
$table->string('lang')->after('i18n');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('country_locales', function (Blueprint $table) {
$table->dropColumn('country_iso');
$table->dropColumn('lang');
});
}
};

View File

@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->mediumText('description')->after('slug')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->dropColumn('description');
});
}
};

View File

@@ -15,11 +15,13 @@ public function up(): void
$table->id();
$table->string('title')->nullable();
$table->string('slug')->nullable();
$table->text('cliffhanger')->nullable();
$table->mediumText('excerpt')->nullable();
$table->foreignId('author_id')->nullable();
$table->datetime('publish_date')->nullable();
$table->boolean('featured')->default(false);
$table->string('featured_image')->nullable();
$table->enum('editor', ['editorjs'])->default('editorjs');
$table->enum('editor', ['editorjs', 'markdown'])->default('editorjs');
$table->json('body')->nullable();
$table->enum('post_format', ['standard'])->default('standard');
$table->integer('comment_count')->default(0);

View File

@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->datetime('publish_date')->nullable()->after('author_id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('publish_date');
});
}
};

View File

@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->enum('type', ['review', 'launch', 'deals'])->default('review')->after('id');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('categories', function (Blueprint $table) {
$table->dropColumn('type');
});
}
};

View File

@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->string('cliffhanger')->after('excerpt')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('posts', function (Blueprint $table) {
$table->dropColumn('cliffhanger');
});
}
};

View File

@@ -1,28 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up()
{
Schema::table('posts', function (Blueprint $table) {
$table->text('cliffhanger')->after('excerpt')->nullable()->change();
});
}
/**
* Reverse the migrations.
*/
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->string('cliffhanger')->after('excerpt')->nullable()->change();
});
}
};

View File

@@ -1,24 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
DB::statement("ALTER TABLE posts CHANGE COLUMN editor editor ENUM('editorjs', 'markdown') NOT NULL DEFAULT 'editorjs'");
}
/**
* Reverse the migrations.
*/
public function down(): void
{
DB::statement("ALTER TABLE posts CHANGE COLUMN editor editor ENUM('editorjs') NOT NULL DEFAULT 'editorjs'");
}
};

View File

@@ -0,0 +1,28 @@
<?php
namespace Database\Seeders;
use App\Models\CountryLocale;
use Illuminate\Database\Seeder;
class CountryLocaleSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$global_country_locale = CountryLocale::where('slug', 'global')->first();
if (is_null($global_country_locale)) {
$global_country_locale = new CountryLocale;
$global_country_locale->name = 'Global';
$global_country_locale->slug = 'global';
$global_country_locale->i18n = 'en';
$global_country_locale->lang = 'en';
$global_country_locale->country_iso = '*';
$global_country_locale->enabled = true;
$global_country_locale->save();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@
use App\Models\Category;
use App\Models\ShopeeSellerCategory;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ShopeeFitnessCategorySeeder extends Seeder
@@ -14,17 +13,16 @@ class ShopeeFitnessCategorySeeder extends Seeder
*/
public function run(): void
{
$shopee_sellers = ["abugarcia.os", "acrossports.os", "adidasmy.os", "aibifitness.os", "alikhsansports.os", "alonefire.os", "alpsport.os", "altrarunningmy.os", "ambroscorp", "antamalaysia.os", "antaofficial.os", "aonijie.os", "apacsofficialflagshipstore", "aqsupport.os", "asicsmalaysia.os", "athletelq.os", "avivaactive.os", "brooks.os", "badmintonfactory", "blenderbottle.os", "bullzenfishing.os", "bushnell.os", "carlton.os", "camelcrownoutdoor.os", "cameloutdoor.os", "capbarbellasia.os", "chaopai.os", "cinellimalaysia.os", "cm2.os", "coleman.os", "consinaofficial.os", "crazeecausa", "dahon.os", "decathlon.official.store", "desiregym.os", "deutermy.os", "dhs.os", "diadoramy.os", "durakingoutdoorandsports.os", "donicmalaysia.os", "drskin.os", "egosports.os", "endurancesports", "expfishing.os", "prokennex.os", "felet.os", "fenin.os", "wums0310.os", "tokushima.os", "fitnessconcept.os", "gattimalaysia", "gearupmy.os", "gintell", "gomexus.os", "gosengs.sports.world", "gsgill.os", "db3686", "hedgrenmy.os", "herschelmy.os", "hiervnofficial.my", "hoopsstation.os", "hydroflaskmy.os", "hypergear.os", "inbike.os", "pa20085566.os", "jakroomy.os", "johnsonfitness.os", "jdtstore", "kalibre.os", "kastking.os", "kingdomfishing.my", "kingsmith.os", "kshbicycle.os", "kuckreja.os", "kawasakibadmintonmalaysia", "lasonaofficial.my", "lining.os", "litepro.my", "lixada.os", "lpmy.os", "lpm.os", "montanic.os", "matsumotostore", "mavllos.os", "maxboltmy", "maxfind.os", "maxx.os", "mobigarden.os", "mcdavidmy.os", "minelabmalaysia", "mobigarden.kj.os", "spacey.os", "montbell.os", "monton.malaysia.os", "moonaz.os", "naturehike.os", "naturehikeglobal.my", "langgou.my", "newbalancemy.os", "nicronmy", "ogevkin.my", "ogawacorp.", "ogival.os", "one.two.fit", "onetwofitofficial.my", "originalclassicmy.os", "ortuseightofficialshop.os", "osprey.os", "exploreroutfitter.os", "outpost.os", "outsidemy.os", "outtobe.os", "ovicx.os", "peak.os", "peaksportsmy.os", "pgmgolf.os", "pinknproper.os", "prestigesports.os", "proapparel.os", "probiker.my", "pronic.os", "prosun.os", "protech.os", "protechbysupercourt", "prspsports", "pumamy.os", "purefishingmalaysia.os", "rcl.os", "rainbowstyle333.os", "rapalamy.os", "reechooutdoor.my", "rigidfitness.os", "ripcurlmy.os", "rockbros.os", "cycling1.my", "rstaichi.os", "runninglabmy.os", "oceansportmy", "s2hcyclemall.os", "salomonmy.os", "sanctbandactive.os", "santic.os", "seahawkfishing.os", "selleitaliamalaysia", "shimanomalaysiacycling.os", "shimanofishingmy.os", "shipwreckskateboards.os", "skelcoremy.os", "kelvenchang.os", "slmbicycle.os", "smilingshark.os", "xunmenglong.my", "sneakerlabmy.os", "snugsport.os", "sofirnlight.my", "sougayilang.os", "sparkprotein.os", "whaledream563", "speedoofficial.os", "sportplanet.os", "sportsdirectmy.os", "stridermalaysia.os", "sunparadisemy", "18138419167.my", "swimfitmy.os", "themarathonshop.os", "thenorthfacemy.os", "tankebicycle.os", "tcetacklesestore", "tecnifibremy", "tenxionofficial.os", "cinemark0621.os", "thirddayco.os", "thkfish.os", "treesandsunoutdoor", "trs.os", "trudivemalaysiasingapore", "tulldent.os", "twinbrothers.os", "underarmourmy.os", "uponumbrella.os", "uscamel1.my", "velo88.os", "victorbysinma", "victormalaysia.os", "victorinox.os", "vigorfitness.os", "viq.os", "vsmash.os", "warrixofficialju.my", "westbiking.os", "worldofsports.os", "xtiger.os", "xcorefitness.os", "xinpower.os", "xiom.os", "xtep.os", "yinhe.os", "yonex.os", "youngofficial.os", "zeromarketplace", "zttobike.my", "2xu.os", "361degrees.os", "910sportswear.os"
];
$shopee_sellers = ['abugarcia.os', 'acrossports.os', 'adidasmy.os', 'aibifitness.os', 'alikhsansports.os', 'alonefire.os', 'alpsport.os', 'altrarunningmy.os', 'ambroscorp', 'antamalaysia.os', 'antaofficial.os', 'aonijie.os', 'apacsofficialflagshipstore', 'aqsupport.os', 'asicsmalaysia.os', 'athletelq.os', 'avivaactive.os', 'brooks.os', 'badmintonfactory', 'blenderbottle.os', 'bullzenfishing.os', 'bushnell.os', 'carlton.os', 'camelcrownoutdoor.os', 'cameloutdoor.os', 'capbarbellasia.os', 'chaopai.os', 'cinellimalaysia.os', 'cm2.os', 'coleman.os', 'consinaofficial.os', 'crazeecausa', 'dahon.os', 'decathlon.official.store', 'desiregym.os', 'deutermy.os', 'dhs.os', 'diadoramy.os', 'durakingoutdoorandsports.os', 'donicmalaysia.os', 'drskin.os', 'egosports.os', 'endurancesports', 'expfishing.os', 'prokennex.os', 'felet.os', 'fenin.os', 'wums0310.os', 'tokushima.os', 'fitnessconcept.os', 'gattimalaysia', 'gearupmy.os', 'gintell', 'gomexus.os', 'gosengs.sports.world', 'gsgill.os', 'db3686', 'hedgrenmy.os', 'herschelmy.os', 'hiervnofficial.my', 'hoopsstation.os', 'hydroflaskmy.os', 'hypergear.os', 'inbike.os', 'pa20085566.os', 'jakroomy.os', 'johnsonfitness.os', 'jdtstore', 'kalibre.os', 'kastking.os', 'kingdomfishing.my', 'kingsmith.os', 'kshbicycle.os', 'kuckreja.os', 'kawasakibadmintonmalaysia', 'lasonaofficial.my', 'lining.os', 'litepro.my', 'lixada.os', 'lpmy.os', 'lpm.os', 'montanic.os', 'matsumotostore', 'mavllos.os', 'maxboltmy', 'maxfind.os', 'maxx.os', 'mobigarden.os', 'mcdavidmy.os', 'minelabmalaysia', 'mobigarden.kj.os', 'spacey.os', 'montbell.os', 'monton.malaysia.os', 'moonaz.os', 'naturehike.os', 'naturehikeglobal.my', 'langgou.my', 'newbalancemy.os', 'nicronmy', 'ogevkin.my', 'ogawacorp.', 'ogival.os', 'one.two.fit', 'onetwofitofficial.my', 'originalclassicmy.os', 'ortuseightofficialshop.os', 'osprey.os', 'exploreroutfitter.os', 'outpost.os', 'outsidemy.os', 'outtobe.os', 'ovicx.os', 'peak.os', 'peaksportsmy.os', 'pgmgolf.os', 'pinknproper.os', 'prestigesports.os', 'proapparel.os', 'probiker.my', 'pronic.os', 'prosun.os', 'protech.os', 'protechbysupercourt', 'prspsports', 'pumamy.os', 'purefishingmalaysia.os', 'rcl.os', 'rainbowstyle333.os', 'rapalamy.os', 'reechooutdoor.my', 'rigidfitness.os', 'ripcurlmy.os', 'rockbros.os', 'cycling1.my', 'rstaichi.os', 'runninglabmy.os', 'oceansportmy', 's2hcyclemall.os', 'salomonmy.os', 'sanctbandactive.os', 'santic.os', 'seahawkfishing.os', 'selleitaliamalaysia', 'shimanomalaysiacycling.os', 'shimanofishingmy.os', 'shipwreckskateboards.os', 'skelcoremy.os', 'kelvenchang.os', 'slmbicycle.os', 'smilingshark.os', 'xunmenglong.my', 'sneakerlabmy.os', 'snugsport.os', 'sofirnlight.my', 'sougayilang.os', 'sparkprotein.os', 'whaledream563', 'speedoofficial.os', 'sportplanet.os', 'sportsdirectmy.os', 'stridermalaysia.os', 'sunparadisemy', '18138419167.my', 'swimfitmy.os', 'themarathonshop.os', 'thenorthfacemy.os', 'tankebicycle.os', 'tcetacklesestore', 'tecnifibremy', 'tenxionofficial.os', 'cinemark0621.os', 'thirddayco.os', 'thkfish.os', 'treesandsunoutdoor', 'trs.os', 'trudivemalaysiasingapore', 'tulldent.os', 'twinbrothers.os', 'underarmourmy.os', 'uponumbrella.os', 'uscamel1.my', 'velo88.os', 'victorbysinma', 'victormalaysia.os', 'victorinox.os', 'vigorfitness.os', 'viq.os', 'vsmash.os', 'warrixofficialju.my', 'westbiking.os', 'worldofsports.os', 'xtiger.os', 'xcorefitness.os', 'xinpower.os', 'xiom.os', 'xtep.os', 'yinhe.os', 'yonex.os', 'youngofficial.os', 'zeromarketplace', 'zttobike.my', '2xu.os', '361degrees.os', '910sportswear.os',
];
$category = Category::where('country_locale_slug','my')->where('name','Fitness')->first();
$category = Category::where('country_locale_slug', 'my')->where('name', 'Fitness')->first();
foreach ($shopee_sellers as $seller)
{
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $seller;
$shopee_seller_category->category_id = $category->id;
$shopee_seller_category->save();
}
foreach ($shopee_sellers as $seller) {
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $seller;
$shopee_seller_category->category_id = $category->id;
$shopee_seller_category->save();
}
}
}

View File

@@ -4,7 +4,6 @@
use App\Models\Category;
use App\Models\ShopeeSellerCategory;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ShopeeHealthCategorySeeder extends Seeder
@@ -14,290 +13,289 @@ class ShopeeHealthCategorySeeder extends Seeder
*/
public function run(): void
{
$shopee_sellers = [
'isawmedical',
'rochediagnostic.digital.my',
'euyansang.os',
'a27139200.os',
'abbioticsmy.os',
'agnutrition.os',
'airinummy',
'activelifemalaysia',
'alpro',
'apexpharmacy',
'appeton.os',
'ash2.os',
'a.plus.os',
'babybee.os',
'backjoymalaysia',
'bamnatural',
'bardox.co',
'bayerconsumerhealth.os',
'bengkungmedikalturki',
'benourish.os',
'berryc.hq',
'bhbhealth',
'feeksempire.os',
'biogro',
'bioaquacelmalaysia',
'biolife.malaysia',
'biocareofficialstore',
'biogreenofficial',
'biogrow.os',
'bioley.os',
'bloomylotus.os',
'bloomfood.co',
'bonlife.os',
'bgdrug.os',
'morehope.my',
'comvita.os',
'caremarkofficial.os',
'catalo.os',
'certaintyofficialstore',
'champs.os',
'changefit.os',
'cleverinmalaysia',
'care.os',
'capkakitiga.os',
'callie.os',
'cosway.os',
'durex.os',
'comfier.my',
'coreblueepro',
'curaproxmy',
'darco.os',
'deeyeo.os',
'dermaltherapy.os',
'dettol.os',
'dfenze',
'deltamart.os',
'ntpm.my',
'doctoroncall.os',
'drbei.os',
'drclo.os',
'dr.elizabeths',
'dr.isla.my',
'dr.isla',
'drmoshealthcaresdnbhd',
'duopharma.os',
'easytomorrowmy',
'egreenbeans',
'eldonhealthcare.os',
'elkenofficial',
'empromalaysia',
'eucapro.os',
'ezywipes.os',
'extreme.my',
'finefoodsmy.os',
'freestylelibre.os',
'wiproconsumercare.my',
'gazillionnutrition.os',
'gintell',
'gkbio.official.store',
'gote.club',
'grapeking.os',
'greencyh.os',
'grnkorea.os',
'guardian.os',
'soapberrygubao.os',
'halagelmalaysia',
'hanamedicofficial',
'hannaancient.my.os',
'hansaplast.my',
'pgstoremy',
'healthlanefamilypharmacy',
'hansherbs',
'haoyikangmy',
'supreprobiotics',
'healnutrition.os',
'herbalfarmer',
'healthparadise.os',
'healthyhugqn.my',
'nhdetoxlim.os',
'herbion.os',
'herbsofgold.os',
'hoyanhor',
'houmhygiene',
'hovidnutriworld',
'wyatt760513.os',
'horigenmy.my',
'homecareshop.os',
'holy.shopee.my',
'himalayamalaysia',
'himalaya.natural',
'hh.herbhealth.os',
'itsuworld.os',
'ideal.beauty.alliance88',
'idsmedmalaysia',
'ihoco',
'imfrom.my',
'incrediwear.os',
'insmartofficialstore.my',
'isoderm.os',
'jamujelita.my',
'a0907512010.os',
'jinkairui.os',
'jointwell',
'jordan.os',
'joyofoiling',
'jsnhorizon',
'jt0886.os',
'jynns.os',
'kacangmacha.os',
'kalbe.my',
'kcare.os',
'kedaidiabetes.luka',
'kedaimasalahlututkaki',
'kinohimitsu.os',
'kitsui.my.hq',
'kobee.os',
'huggies.os',
'labelletea51.my',
'laohuangju.os',
'lennox.os',
'vinegarbless.my',
'lifespace.os',
'lifespaceofficial.my.my',
'loveearth.os',
'unilevermy',
'mirafilzah.os',
'lushproteinmy',
'm2.os',
'manfortlab',
'mariafaridasignature.os',
'medicos.os',
'medicurve',
'mediqtto.os',
'medisanaofficialstore',
'medishield.regretless',
'mf3.os',
'mijep.my',
'mobees.os',
'mpdsummit',
'muscletech.official',
'mutyara.os',
'myprotein.official',
'nestidante.os',
'naamskin',
'nanojapan',
'nanosingaporemy',
'naturahousemalaysia',
'natureswaymy.os',
'neutrovis.os',
'manukahealth.my',
'nitrione.os',
'nixoderm.os',
'nowfoodsofficialmy',
'nulatexmy',
'nutrafem.os',
'nutrione.os',
'nusamedic.os',
'nutriva888',
'nutrixgold.os',
'one.os',
'offen.os',
'ogawacorp.',
'olivenol.os',
'oilypod',
'olo.os',
'earthvitamins.os',
'omron.os',
'onecare.os',
'onetouch.os',
'oppo.os',
'optimumnutrition.os',
'oradexhb',
'organicule',
'orthosoft.os',
'osim.os',
'osteoactiv.os',
'myostricare',
'ostrovit.os',
'p.love.os',
'pghealth.my',
'pandababytw.os',
'pharmanutrihq',
'pharmsvilleofficial.os',
'pk24advanced.os',
'playsafeunlimitedmalaysia',
'popi.os',
'psang.os',
'bloodofficialstoremy',
'purelyb123',
'puremed.os',
'quanstarbiotech.os',
'quinlivan.os',
'rossmax.os',
'rafyaakob.os',
'restore.os',
'rosken.os',
'rtopr.os',
'scitecnutrition.os',
'sambucol.os',
'sanofiofficialstore',
'scentpur.os',
'scseven',
'simply.os',
'sinocare.os',
'kyuwlcdcu5',
'snowfit.os',
'solaray',
'soluxe',
'southerncrescent.malaysia',
'spaceylon.com.my',
'splat.os',
'springhealthofficial',
'functionalfoodclub',
'sunstar.os',
'suubalm.os',
'naturaloptions.os',
'swisseoverseas.os',
'swisse.malaysia',
'tanameraofficial',
'find.us.here.tenga.my',
'tenga.os',
'theaprilab2vq.my',
'therabreath.os',
'theragun.os',
'tigerbalm.os',
'timo1q.os',
'topglove',
'totalimage',
'haniszalikhaofficial',
'tremella.os',
'trudolly.os',
'trulife.os',
'sofnonshop.os',
'tyt1957',
'ujuwon.os',
'unicaremalaysia',
'vitahealth.os',
'vnutripharm.os',
'valens.nutrition',
'vircast.os',
'vitagreen.official.my',
'vitascience.os',
'oujiwalch',
'winwa.os',
'wrightlife.my',
'xkoomy',
'yohopower.os',
'youvitmalaysia',
'yukazan',
'yummihousemy',
'yuwell.os',
'3mlittmann.os',
'medicareproducts',
];
$shopee_sellers = [
'isawmedical',
'rochediagnostic.digital.my',
'euyansang.os',
'a27139200.os',
'abbioticsmy.os',
'agnutrition.os',
'airinummy',
'activelifemalaysia',
'alpro',
'apexpharmacy',
'appeton.os',
'ash2.os',
'a.plus.os',
'babybee.os',
'backjoymalaysia',
'bamnatural',
'bardox.co',
'bayerconsumerhealth.os',
'bengkungmedikalturki',
'benourish.os',
'berryc.hq',
'bhbhealth',
'feeksempire.os',
'biogro',
'bioaquacelmalaysia',
'biolife.malaysia',
'biocareofficialstore',
'biogreenofficial',
'biogrow.os',
'bioley.os',
'bloomylotus.os',
'bloomfood.co',
'bonlife.os',
'bgdrug.os',
'morehope.my',
'comvita.os',
'caremarkofficial.os',
'catalo.os',
'certaintyofficialstore',
'champs.os',
'changefit.os',
'cleverinmalaysia',
'care.os',
'capkakitiga.os',
'callie.os',
'cosway.os',
'durex.os',
'comfier.my',
'coreblueepro',
'curaproxmy',
'darco.os',
'deeyeo.os',
'dermaltherapy.os',
'dettol.os',
'dfenze',
'deltamart.os',
'ntpm.my',
'doctoroncall.os',
'drbei.os',
'drclo.os',
'dr.elizabeths',
'dr.isla.my',
'dr.isla',
'drmoshealthcaresdnbhd',
'duopharma.os',
'easytomorrowmy',
'egreenbeans',
'eldonhealthcare.os',
'elkenofficial',
'empromalaysia',
'eucapro.os',
'ezywipes.os',
'extreme.my',
'finefoodsmy.os',
'freestylelibre.os',
'wiproconsumercare.my',
'gazillionnutrition.os',
'gintell',
'gkbio.official.store',
'gote.club',
'grapeking.os',
'greencyh.os',
'grnkorea.os',
'guardian.os',
'soapberrygubao.os',
'halagelmalaysia',
'hanamedicofficial',
'hannaancient.my.os',
'hansaplast.my',
'pgstoremy',
'healthlanefamilypharmacy',
'hansherbs',
'haoyikangmy',
'supreprobiotics',
'healnutrition.os',
'herbalfarmer',
'healthparadise.os',
'healthyhugqn.my',
'nhdetoxlim.os',
'herbion.os',
'herbsofgold.os',
'hoyanhor',
'houmhygiene',
'hovidnutriworld',
'wyatt760513.os',
'horigenmy.my',
'homecareshop.os',
'holy.shopee.my',
'himalayamalaysia',
'himalaya.natural',
'hh.herbhealth.os',
'itsuworld.os',
'ideal.beauty.alliance88',
'idsmedmalaysia',
'ihoco',
'imfrom.my',
'incrediwear.os',
'insmartofficialstore.my',
'isoderm.os',
'jamujelita.my',
'a0907512010.os',
'jinkairui.os',
'jointwell',
'jordan.os',
'joyofoiling',
'jsnhorizon',
'jt0886.os',
'jynns.os',
'kacangmacha.os',
'kalbe.my',
'kcare.os',
'kedaidiabetes.luka',
'kedaimasalahlututkaki',
'kinohimitsu.os',
'kitsui.my.hq',
'kobee.os',
'huggies.os',
'labelletea51.my',
'laohuangju.os',
'lennox.os',
'vinegarbless.my',
'lifespace.os',
'lifespaceofficial.my.my',
'loveearth.os',
'unilevermy',
'mirafilzah.os',
'lushproteinmy',
'm2.os',
'manfortlab',
'mariafaridasignature.os',
'medicos.os',
'medicurve',
'mediqtto.os',
'medisanaofficialstore',
'medishield.regretless',
'mf3.os',
'mijep.my',
'mobees.os',
'mpdsummit',
'muscletech.official',
'mutyara.os',
'myprotein.official',
'nestidante.os',
'naamskin',
'nanojapan',
'nanosingaporemy',
'naturahousemalaysia',
'natureswaymy.os',
'neutrovis.os',
'manukahealth.my',
'nitrione.os',
'nixoderm.os',
'nowfoodsofficialmy',
'nulatexmy',
'nutrafem.os',
'nutrione.os',
'nusamedic.os',
'nutriva888',
'nutrixgold.os',
'one.os',
'offen.os',
'ogawacorp.',
'olivenol.os',
'oilypod',
'olo.os',
'earthvitamins.os',
'omron.os',
'onecare.os',
'onetouch.os',
'oppo.os',
'optimumnutrition.os',
'oradexhb',
'organicule',
'orthosoft.os',
'osim.os',
'osteoactiv.os',
'myostricare',
'ostrovit.os',
'p.love.os',
'pghealth.my',
'pandababytw.os',
'pharmanutrihq',
'pharmsvilleofficial.os',
'pk24advanced.os',
'playsafeunlimitedmalaysia',
'popi.os',
'psang.os',
'bloodofficialstoremy',
'purelyb123',
'puremed.os',
'quanstarbiotech.os',
'quinlivan.os',
'rossmax.os',
'rafyaakob.os',
'restore.os',
'rosken.os',
'rtopr.os',
'scitecnutrition.os',
'sambucol.os',
'sanofiofficialstore',
'scentpur.os',
'scseven',
'simply.os',
'sinocare.os',
'kyuwlcdcu5',
'snowfit.os',
'solaray',
'soluxe',
'southerncrescent.malaysia',
'spaceylon.com.my',
'splat.os',
'springhealthofficial',
'functionalfoodclub',
'sunstar.os',
'suubalm.os',
'naturaloptions.os',
'swisseoverseas.os',
'swisse.malaysia',
'tanameraofficial',
'find.us.here.tenga.my',
'tenga.os',
'theaprilab2vq.my',
'therabreath.os',
'theragun.os',
'tigerbalm.os',
'timo1q.os',
'topglove',
'totalimage',
'haniszalikhaofficial',
'tremella.os',
'trudolly.os',
'trulife.os',
'sofnonshop.os',
'tyt1957',
'ujuwon.os',
'unicaremalaysia',
'vitahealth.os',
'vnutripharm.os',
'valens.nutrition',
'vircast.os',
'vitagreen.official.my',
'vitascience.os',
'oujiwalch',
'winwa.os',
'wrightlife.my',
'xkoomy',
'yohopower.os',
'youvitmalaysia',
'yukazan',
'yummihousemy',
'yuwell.os',
'3mlittmann.os',
'medicareproducts',
];
$category = Category::where('country_locale_slug','my')->where('name','Health')->first();
$category = Category::where('country_locale_slug', 'my')->where('name', 'Health')->first();
foreach ($shopee_sellers as $seller)
{
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $seller;
$shopee_seller_category->category_id = $category->id;
$shopee_seller_category->save();
}
foreach ($shopee_sellers as $seller) {
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $seller;
$shopee_seller_category->category_id = $category->id;
$shopee_seller_category->save();
}
}
}

View File

@@ -4,7 +4,6 @@
use App\Models\Category;
use App\Models\ShopeeSellerCategory;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
class ShopeeHomeLivingCategorySeeder extends Seeder
@@ -14,17 +13,16 @@ class ShopeeHomeLivingCategorySeeder extends Seeder
*/
public function run(): void
{
$shopee_sellers = ["aands.os", "acerpure.os", "acsonmalaysia.os", "aicook.my", "airbotmalaysia", "alphaofficialstore", "aolonmalaysia.os", "aolon.os", "aqara.os", "bacony.my", "bearofficialstore.os", "butterflymalaysia.os", "bacfree.os", "bearglobal.my", "beko.os", "bestdenkimy", "biolomix.os", "biolomixlocal.my", "bissellmy", "blueair.os", "boschhomeappliancesmy.os", "boschmy", "bossmankaden", "brunomalaysia", "corvan.os", "charlcomy", "chiqmalaysia", "valeo.os", "cookraze", "cornell.os", "cosori.os", "courts.os", "cuckoo.os", "delonghi.os", "desahome.os", "daikinmy.os", "daytech.os", "deerma.malaysia", "delfino.os", "amazefanbrandshop.my", "delonghi.os", "panasonic888.os", "deroma.os", "dibea.os", "domus18", "dreamecopperconnect", "dreamemy.os", "officialdysonstore", "ecoluxemalaysia", "ecovacs.os", "edgewall.os", "eksexprez", "elba.os", "electricalshopmy", "electrolux.os", "electrova", "shinghing", "erainetmy", "eroc.my", "etouchplus.os", "europlus.os", "ezilah.os", "faber.os", "fanzomalaysia", "fotile.os", "gaabor.os", "gell.os", "giselleha", "gogeousofficial", "haier.os", "hanriver.malaysia.my", "hanriver.official", "hanabishi.os", "haniertv", "hatarimalaysia", "hericaine.os", "hetch", "hibrew.os", "hiconos", "hiraki.os", "hisensecertifiedstore.os", "hitachi.os", "homeessentialmall.os", "hitec.os", "hizero.os", "hodekt.official.my", "homeessentialmall.os", "huashengonlineshop", "huromofficial", "igadgets", "ilife.os", "imaxx", "innofoodstore", "instantpot.os", "irisohyama.os", "irobot.os", "isonicofficialstore", "jabenmalaysia", "jafairsolution.os", "jamaystore.my", "jeeteemalaysia.os", "jhhomeappliances", "jimmy.os", "jisulife.my", "wendykao.os", "joyamios", "tenkaryohin", "kadonio.my", "kaizendenkimy", "baolijie123.my", "kgcadvance", "khind.os", "khindborneo.os", "kimviento.os", "kimviento.my", "kitchenaid.os", "konkacreative", "konkadirect.os", "kpielectrical", "kronoshop", "kuvings.os", "lebensstil.os", "lemax.official", "levoit.os", "lg.os", "lionmas", "morphyrichards.os", "mayer.os", "morgan.kings", "mbh.os", "maxiestore", "maxiestore", "meckmy.os", "megraos", "miui.os", "mmxmalaysia", "muzen.os", "nakadagroup.os", "mynarwal", "nescafedolcegusto.os", "nesh.os", "sharkninjaofficial", "njoi.os", "norviamalaysia", "olayksmy.os", "onehomeappliance", "itsasomarketing", "onemoon.os", "philips.my", "panasonic.malaysia", "panasonic.authorised.partner", "panasonic.elite", "panasonic.partner", "panasonicsignaturemall", "pensonic", "pensonic", "perysmith", "philipstv.os", "picogram.os", "proscenic.os", "retekess.my", "rezo.os", "riino.os", "rinnai.os", "robam.os", "roborockmalaysia", "rubine.os", "russelltaylors.os", "selamat.os", "sonystore.os", "sakura.os", "samsungappliancesos", "samsungbrandstoremy.os", "samugiken.os", "samview.os", "sanus.os", "scottmiller", "sensonic.my", "shibuifujiaire", "shimonomalaysia.os", "simplusmalaysia", "sincero.os", "singermy", "skmagicmy.os", "skyworth.os", "smartlifestyle99", "smartmi.os", "snfonline", "sodaxpress", "soundteohmy.os", "sterramy", "sunatur", "sureloc.os", "swissthomas.os", "switchbot.os", "tbm.os", "tanradio.com", "tanradio.com", "tcl.os", "thebaker.os", "thermomixmalaysia", "tineco.os", "tjean.os", "tonze.my", "toshibatv.os", "urban.home", "uwantmalaysia", "vcomm.os", "viewsonic.os", "vizon.os", "yeedi.os", "yetair", "yilizomana.os", "360smartlife.os"
];
$shopee_sellers = ['aands.os', 'acerpure.os', 'acsonmalaysia.os', 'aicook.my', 'airbotmalaysia', 'alphaofficialstore', 'aolonmalaysia.os', 'aolon.os', 'aqara.os', 'bacony.my', 'bearofficialstore.os', 'butterflymalaysia.os', 'bacfree.os', 'bearglobal.my', 'beko.os', 'bestdenkimy', 'biolomix.os', 'biolomixlocal.my', 'bissellmy', 'blueair.os', 'boschhomeappliancesmy.os', 'boschmy', 'bossmankaden', 'brunomalaysia', 'corvan.os', 'charlcomy', 'chiqmalaysia', 'valeo.os', 'cookraze', 'cornell.os', 'cosori.os', 'courts.os', 'cuckoo.os', 'delonghi.os', 'desahome.os', 'daikinmy.os', 'daytech.os', 'deerma.malaysia', 'delfino.os', 'amazefanbrandshop.my', 'delonghi.os', 'panasonic888.os', 'deroma.os', 'dibea.os', 'domus18', 'dreamecopperconnect', 'dreamemy.os', 'officialdysonstore', 'ecoluxemalaysia', 'ecovacs.os', 'edgewall.os', 'eksexprez', 'elba.os', 'electricalshopmy', 'electrolux.os', 'electrova', 'shinghing', 'erainetmy', 'eroc.my', 'etouchplus.os', 'europlus.os', 'ezilah.os', 'faber.os', 'fanzomalaysia', 'fotile.os', 'gaabor.os', 'gell.os', 'giselleha', 'gogeousofficial', 'haier.os', 'hanriver.malaysia.my', 'hanriver.official', 'hanabishi.os', 'haniertv', 'hatarimalaysia', 'hericaine.os', 'hetch', 'hibrew.os', 'hiconos', 'hiraki.os', 'hisensecertifiedstore.os', 'hitachi.os', 'homeessentialmall.os', 'hitec.os', 'hizero.os', 'hodekt.official.my', 'homeessentialmall.os', 'huashengonlineshop', 'huromofficial', 'igadgets', 'ilife.os', 'imaxx', 'innofoodstore', 'instantpot.os', 'irisohyama.os', 'irobot.os', 'isonicofficialstore', 'jabenmalaysia', 'jafairsolution.os', 'jamaystore.my', 'jeeteemalaysia.os', 'jhhomeappliances', 'jimmy.os', 'jisulife.my', 'wendykao.os', 'joyamios', 'tenkaryohin', 'kadonio.my', 'kaizendenkimy', 'baolijie123.my', 'kgcadvance', 'khind.os', 'khindborneo.os', 'kimviento.os', 'kimviento.my', 'kitchenaid.os', 'konkacreative', 'konkadirect.os', 'kpielectrical', 'kronoshop', 'kuvings.os', 'lebensstil.os', 'lemax.official', 'levoit.os', 'lg.os', 'lionmas', 'morphyrichards.os', 'mayer.os', 'morgan.kings', 'mbh.os', 'maxiestore', 'maxiestore', 'meckmy.os', 'megraos', 'miui.os', 'mmxmalaysia', 'muzen.os', 'nakadagroup.os', 'mynarwal', 'nescafedolcegusto.os', 'nesh.os', 'sharkninjaofficial', 'njoi.os', 'norviamalaysia', 'olayksmy.os', 'onehomeappliance', 'itsasomarketing', 'onemoon.os', 'philips.my', 'panasonic.malaysia', 'panasonic.authorised.partner', 'panasonic.elite', 'panasonic.partner', 'panasonicsignaturemall', 'pensonic', 'pensonic', 'perysmith', 'philipstv.os', 'picogram.os', 'proscenic.os', 'retekess.my', 'rezo.os', 'riino.os', 'rinnai.os', 'robam.os', 'roborockmalaysia', 'rubine.os', 'russelltaylors.os', 'selamat.os', 'sonystore.os', 'sakura.os', 'samsungappliancesos', 'samsungbrandstoremy.os', 'samugiken.os', 'samview.os', 'sanus.os', 'scottmiller', 'sensonic.my', 'shibuifujiaire', 'shimonomalaysia.os', 'simplusmalaysia', 'sincero.os', 'singermy', 'skmagicmy.os', 'skyworth.os', 'smartlifestyle99', 'smartmi.os', 'snfonline', 'sodaxpress', 'soundteohmy.os', 'sterramy', 'sunatur', 'sureloc.os', 'swissthomas.os', 'switchbot.os', 'tbm.os', 'tanradio.com', 'tanradio.com', 'tcl.os', 'thebaker.os', 'thermomixmalaysia', 'tineco.os', 'tjean.os', 'tonze.my', 'toshibatv.os', 'urban.home', 'uwantmalaysia', 'vcomm.os', 'viewsonic.os', 'vizon.os', 'yeedi.os', 'yetair', 'yilizomana.os', '360smartlife.os',
];
$category = Category::where('country_locale_slug','my')->where('name','Home & Living')->first();
$category = Category::where('country_locale_slug', 'my')->where('name', 'Home & Living')->first();
foreach ($shopee_sellers as $seller)
{
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $seller;
$shopee_seller_category->category_id = $category->id;
$shopee_seller_category->save();
}
foreach ($shopee_sellers as $seller) {
$shopee_seller_category = new ShopeeSellerCategory;
$shopee_seller_category->seller = $seller;
$shopee_seller_category->category_id = $category->id;
$shopee_seller_category->save();
}
}
}

File diff suppressed because it is too large Load Diff

12
dev.sh
View File

@@ -6,13 +6,5 @@ eval 'php artisan optimize:clear';
eval 'php artisan ziggy:generate';
eval 'blade-formatter --write resources/**/*.blade.php';
eval './vendor/bin/pint';
# eval 'npm run dev';
tmux \
new-session 'npm run dev' \; \
# split-window 'php artisan queue:work' \; \
# split-window 'php artisan schedule:work' \; \
# split-window 'php artisan horizon' \; \
# new-window \; \
# detach-client
tmux a
eval "eval 'find . -name '.DS_Store' -type f -exec rm {} +'";
eval 'npm run dev';

View File

@@ -1,6 +1,7 @@
#!/bin/bash
eval 'APP_URL=https://productalert.co php artisan ziggy:generate';
eval 'APP_URL=https://aibuddytool.com php artisan ziggy:generate';
eval 'blade-formatter --write resources/**/*.blade.php';
eval './vendor/bin/pint';
eval "eval 'find . -name '.DS_Store' -type f -exec rm {} +'";
eval 'npm run build';

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 630 B

After

Width:  |  Height:  |  Size: 561 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

BIN
public/icon-128x128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
public/icon-144x144.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
public/icon-152x152.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
public/icon-192x192.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
public/icon-384x384.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
public/icon-48x48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

BIN
public/icon-512x512.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
public/icon-570x570.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
public/icon-72x72.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/icon-96x96.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
resources/.DS_Store vendored

Binary file not shown.

View File

@@ -1,4 +1,4 @@
const Ziggy = {"url":"https:\/\/productalert.co","port":null,"defaults":{},"routes":{"debugbar.openhandler":{"uri":"_debugbar\/open","methods":["GET","HEAD"]},"debugbar.clockwork":{"uri":"_debugbar\/clockwork\/{id}","methods":["GET","HEAD"]},"debugbar.assets.css":{"uri":"_debugbar\/assets\/stylesheets","methods":["GET","HEAD"]},"debugbar.assets.js":{"uri":"_debugbar\/assets\/javascript","methods":["GET","HEAD"]},"debugbar.cache.delete":{"uri":"_debugbar\/cache\/{key}\/{tags?}","methods":["DELETE"]},"sanctum.csrf-cookie":{"uri":"sanctum\/csrf-cookie","methods":["GET","HEAD"]},"ignition.healthCheck":{"uri":"_ignition\/health-check","methods":["GET","HEAD"]},"ignition.executeSolution":{"uri":"_ignition\/execute-solution","methods":["POST"]},"ignition.updateConfig":{"uri":"_ignition\/update-config","methods":["POST"]},"api.auth.login.post":{"uri":"api\/login","methods":["POST"]},"api.auth.logout.post":{"uri":"api\/logout","methods":["POST"]},"api.admin.post.get":{"uri":"api\/admin\/post\/{id}","methods":["GET","HEAD"]},"api.admin.country-locales":{"uri":"api\/admin\/country-locales","methods":["GET","HEAD"]},"api.admin.categories":{"uri":"api\/admin\/categories\/{country_locale_slug}","methods":["GET","HEAD"]},"api.admin.authors":{"uri":"api\/admin\/authors","methods":["GET","HEAD"]},"api.admin.upload.cloud.image":{"uri":"api\/admin\/image\/upload","methods":["POST"]},"api.admin.post.upsert":{"uri":"api\/admin\/admin\/post\/upsert","methods":["POST"]},"feeds.main":{"uri":"posts.rss","methods":["GET","HEAD"]},"login":{"uri":"login","methods":["GET","HEAD"]},"logout":{"uri":"logout","methods":["POST"]},"register":{"uri":"register","methods":["GET","HEAD"]},"password.request":{"uri":"password\/reset","methods":["GET","HEAD"]},"password.email":{"uri":"password\/email","methods":["POST"]},"password.reset":{"uri":"password\/reset\/{token}","methods":["GET","HEAD"]},"password.update":{"uri":"password\/reset","methods":["POST"]},"password.confirm":{"uri":"password\/confirm","methods":["GET","HEAD"]},"dashboard":{"uri":"admin","methods":["GET","HEAD"]},"admin.changelog":{"uri":"admin\/changelog","methods":["GET","HEAD"]},"about":{"uri":"admin\/about","methods":["GET","HEAD"]},"users.index":{"uri":"admin\/users","methods":["GET","HEAD"]},"posts.manage":{"uri":"admin\/posts","methods":["GET","HEAD"]},"posts.manage.edit":{"uri":"admin\/posts\/edit\/{post_id}","methods":["GET","HEAD"]},"posts.manage.delete":{"uri":"admin\/posts\/delete\/{post_id}","methods":["GET","HEAD"]},"posts.manage.indexing":{"uri":"admin\/posts\/indexing\/{post_id}","methods":["GET","HEAD"]},"posts.manage.new":{"uri":"admin\/posts\/new","methods":["GET","HEAD"]},"profile.show":{"uri":"admin\/profile","methods":["GET","HEAD"]},"profile.update":{"uri":"admin\/profile","methods":["PUT"]},"home":{"uri":"\/","methods":["GET","HEAD"]},"home.country":{"uri":"{country}","methods":["GET","HEAD"]},"home.country.posts":{"uri":"{country}\/posts","methods":["GET","HEAD"]},"home.country.post":{"uri":"{country}\/posts\/{post_slug}","methods":["GET","HEAD"]},"home.country.category":{"uri":"{country}\/{category}","methods":["GET","HEAD"]}}};
const Ziggy = {"url":"https:\/\/aibuddytool.test","port":null,"defaults":{},"routes":{"debugbar.openhandler":{"uri":"_debugbar\/open","methods":["GET","HEAD"]},"debugbar.clockwork":{"uri":"_debugbar\/clockwork\/{id}","methods":["GET","HEAD"]},"debugbar.assets.css":{"uri":"_debugbar\/assets\/stylesheets","methods":["GET","HEAD"]},"debugbar.assets.js":{"uri":"_debugbar\/assets\/javascript","methods":["GET","HEAD"]},"debugbar.cache.delete":{"uri":"_debugbar\/cache\/{key}\/{tags?}","methods":["DELETE"]},"sanctum.csrf-cookie":{"uri":"sanctum\/csrf-cookie","methods":["GET","HEAD"]},"ignition.healthCheck":{"uri":"_ignition\/health-check","methods":["GET","HEAD"]},"ignition.executeSolution":{"uri":"_ignition\/execute-solution","methods":["POST"]},"ignition.updateConfig":{"uri":"_ignition\/update-config","methods":["POST"]},"api.auth.login.post":{"uri":"api\/login","methods":["POST"]},"api.auth.logout.post":{"uri":"api\/logout","methods":["POST"]},"api.admin.post.get":{"uri":"api\/admin\/post\/{id}","methods":["GET","HEAD"]},"api.admin.country-locales":{"uri":"api\/admin\/country-locales","methods":["GET","HEAD"]},"api.admin.categories":{"uri":"api\/admin\/categories\/{country_locale_slug}","methods":["GET","HEAD"]},"api.admin.authors":{"uri":"api\/admin\/authors","methods":["GET","HEAD"]},"api.admin.upload.cloud.image":{"uri":"api\/admin\/image\/upload","methods":["POST"]},"api.admin.post.upsert":{"uri":"api\/admin\/admin\/post\/upsert","methods":["POST"]},"feeds.main":{"uri":"posts.rss","methods":["GET","HEAD"]},"login":{"uri":"login","methods":["GET","HEAD"]},"logout":{"uri":"logout","methods":["POST"]},"register":{"uri":"register","methods":["GET","HEAD"]},"password.request":{"uri":"password\/reset","methods":["GET","HEAD"]},"password.email":{"uri":"password\/email","methods":["POST"]},"password.reset":{"uri":"password\/reset\/{token}","methods":["GET","HEAD"]},"password.update":{"uri":"password\/reset","methods":["POST"]},"password.confirm":{"uri":"password\/confirm","methods":["GET","HEAD"]},"dashboard":{"uri":"admin","methods":["GET","HEAD"]},"admin.changelog":{"uri":"admin\/changelog","methods":["GET","HEAD"]},"about":{"uri":"admin\/about","methods":["GET","HEAD"]},"users.index":{"uri":"admin\/users","methods":["GET","HEAD"]},"posts.manage":{"uri":"admin\/posts","methods":["GET","HEAD"]},"posts.manage.edit":{"uri":"admin\/posts\/edit\/{post_id}","methods":["GET","HEAD"]},"posts.manage.delete":{"uri":"admin\/posts\/delete\/{post_id}","methods":["GET","HEAD"]},"posts.manage.indexing":{"uri":"admin\/posts\/indexing\/{post_id}","methods":["GET","HEAD"]},"posts.manage.new":{"uri":"admin\/posts\/new","methods":["GET","HEAD"]},"profile.show":{"uri":"admin\/profile","methods":["GET","HEAD"]},"profile.update":{"uri":"admin\/profile","methods":["PUT"]},"home":{"uri":"\/","methods":["GET","HEAD"]}}};
if (typeof window !== 'undefined' && typeof window.Ziggy !== 'undefined') {
Object.assign(Ziggy.routes, window.Ziggy.routes);

View File

@@ -30,7 +30,7 @@ $grays: (
"600": $gray-600,
"700": $gray-700,
"800": $gray-800,
"900": $gray-900
"900": $gray-900,
);
// scss-docs-end gray-colors-map
// fusv-enable
@@ -63,7 +63,7 @@ $colors: (
"black": $black,
"white": $white,
"gray": $gray-600,
"gray-dark": $gray-800
"gray-dark": $gray-800,
);
// scss-docs-end colors-map
@@ -185,7 +185,7 @@ $blues: (
"blue-600": $blue-600,
"blue-700": $blue-700,
"blue-800": $blue-800,
"blue-900": $blue-900
"blue-900": $blue-900,
);
$indigos: (
@@ -197,7 +197,7 @@ $indigos: (
"indigo-600": $indigo-600,
"indigo-700": $indigo-700,
"indigo-800": $indigo-800,
"indigo-900": $indigo-900
"indigo-900": $indigo-900,
);
$purples: (
@@ -209,7 +209,7 @@ $purples: (
"purple-600": $purple-600,
"purple-700": $purple-700,
"purple-800": $purple-800,
"purple-900": $purple-900
"purple-900": $purple-900,
);
$pinks: (
@@ -221,7 +221,7 @@ $pinks: (
"pink-600": $pink-600,
"pink-700": $pink-700,
"pink-800": $pink-800,
"pink-900": $pink-900
"pink-900": $pink-900,
);
$reds: (
@@ -233,7 +233,7 @@ $reds: (
"red-600": $red-600,
"red-700": $red-700,
"red-800": $red-800,
"red-900": $red-900
"red-900": $red-900,
);
$oranges: (
@@ -245,7 +245,7 @@ $oranges: (
"orange-600": $orange-600,
"orange-700": $orange-700,
"orange-800": $orange-800,
"orange-900": $orange-900
"orange-900": $orange-900,
);
$yellows: (
@@ -257,7 +257,7 @@ $yellows: (
"yellow-600": $yellow-600,
"yellow-700": $yellow-700,
"yellow-800": $yellow-800,
"yellow-900": $yellow-900
"yellow-900": $yellow-900,
);
$greens: (
@@ -269,7 +269,7 @@ $greens: (
"green-600": $green-600,
"green-700": $green-700,
"green-800": $green-800,
"green-900": $green-900
"green-900": $green-900,
);
$teals: (
@@ -281,7 +281,7 @@ $teals: (
"teal-600": $teal-600,
"teal-700": $teal-700,
"teal-800": $teal-800,
"teal-900": $teal-900
"teal-900": $teal-900,
);
$cyans: (
@@ -293,12 +293,12 @@ $cyans: (
"cyan-600": $cyan-600,
"cyan-700": $cyan-700,
"cyan-800": $cyan-800,
"cyan-900": $cyan-900
"cyan-900": $cyan-900,
);
// fusv-enable
// scss-docs-start theme-color-variables
$primary: $red;
$primary: $blue;
$secondary: $gray-600;
$success: $green;
$info: $cyan;
@@ -317,6 +317,6 @@ $theme-colors: (
"warning": $warning,
"danger": $danger,
"light": $light,
"dark": $dark
"dark": $dark,
);
// scss-docs-end theme-colors-map

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,52 @@
@extends('layouts.front.app')
@section('content')
<div class="container-lg py-3">
<div class="row justify-content-center text-center">
<div class="col-12 col-md-8 col-lg-6 col-xl-5">
<h2>Find the perfect AI tool for every task</h2>
<p>Elevate productivity with XXX+ AI tools & growing 🚀</p>
<br>
<form class="d-flex" role="search">
<input class="rounded-pill form-control me-2" type="search" placeholder="Search" aria-label="Search"
control-id="ControlID-1">
<button class="rounded-pill btn btn-primary px-4 fw-bold" type="submit" control-id="ControlID-2">
<span class=" mb-0">Search</span>
</button>
</form>
<br>
</div>
</div>
<div class="row justify-content-center mb-4">
<div class="col-12 col-md-10 col-lg-9 col-xl-8 text-center">
<span class="fw-bold">Explore AI Tools: </span>
@for ($i = 1; $i <= 20; $i++)
<a href="#"
class="btn btn-outline-primary border-1 fw-bold border-primary rounded-pill px-3 btn-sm mb-1">Category
{{ $i }}</a>
@endfor
</div>
</div>
<h3 class="text-center fw-bold">Latest AI Tools</h3>
<div class="row justify-content-center g-3 mb-4">
@for ($i = 1; $i <= 8; $i++)
<div class="col-12 col-md-6 col-lg-4">
<div class="card">
<img src="https://placekitten.com/1024/576" class="card-img-top" alt="...">
<div class="card-body">
<h4 class="fw-bold"><a href="#">AI Tool {{ $i }}</a></h4>
<p>Template Prompts is a private AI prompts library that allows templates so you can reuse
prompts acro..</p>
</div>
</div>
</div>
@endfor
</div>
<div class="w-100 text-center">
<a href="#" class="btn btn-primary rounded-pill px-4">Explore XXXX+ AI Tools</a>
</div>
</div>
@endsection

Binary file not shown.

View File

@@ -18,7 +18,7 @@
<link rel="apple-touch-icon" sizes="180x180" href="{{ asset('apple-touch-icon.png') }}">
<link rel="icon" type="image/png" sizes="32x32" href="{{ asset('favicon-32x32.png') }}">
<link rel="icon" type="image/png" sizes="16x16" href="{{ asset('favicon-16x16.png') }}">
<link rel="manifest" href="{{ asset('site.webmanifest')}}">
<link rel="manifest" href="{{ asset('site.webmanifest') }}">
@vite('resources/sass/front-app.scss')

View File

@@ -1,69 +1,7 @@
<div class="container-fluid border-top">
<footer class="py-5 container">
<div class="row justify-content-center">
<div class="col-6 col-md-2 mb-3">
<ul class="nav flex-column">
@foreach ($categories as $category)
@if ($category->id % 2 == 0)
<li class="nav-item mb-2">
<a class="nav-link p-0 text-body-secondary"
href="{{ route('home.country.category', ['country' => $category->country_locale_slug, 'category' => $category->slug]) }}">{{ $category->name }}</a>
</li>
@endif
@endforeach
</ul>
</div>
<footer class="container-lg">
<div class="col-6 col-md-2 mb-3">
<ul class="nav flex-column">
@foreach ($categories as $category)
@if ($category->id % 2 == 1)
<li class="nav-item mb-2">
<a class="nav-link p-0 text-body-secondary"
href="{{ route('home.country.category', ['country' => $category->country_locale_slug, 'category' => $category->slug]) }}">{{ $category->name }}</a>
</li>
@endif
@endforeach
</ul>
</div>
<div class="col-md-5 mb-3">
@if ($country_locales->count() > 1)
<div class="dropdown mb-4">
<button class="btn btn-outline-primary dropdown-toggle" type="button" id="dropdownMenuSwitch"
data-bs-toggle="dropdown" aria-expanded="false">
{{ $current_country_locale->name }}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuSwitch">
@foreach ($country_locales as $country_locale)
@if ($country_locale->id != $current_country_locale->id)
<li><a class="dropdown-item"
href="{{ route('home.country', [
'country' => $country_locale->slug,
]) }}">{{ $country_locale->name }}</a>
</li>
@endif
@endforeach
</ul>
</div>
@endif
{{-- <form>
<h5>Subscribe to our newsletter</h5>
<p>Monthly digest of what's new and exciting from us.</p>
<div class="d-flex flex-column flex-sm-row w-100 gap-2">
<label for="newsletter1" class="visually-hidden">Email address</label>
<input id="newsletter1" type="disabled" class="form-control disabled" placeholder="Email address">
<button class="btn btn-primary" type="button">Subscribe</button>
</div>
</form> --}}
</div>
</div>
<div class="d-flex flex-column flex-sm-row justify-content-center py-4 my-4">
<div class="d-flex flex-column flex-sm-row justify-content-center pt-3">
<p>© {{ date('Y') }} {{ config('app.name') }}. All rights reserved.</p>
{{-- <ul class="list-unstyled d-flex">
<li class="ms-3"><a class="link-body-emphasis" href="#"><svg class="bi" width="24"

View File

@@ -1,84 +1,13 @@
<div class="container-fluid border-bottom">
<header class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between py-3">
<div class="col-md-3 mb-2 mb-md-0">
<button class="navbar-toggler" type="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbar"
aria-controls="offcanvasNavbar" aria-label="Toggle navigation">
<i class="h4 bi bi-list"></i>
</button>
<div class="offcanvas offcanvas-start" tabindex="-1" id="offcanvasNavbar"
aria-labelledby="offcanvasNavbarLabel">
<div class="offcanvas-header">
<h4 class="offcanvas-title fw-bold mb-0" id="offcanvasNavbarLabel">
{{ config('app.name') }}
{{ str_contains(request()->route()->getName(),'home.country')? get_country_emoji_by_iso($current_country_locale->country_iso): '' }}
</h4>
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body p-0">
<header class="d-flex flex-wrap align-items-center justify-content-center py-3">
<div class="col-auto">
@if ($country_locales->count() > 1)
<div class="p-3">
<div class="dropdown d-grid">
<button class="btn btn-outline-primary dropdown-toggle" type="button"
id="dropdownMenuSwitch" data-bs-toggle="dropdown" aria-expanded="false">
{{ $current_country_locale->name }}
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuSwitch">
@foreach ($country_locales as $country_locale)
@if ($country_locale->id != $current_country_locale->id)
<li><a class="dropdown-item"
href="{{ route('home.country', [
'country' => $country_locale->slug,
]) }}">{{ $country_locale->name }}</a>
</li>
@endif
@endforeach
</ul>
</div>
</div>
<div class="border-bottom"></div>
@endif
<div class="p-3">
<ul class="navbar-nav justify-content-end flex-grow-1 pe-3">
<li class="nav-item">
<a class="nav-link active" aria-current="page"
href="{{ route('home.country', ['country' => $current_country_locale->slug]) }}">Home</a>
</li>
@foreach ($categories as $category)
<li class="nav-item">
<a class="nav-link active" aria-current="page"
href="{{ route('home.country.category', ['country' => $category->country_locale_slug, 'category' => $category->slug]) }}">{{ $category->name }}</a>
</li>
@endforeach
</ul>
</div>
</div>
</div>
<a href="/" class="d-inline-flex link-body-emphasis text-decoration-none">
<a href="/" class="d-inline-flex link-body-emphasis text-decoration-none text-center">
<h1 class="h4 mb-0 fw-bold">
{{ config('app.name') }}
{{ str_contains(request()->route()->getName(),'home.country')? get_country_emoji_by_iso($current_country_locale->country_iso): '' }}
</h1>
</a>
</div>
<ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
@foreach ($categories as $category)
@if ($category->is_top)
<li><a href="{{ route('home.country.category', ['country' => $category->country_locale_slug, 'category' => $category->slug]) }}"
class="nav-link px-2 link-secondary">{{ $category->short_name }}</a></li>
@endif
@endforeach
</ul>
<div class="col-md-3 text-end">
</div>
</header>
</div>

View File

@@ -43,10 +43,10 @@
Route::get('/', [App\Http\Controllers\Front\HomeController::class, 'index'])->name('home');
Route::get('/{country}', [App\Http\Controllers\Front\HomeController::class, 'country'])->name('home.country');
// Route::get('/{country}', [App\Http\Controllers\Front\OldHomeController::class, 'country'])->name('home.country');
Route::get('/{country}/posts', [App\Http\Controllers\Front\HomeController::class, 'all'])->name('home.country.posts');
// Route::get('/{country}/posts', [App\Http\Controllers\Front\OldHomeController::class, 'all'])->name('home.country.posts');
Route::get('/{country}/posts/{post_slug}', [App\Http\Controllers\Front\HomeController::class, 'post'])->name('home.country.post');
// Route::get('/{country}/posts/{post_slug}', [App\Http\Controllers\Front\OldHomeController::class, 'post'])->name('home.country.post');
Route::get('/{country}/{category}', [App\Http\Controllers\Front\HomeController::class, 'countryCategory'])->name('home.country.category');
// Route::get('/{country}/{category}', [App\Http\Controllers\Front\OldHomeController::class, 'countryCategory'])->name('home.country.category');