<?php
namespace App\Controller;
use App\Helpers\WoocommerceHelper;
use App\Images\ImageRenderer;
use App\Service\SchemaService;
use Metabolism\WordpressBundle\Entity\Post;
use Metabolism\WordpressBundle\Entity\PostCollection;
use Metabolism\WordpressBundle\Entity\Term;
use Metabolism\WordpressBundle\Service\PaginationService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractController
{
#[Route('/product/{slug}', requirements: ['slug' => '.+'])]
public function productAction(Post $post, SchemaService $schemaService, ImageRenderer $imageRenderer, WoocommerceHelper $woocommerceHelper)
{
$product = wc_get_product($post->ID);
$producto['id'] = $product->get_id();
$producto['link'] = $product->get_permalink();
$producto['slug'] = $product->get_slug();
$producto['name'] = $product->get_name();
$producto['sku'] = $product->get_sku();
$producto['description'] = apply_filters('the_content', nl2br($product->get_description()));
$producto['short_description'] = strip_tags($product->get_short_description(), '<p><strong>');
$producto['is_in_stock'] = $product->is_in_stock() && $product->get_price();
$tax_rates = $product->get_tax_class() ? \WC_Tax::get_rates($product->get_tax_class()) : \WC_Tax::get_rates('');
$taxes = 1;
if (!empty($tax_rates)) {
$tax_rate = reset($tax_rates);
$taxes += $tax_rate['rate'] / 100;
}
$producto['taxes'] = !empty($tax_rates) ? $taxes : null;
$producto['price'] = $product->get_price() ? $product->get_price() * $taxes : null;
$producto['regular_price'] = $product->is_type('variable') ? floatval($product->get_variation_regular_price('min', true) + 0) * $taxes : floatval($product->get_regular_price()) * $taxes;
$producto['sale_price'] = $product->is_type('variable') ? floatval($product->get_variation_sale_price('min', true) + 0) * $taxes : floatval($product->get_sale_price()) * $taxes;
if ($producto['regular_price'] == $producto['sale_price']) {
$producto['sale_price'] = $product->is_type('variable') ? floatval($product->get_variation_price('min', true) + 0) * $taxes : floatval($product->get_sale_price()) * $taxes;
} else if ($producto['sale_price']) {
$producto['discount'] = round(100 - ($producto['sale_price'] * 100) / $producto['regular_price'], 2, PHP_ROUND_HALF_UP);
}
$producto['width'] = get_post_meta($product->get_id(), '_width', true);
$producto['height'] = get_post_meta($product->get_id(), '_height', true);
$producto['length'] = get_post_meta($product->get_id(), '_length', true);
$producto['attributes'] = WoocommerceHelper::getProductAttributes($product);
$image_id = $product->get_image_id();
$producto['gallery'] = [];
if ($image_id) {
$producto['image'] = $imageRenderer->getAttributesWordpress($image_id, 'product', 'gallery')['src'];
$imageAttributes = $imageRenderer->getAttributesWordpress($image_id, 'product', 'gallery');
$imageAttributes['thumbnail'] = $imageRenderer->getAttributesWordpress($image_id, 'product', 'thumbnail');
$producto['gallery'][] = $imageAttributes;
}
foreach ($product->get_gallery_image_ids() as $key => $id) {
$imageAttributes = $imageRenderer->getAttributesWordpress($id, 'product', 'gallery');
$imageAttributes['thumbnail'] = $imageRenderer->getAttributesWordpress($id, 'product', 'thumbnail');
$producto['gallery'][] = $imageAttributes;
}
$attributes = [];
foreach ($_GET as $key => $value) {
if (strpos($key, 'attribute_pa_') === 0) {
$attributes[$key] = $value;
}
}
if ($product->is_type('variable')) {
$producto['available_variations'] = $product->get_available_variations();
$producto['variation_attributes'] = WoocommerceHelper::getVariationAttributes($product);
$producto['default_variation'] = WoocommerceHelper::getDefaultVariation($product);
if ($attributes) {
foreach ($producto['default_variation']['attributes'] as $key => $value) {
if (!isset($attributes[$key])) {
$attributes[$key] = $value;
}
}
$producto['default_variation'] = $producto['available_variations'][array_search(WoocommerceHelper::findProductVariationId($product, $attributes), array_column($producto['available_variations'], 'variation_id'))];
} else if (isset($_GET['v']) && array_search($_GET['v'], array_column($producto['available_variations'], 'variation_id')) !== false) {
$producto['default_variation'] = $producto['available_variations'][array_search($_GET['v'], array_column($producto['available_variations'], 'variation_id'))];
}
// Poner un valor a los atributos de la variación por defecto que este vacía
foreach ($producto['default_variation']['attributes'] as $key => $value) {
if (empty($value)) {
if (isset($attributes[$key]) && $attributes[$key]) {
$producto['default_variation']['attributes'][$key] = $attributes[$key];
} else {
$attribute = str_replace('attribute_', '', $key);
$producto['default_variation']['attributes'][$key] = $producto['variation_attributes'][$attribute][0];
}
}
}
$producto['galleryVariations'] = $woocommerceHelper->getProductAttributesGallery($product);
}
$producto['upsell_ids'] = $product->get_upsell_ids();
foreach ($product->get_category_ids() as $key => $categoria) {
$term = get_term($categoria, 'product_cat');
$producto['categories'][$key]['id'] = $categoria;
$producto['categories'][$key]['parent'] = $term->parent;
$producto['categories'][$key]['name'] = $term->name;
$producto['categories'][$key]['slug'] = $term->slug;
$producto['categories'][$key]['link'] = get_term_link($term);
}
$producto['accordion'] = [];
if (!empty($producto['description'])) {
$producto['accordion'][] = [
'titulo' => 'Descripción',
'descripcion' => $producto['description']
];
}
if ($producto['sku'] || $producto['attributes']) {
$specifications = [];
if ($producto['sku']) {
$specifications[] = [
'name' => 'SKU',
'value' => $producto['sku']
];
}
foreach ($producto['attributes'] as $key => $attributes) {
if ($key == 'pa_tiempo-de-envio') {
continue;
}
$specifications[] = [
'name' => wc_attribute_label($key),
'value' => implode(', ', array_map(function ($attribute) {
return $attribute['name'];
}, $attributes))
];
}
$producto['accordion'][] = [
'titulo' => 'Especificaciones',
'descripcion' => $this->render('components/product-specifications.html.twig', [
'specifications' => $specifications
])->getContent()
];
}
return $this->render('product.html.twig', [
'product' => $producto,
'cart_url' => wc_get_cart_url(),
'json_schema' => $schemaService->injectSchemaProduct($producto)->toScript()
]);
}
public function productCatAction(Term $term, PostCollection $posts)
{
$facets = ['precio', 'product_cat'];
$shortcodes = [];
foreach ($facets as $facet) {
$shortcodes[] = do_shortcode('[facetwp facet="' . $facet . '"]');
}
$filtros = [
[
'filter_slug' => 'product_cat',
'filter_value' => $term->slug
]
];
FWP()->request->url_vars += array_reduce($filtros, function ($carry, $item) {
$carry[$item['filter_slug']] = array_merge($carry[$item['filter_slug']] ?? [], explode('|', $item['filter_value']));
return $carry;
}, []);
return $this->render('archive-product.html.twig', [
'term' => $term,
'tipo_productos' => $this->getFilterTipoProductos(),
'filtros' => $filtros,
'facets_shortcodes' => $shortcodes
]);
}
public function productTagAction(Term $term, PostCollection $posts)
{
$facets = ['precio', 'product_cat'];
$shortcodes = [];
foreach ($facets as $facet) {
$shortcodes[] = do_shortcode('[facetwp facet="' . $facet . '"]');
}
return $this->render('archive-product.html.twig', [
'term' => $term,
'tipo_productos' => $this->getFilterTipoProductos(),
'facets_shortcodes' => $shortcodes
]);
}
public function productArchiveAction(PostCollection $posts)
{
$post = new Post(wc_get_page_id('shop'));
$facets = ['precio', 'product_cat'];
$shortcodes = [];
foreach ($facets as $facet) {
$shortcodes[] = do_shortcode('[facetwp facet="' . $facet . '"]');
}
return $this->render('archive-product.html.twig', [
'post' => $post,
'tipo_productos' => $this->getFilterTipoProductos(),
'facets_shortcodes' => $shortcodes
]);
}
private function getFilterTipoProductos()
{
$args = [
'post_type' => 'wp_block',
'title' => 'FILTRO CATEGORIAS PRODUCTOS',
'posts_per_page' => 1
];
$query = new \WP_Query($args);
if ($query->have_posts()) {
$block_post = $query->posts[0];
return do_blocks($block_post->post_content);
}
}
}