<?php
/**
* AUTO-FILL EMPTY COLUMNS IN ELECTRON WOO GRID - COMPLETE SOLUTION
* Copy this entire code to your theme's functions.php file
*/
// ==============================================
// 1. FORCE QUERY TO FILL EMPTY SLOTS
// ==============================================
add_filter('woocommerce_product_query', 'electron_force_no_empty_columns', 99);
function electron_force_no_empty_columns($q) {
// Only on main shop/archive pages
if (is_admin() || !$q->is_main_query() || !(is_shop() || is_product_category() || is_product_tag())) {
return $q;
}
$posts_per_page = $q->get('posts_per_page');
$current_page = $q->get('paged') ?: 1;
$total_products = $q->found_posts;
$columns = 4; // Change this to your grid columns number
// Only on first page
if ($current_page == 1 && $total_products > 0) {
$remainder = $total_products % $columns;
if ($remainder != 0) {
$new_per_page = $posts_per_page + ($columns - $remainder);
if ($new_per_page <= $total_products + $columns) {
$q->set('posts_per_page', $new_per_page);
}
}
}
return $q;
}
// ==============================================
// 2. AUTO-FILL EMPTY COLUMNS WITH DEFAULT PRODUCTS
// ==============================================
add_action('woocommerce_after_shop_loop', 'electron_fill_empty_grid_columns', 5);
function electron_fill_empty_grid_columns() {
global $wp_query;
$product_count = $wp_query->post_count;
$columns = 4; // Match your grid columns
$total_products_found = $wp_query->found_posts;
// Calculate empty slots
$empty_slots = $columns - ($product_count % $columns);
// Don't fill if no empty slots or if all products shown
if ($empty_slots == $columns || $empty_slots == 0 || $product_count == 0) {
return;
}
// Get default products to fill empty slots (most popular)
$default_products = wc_get_products(array(
'limit' => $empty_slots,
'orderby' => 'popularity',
'order' => 'DESC',
'status' => 'publish',
'stock_status' => 'instock'
));
// If no products found, get any products
if (empty($default_products)) {
$default_products = wc_get_products(array(
'limit' => $empty_slots,
'orderby' => 'date',
'order' => 'DESC',
'status' => 'publish'
));
}
// Display each default product
foreach ($default_products as $product) {
electron_display_filler_product($product);
}
}
// ==============================================
// 3. DISPLAY FILLER PRODUCT (Clone style)
// ==============================================
function electron_display_filler_product($product) {
if (!$product) return;
?>
<div class="electron-loop-product type-2 product type-product status-publish instock product_cat-default has-post-thumbnail shipping-taxable purchasable product-type-simple electron-filler-product" data-product-animation="fadeInUp">
<div class="product-inner" data-id="<?php echo esc_attr($product->get_id()); ?>">
<!-- Thumbnail / Image -->
<div class="thumb-wrapper">
<a href="<?php echo esc_url($product->get_permalink()); ?>" class="product-link" title="<?php echo esc_attr($product->get_name()); ?>">
<?php echo $product->get_image('full'); ?>
</a>
<!-- Product Actions -->
<div class="product-actions hint-top">
<div class="electron-product-button electron-compare-btn spinner" data-id="<?php echo esc_attr($product->get_id()); ?>" data-name="<?php echo esc_attr($product->get_name()); ?>">
<span class="electron-hint">Compare</span>
<svg class="svgCompare electron-svg-icon" width="512" height="512" fill="currentColor" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<use href="#shopCompare"></use>
</svg>
</div>
<div class="electron-quickview-btn electron-product-button" data-id="<?php echo esc_attr($product->get_id()); ?>" data-label="Quick View">
<span class="electron-hint">Quick View</span>
<svg class="quickview electron-svg-icon" width="512" height="512" fill="currentColor" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<use href="#shopEye"></use>
</svg>
</div>
</div>
</div>
<!-- Details Wrapper -->
<div class="details-wrapper">
<div class="details-inner">
<h6 class="product-name">
<a href="<?php echo esc_url($product->get_permalink()); ?>" title="<?php echo esc_attr($product->get_name()); ?>">
<?php echo esc_html($product->get_name()); ?>
</a>
</h6>
<span class="product-price">
<?php echo $product->get_price_html(); ?>
</span>
<div class="shipping-badge">
<img draggable="false" role="img" class="emoji" alt="🚚" src="https://s.w.org/images/core/emoji/17.0.2/svg/1f69a.svg">
Livraison gratuite
</div>
<div class="stock-rating">
<span class="electron-small-title electron-stock-status instock">In stock:</span>
</div>
</div>
<!-- Product Footer -->
<div class="product-footer">
<ul class="product-features">
<li><span class="checked">✓</span> Meilleur prix au Maroc</li>
<li><span class="checked">✓</span> 12 mois de garantie</li>
<li><span class="checked">✓</span> livraison 24h</li>
</ul>
<a href="/?add-to-cart=<?php echo esc_attr($product->get_id()); ?>"
data-quantity="1"
data-product_id="<?php echo esc_attr($product->get_id()); ?>"
data-product_sku="<?php echo esc_attr($product->get_sku()); ?>"
class="type-simple electron_ajax_add_to_cart electron-btn electron-btn-primary electron-product-cart has-icon"
rel="nofollow"
title="Ajouter au panier"
data-title="Ajouter au panier">
<span class="cart-text">Ajouter au panier</span>
<svg class="svgaddtocart electron-svg-icon" width="512" height="512" fill="currentColor" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
<use href="#shopBag"></use>
</svg>
</a>
</div>
</div>
<div class="content-hidden" style="margin-bottom: -60px;">-</div>
</div>
</div>
<?php
}
// ==============================================
// 4. AJAX HANDLER FOR COMPARE & QUICK VIEW
// ==============================================
add_action('wp_ajax_electron_filler_product_data', 'electron_get_filler_product_data');
add_action('wp_ajax_nopriv_electron_filler_product_data', 'electron_get_filler_product_data');
function electron_get_filler_product_data() {
$product_id = intval($_POST['product_id']);
$product = wc_get_product($product_id);
if ($product) {
wp_send_json_success(array(
'id' => $product->get_id(),
'name' => $product->get_name(),
'price' => $product->get_price_html(),
'image' => $product->get_image(),
'permalink' => $product->get_permalink(),
'description' => $product->get_short_description()
));
}
wp_send_json_error();
}
// ==============================================
// 5. INJECT JAVASCRIPT FOR DYNAMIC FILLING (BACKUP)
// ==============================================
add_action('wp_footer', 'electron_inject_grid_filler_js');
function electron_inject_grid_filler_js() {
if (!is_shop() && !is_product_category() && !is_product_tag()) {
return;
}
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
// Wait for Electron grid to load
setTimeout(function() {
function fillEmptyGridSlots() {
$('.electron-products.products').each(function() {
var $container = $(this);
var $products = $container.find('.electron-loop-product');
var columns = 4; // Change to your grid columns
// Check if grid needs filling
if ($products.length > 0 && $products.length % columns !== 0) {
var emptySlots = columns - ($products.length % columns);
// Only fill if we have filler products from PHP
if ($('.electron-filler-product').length > 0) {
var $fillers = $('.electron-filler-product');
for (var i = 0; i < emptySlots && i < $fillers.length; i++) {
var $clone = $fillers.eq(i).clone();
$container.append($clone);
}
}
}
});
}
fillEmptyGridSlots();
// Re-run after any AJAX updates
$(document).ajaxComplete(function() {
setTimeout(fillEmptyGridSlots, 100);
});
}, 500);
});
</script>
<style>
/* Style for filler products */
.electron-filler-product {
animation: fadeInUp 0.5s ease-out;
}
.electron-filler-product .product-footer .electron-product-cart {
background: #4CAF50;
transition: all 0.3s ease;
}
.electron-filler-product .product-footer .electron-product-cart:hover {
background: #45a049;
transform: translateY(-2px);
}
/* Fix grid consistency */
.electron-products.products {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 30px;
}
@media (max-width: 992px) {
.electron-products.products {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 576px) {
.electron-products.products {
grid-template-columns: 1fr;
}
}
/* Ensure all product cards have same height */
.electron-loop-product {
height: 100%;
display: flex;
flex-direction: column;
}
.product-inner {
height: 100%;
display: flex;
flex-direction: column;
}
.details-wrapper {
flex: 1;
}
</style>
<?php
}
// ==============================================
// 6. CLEAR CACHE AUTOMATICALLY (Optional)
// ==============================================
add_action('save_post_product', 'electron_clear_grid_cache', 99);
function electron_clear_grid_cache($post_id) {
// Clear Elementor cache
if (class_exists('\Elementor\Plugin')) {
\Elementor\Plugin::$instance->files_manager->clear_cache();
}
// Clear WooCommerce transients
wc_delete_product_transients();
// Clear Electron cache if exists
if (function_exists('electron_clear_cache')) {
electron_clear_cache();
}
}
// ==============================================
// 7. ADMIN NOTICE (Optional)
// ==============================================
add_action('admin_notices', 'electron_grid_filler_notice');
function electron_grid_filler_notice() {
if (isset($_GET['page']) && $_GET['page'] == 'wc-status') {
echo '<div class="notice notice-success is-dismissible">
<p>✅ Auto-Fill Grid Columns is ACTIVE! Empty grid columns will be automatically filled with products.</p>
</div>';
}
}
?> <!-- END OF CODE -->