Products seeded but not showing on frontend
-
I've used the ProductSeeder as a basis to write a custom seeder with our own products . The products are seeded and showing up in the backend but not on the frontend. If I open each individual product and press save, they do show up on the frontend.
Even though the products don't show up on the frontend the filter for the price range does update the range to reflect the cheapest and most expensive product dat should be visible.
I've already tried firing the 'catalog.product.update.after' event, but to no avail.
What am I missing?
-
Hello @MartintheMartian ,
Please share your approach to product seeding (I mean what you override to the database inside your seeder file).
Kindly share some screenshots of your seeder file to which you have made changes...
-
@amit-webkul This is the seeder so far:
<?php namespace Foris\Development\Database\Seeders; use Carbon\Carbon; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Seeder; use Illuminate\Http\File; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Event; use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use Webkul\Attribute\Models\Attribute; use Webkul\Attribute\Models\AttributeOption; use Webkul\CatalogRule\Helpers\CatalogRuleIndex; use Webkul\Category\Models\Category; use Webkul\Installer\Database\Seeders\Category\CategoryTableSeeder; use Webkul\Product\Models\Product; class InternetBikesSeeder extends Seeder { private Collection $importedProducts; private array $attributeTypeFields = [ 'text' => 'text_value', 'textarea' => 'text_value', 'price' => 'float_value', 'boolean' => 'boolean_value', 'select' => 'integer_value', 'multiselect' => 'text_value', 'datetime' => 'datetime_value', 'date' => 'date_value', 'file' => 'text_value', 'image' => 'text_value', 'checkbox' => 'text_value', ]; /** * Run the database seeds. * * @return void */ public function run() { $this->importedProducts = collect(); $parameters = []; DB::table('products')->delete(); DB::table('categories')->delete(); DB::table('product_categories')->delete(); $categoryTableSeeder = new CategoryTableSeeder; $categoryTableSeeder->run($parameters); $categoryTableSeeder->sampleCategories($parameters); Model::unguard(); $xml = simplexml_load_string(Http::get('https://www.******.com/feeds/feed-en.xml')->body(), 'SimpleXMLElement', LIBXML_NOCDATA); $json = json_encode($xml); $array = json_decode($json, true); $inventoryArray = []; $productCategoryArray = []; $productCount = 0; foreach ($array['product'] as $product) { if ($productCount == 5) { continue; } $product['parent_id'] = 0; $this->importedProducts->add($product); $defaultLocale = $parameters['default_locale'] ?? config('app.locale'); $now = Carbon::now(); $locales = $parameters['allowed_locales'] ?? [$defaultLocale]; $localeProductsData = $this->prepareProductsData($locales); $products = Arr::map($localeProductsData[$defaultLocale], function ($row) { return Arr::only($row, ['parent_id', 'sku', 'type', 'attribute_family_id', 'created_at', 'updated_at']); }); DB::table('products')->insert($products); $createdProducts = DB::table('products')->get(); for ($i = 0; $i < count($localeProductsData[$defaultLocale]); $i++) { $localeProductsData[$defaultLocale][$i]['product_id'] = $createdProducts->firstWhere('sku', $localeProductsData[$defaultLocale][$i]['sku'])->id; $imagesArray = []; $productCategoryArray[] = [ 'product_id' => $localeProductsData[$defaultLocale][$i]['product_id'], 'category_id' => Category::whereNotNull('parent_id')->inRandomOrder()->first()->id, ]; $inventoryArray[] = [ 'product_id' => $localeProductsData[$defaultLocale][$i]['product_id'], 'vendor_id' => 0, 'inventory_source_id' => 1, 'qty' => $product['stock'], ]; for ($j = 1; $j < 7; $j++) { if (! is_array($product['image_'.$j])) { $imagesArray[] = [ 'type' => 'image', 'path' => $this->productImages('product/'.$localeProductsData[$defaultLocale][$i]['product_id'], $product['image_'.$j]), 'product_id' => $localeProductsData[$defaultLocale][$i]['product_id'], 'position' => 1, ]; } } DB::table('product_images')->insert($imagesArray); } $attributes = DB::table('attributes')->get(); $productsAttributeValues = []; $attributeValues = []; foreach ($localeProductsData as $locale => $productsData) { $productsFlatData = Arr::map($localeProductsData[$locale], function ($row) { return Arr::except($row, ['color', 'size', 'parent_id']); }); DB::table('product_flat')->insert($productsFlatData); $skipAttributes = [ 'product_id', 'parent_id', 'type', 'attribute_family_id', 'locale', 'channel', 'created_at', 'updated_at', ]; $localeSpecificAttributes = [ 'name', 'url_key', 'short_description', 'description', 'meta_title', 'meta_keywords', 'meta_description', ]; $guestCheckoutAttribute = Attribute::where('code', 'guest_checkout')->first(); foreach ($productsData as $productData) { foreach ($productData as $attributeCode => $value) { if (in_array($attributeCode, $skipAttributes)) { continue; } if ($locale !== 'en' && ! in_array($attributeCode, $localeSpecificAttributes)) { continue; } $attribute = $attributes->where('code', $attributeCode)->first(); $uniqueId = implode('|', array_filter([ $attribute->value_per_channel ? 'default' : null, $attribute->value_per_locale ? $locale : null, $productData['product_id'], $attribute->id, ])); if (array_key_exists($uniqueId, $productsAttributeValues)) { continue; } $attributeTypeValues = array_fill_keys(array_values($this->attributeTypeFields), null); $attributeValues[] = array_merge($attributeTypeValues, [ 'attribute_id' => $attribute->id, 'product_id' => $productData['product_id'], $this->attributeTypeFields[$attribute->type] => $value, 'channel' => $attribute->value_per_channel ? 'default' : null, 'locale' => $attribute->value_per_locale ? $locale : null, 'unique_id' => $uniqueId, 'json_value' => null, ]); } $guestCheckoutAttributeUniqueId = implode('|', array_filter([ $guestCheckoutAttribute->value_per_channel ? 'default' : null, $guestCheckoutAttribute->value_per_locale ? $locale : null, $productData['product_id'], $guestCheckoutAttribute->id, ])); $attributeValues[] = array_merge($attributeTypeValues, [ 'attribute_id' => $guestCheckoutAttribute->id, 'product_id' => $productData['product_id'], 'boolean_value' => 1, 'channel' => 'default', 'locale' => $locale, 'unique_id' => $guestCheckoutAttributeUniqueId, 'json_value' => null, ]); } } DB::table('product_attribute_values')->insert($attributeValues); $productCount++; } DB::table('product_inventories')->insert($inventoryArray); DB::table('product_categories')->insert($productCategoryArray); Model::reguard(); $importedProducts = Product::all(); foreach ($importedProducts as $importedProduct) { $importedProduct->save(); Event::dispatch('catalog.product.update.after', $importedProduct); app(CatalogRuleIndex::class)->reIndexProduct($importedProduct); } echo 'done'.PHP_EOL; } public function prepareProductsData($locales) { $products = []; $currentDate = Carbon::now(); $now = $currentDate->format('Y-m-d H:i:s'); $sizeAttribute = Attribute::where('code', 'size')->first(); $colourAttribute = Attribute::where('code', 'color')->first(); foreach ($locales as $locale) { foreach ($this->importedProducts as $importedProduct) { if (isset($importedProduct['wheelsize'])) { $option = AttributeOption::updateOrCreate([ 'attribute_id' => $sizeAttribute->id, 'admin_name' => $importedProduct['wheelsize'], ], [ 'attribute_id' => $sizeAttribute->id, 'admin_name' => $importedProduct['wheelsize'], ]); $option->translations()->updateOrCreate([ 'label' => $importedProduct['wheelsize'], 'locale' => $locale, ], [ 'label' => $importedProduct['wheelsize'], 'locale' => $locale, ]); $sizeId = $option->id; } if (isset($importedProduct['colour'])) { $option = AttributeOption::updateOrCreate([ 'attribute_id' => $colourAttribute->id, 'admin_name' => Str::before($importedProduct['colour'], ','), ], [ 'attribute_id' => $colourAttribute->id, 'admin_name' => Str::ucfirst(Str::before($importedProduct['colour'], ',')), ]); $option->translations()->updateOrCreate([ 'label' => Str::before($importedProduct['colour'], ','), 'locale' => $locale, ], [ 'label' => Str::ucfirst(Str::before($importedProduct['colour'], ',')), 'locale' => $locale, ]); $colourId = $option->id; } $products[$locale] = [ [ 'sku' => $importedProduct['sku'], 'type' => 'simple', 'product_number' => null, 'name' => $importedProduct['name'], 'short_description' => $importedProduct['description'], 'description' => $importedProduct['description'], 'url_key' => Str::slug($importedProduct['name']), 'new' => 1, 'featured' => 1, 'status' => 1, 'meta_title' => $importedProduct['name'], 'meta_keywords' => 'fiets', 'meta_description' => $importedProduct['description'], 'price' => $importedProduct['price'], 'special_price' => null, 'special_price_from' => null, 'special_price_to' => null, 'weight' => isset($importedProduct['weightinkg']) ? ((int) ((float) $importedProduct['weightinkg']) * 1000) : null, 'created_at' => $now, 'locale' => $locale, 'channel' => 'default', 'attribute_family_id' => 1, 'product_id' => null, 'updated_at' => $now, 'parent_id' => null, 'visible_individually' => 1, 'size' => $sizeId ?? null, 'color' => $colourId ?? null, ], ]; } } return $products; } public function productImages($targetPath, $file, $default = null) { if (str_contains(get_headers($file)[0], '200 OK')) { $contents = file_get_contents($file); $name = substr($file, strrpos($file, '/') + 1); Storage::put($targetPath.'/'.$name, $contents); return $targetPath.'/'.$name; } if (! $default) { return; } if (file_exists($default)) { return Storage::putFile($targetPath, new File($default)); } } }
-