var/cache/dev/twig/74/748982afcd6e406888dc5d4af1eae82fc3a129eb124e25c909c58165e4f3379f.php line 53

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\SandboxExtension;
  6. use Twig\Markup;
  7. use Twig\Sandbox\SecurityError;
  8. use Twig\Sandbox\SecurityNotAllowedTagError;
  9. use Twig\Sandbox\SecurityNotAllowedFilterError;
  10. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  11. use Twig\Source;
  12. use Twig\Template;
  13. /* Product/list.twig */
  14. class __TwigTemplate_bef9dab78eb246ff81cb0084ef5ae32d4ccdad3d7561b2fda6b324d40f8004e5 extends \Eccube\Twig\Template
  15. {
  16.     private $source;
  17.     private $macros = [];
  18.     public function __construct(Environment $env)
  19.     {
  20.         parent::__construct($env);
  21.         $this->source $this->getSourceContext();
  22.         $this->blocks = [
  23.             'stylesheet' => [$this'block_stylesheet'],
  24.             'javascript' => [$this'block_javascript'],
  25.             'main' => [$this'block_main'],
  26.         ];
  27.     }
  28.     protected function doGetParent(array $context)
  29.     {
  30.         // line 11
  31.         return "default_frame.twig";
  32.     }
  33.     protected function doDisplay(array $context, array $blocks = [])
  34.     {
  35.         $macros $this->macros;
  36.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  37.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/list.twig"));
  38.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  39.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Product/list.twig"));
  40.         // line 13
  41.         $context["body_class"] = "product_page";
  42.         // line 11
  43.         $this->parent $this->loadTemplate("default_frame.twig""Product/list.twig"11);
  44.         $this->parent->display($contextarray_merge($this->blocks$blocks));
  45.         
  46.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  47.         
  48.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  49.     }
  50.     // line 16
  51.     public function block_stylesheet($context, array $blocks = [])
  52.     {
  53.         $macros $this->macros;
  54.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  55.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  56.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  57.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheet"));
  58.         // line 17
  59.         echo "    <link rel=\"stylesheet\" href=\"";
  60.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("assets/css/product-list.css"), "html"nulltrue);
  61.         echo "\">
  62. ";
  63.         
  64.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  65.         
  66.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  67.     }
  68.     // line 20
  69.     public function block_javascript($context, array $blocks = [])
  70.     {
  71.         $macros $this->macros;
  72.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  73.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  74.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  75.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  76.         // line 21
  77.         echo "<script>
  78. (function() {
  79.     // Lấy URL hiện tại và tạo URLSearchParams
  80.     function getCurrentUrlParams() {
  81.         const urlParams = new URLSearchParams(window.location.search);
  82.         return urlParams;
  83.     }
  84.     // Cập nhật URL với category filters và reload
  85.     function updateCategoryFilters() {
  86.         const checkboxes = document.querySelectorAll('.filter-option__checkbox');
  87.         const urlParams = getCurrentUrlParams();
  88.         // Xóa tất cả category_filter[] cũ (có thể có nhiều giá trị)
  89.         const keysToDelete = [];
  90.         urlParams.forEach(function(value, key) {
  91.             if (key === 'category_filter[]' || key.startsWith('category_filter')) {
  92.                 keysToDelete.push(key);
  93.             }
  94.         });
  95.         keysToDelete.forEach(function(key) {
  96.             urlParams.delete(key);
  97.         });
  98.         // Thu thập category theo từng block tiêu chí.
  99.         // Trong cùng block là OR, giữa các block sẽ được backend xử lý là AND.
  100.         const selectedCategoriesByGroup = {};
  101.         checkboxes.forEach(function(checkbox) {
  102.             if (checkbox.checked) {
  103.                 const groupId = checkbox.dataset.groupId;
  104.                 if (!selectedCategoriesByGroup[groupId]) {
  105.                     selectedCategoriesByGroup[groupId] = [];
  106.                 }
  107.                 selectedCategoriesByGroup[groupId].push(checkbox.value);
  108.             }
  109.         });
  110.         Object.keys(selectedCategoriesByGroup).forEach(function(groupId) {
  111.             selectedCategoriesByGroup[groupId].forEach(function(categoryId) {
  112.                 urlParams.append('category_filter[' + groupId + '][]', categoryId);
  113.             });
  114.         });
  115.         // Reset về trang 1 khi filter
  116.         urlParams.set('pageno', '1');
  117.         // Tạo URL mới
  118.         const queryString = urlParams.toString();
  119.         const newUrl = queryString
  120.             ? window.location.pathname + '?' + queryString
  121.             : window.location.pathname;
  122.         // Reload page với query params mới
  123.         window.location.href = newUrl;
  124.     }
  125.     // Khôi phục trạng thái checkbox từ URL và xử lý nút search
  126.     document.addEventListener('DOMContentLoaded', function() {
  127.         const checkboxes = document.querySelectorAll('.filter-option__checkbox');
  128.         const searchButton = document.querySelector('.btn-search');
  129.         // Khôi phục trạng thái checkbox từ URL
  130.         const urlParams = getCurrentUrlParams();
  131.         const selectedCategories = [];
  132.         urlParams.forEach(function(value, key) {
  133.             if (key.startsWith('category_filter[')) {
  134.                 selectedCategories.push(value);
  135.             }
  136.         });
  137.         checkboxes.forEach(function(checkbox) {
  138.             // Set checked nếu category ID có trong URL
  139.             if (selectedCategories.includes(checkbox.value)) {
  140.                 checkbox.checked = true;
  141.             }
  142.             // Không lắng nghe sự kiện change trên checkbox nữa
  143.         });
  144.         // Lắng nghe sự kiện click trên nút search
  145.         if (searchButton) {
  146.             searchButton.addEventListener('click', function() {
  147.                 updateCategoryFilters();
  148.             });
  149.         }
  150.     });
  151. })();
  152. </script>
  153. ";
  154.         
  155.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  156.         
  157.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  158.     }
  159.     // line 110
  160.     public function block_main($context, array $blocks = [])
  161.     {
  162.         $macros $this->macros;
  163.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  164.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->enter($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  165.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02 $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  166.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->enter($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""main"));
  167.         // line 111
  168.         echo "
  169.  <body>
  170.   <!-- breadcrumb section -->
  171.   <div class=\"breadcrumb-section\">
  172.     <div class=\"container-1360 border-box px-40\">
  173.       <nav class=\"breadcrumb\">
  174.         <a href=\"";
  175.         // line 117
  176.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("homepage");
  177.         echo "\" class=\"breadcrumb__item text-black\">ホーム</a>
  178.         <img src=\"";
  179.         // line 118
  180.         echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("assets/img/default/icons/icon-breadcrumb-arrow.svg"), "html"nulltrue);
  181.         echo "\" alt=\">\" class=\"breadcrumb__separator\">
  182.         <a href=\"";
  183.         // line 119
  184.         echo $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_list");
  185.         echo "\" class=\"breadcrumb__item text-black\">商品一覧</a>
  186.       </nav>
  187.     </div>
  188.   </div>
  189.   <!-- product list section -->
  190.   <div class=\"container-1200\">
  191.     <div class=\"product-list-wrapper\">
  192.       <div class=\"product-list-left\">
  193.         ";
  194.         // line 128
  195.         if ((array_key_exists("searchable_categories"$context) && (twig_length_filter($this->env, (isset($context["searchable_categories"]) || array_key_exists("searchable_categories"$context) ? $context["searchable_categories"] : (function () { throw new RuntimeError('Variable "searchable_categories" does not exist.'128$this->source); })())) > 0))) {
  196.             // line 129
  197.             echo "          ";
  198.             $context['_parent'] = $context;
  199.             $context['_seq'] = twig_ensure_traversable((isset($context["searchable_categories"]) || array_key_exists("searchable_categories"$context) ? $context["searchable_categories"] : (function () { throw new RuntimeError('Variable "searchable_categories" does not exist.'129$this->source); })()));
  200.             foreach ($context['_seq'] as $context["_key"] => $context["group"]) {
  201.                 // line 130
  202.                 echo "            <div class=\"filter-group\">
  203.               <div class=\"filter-group__header\">";
  204.                 // line 131
  205.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse131), "name", [], "any"falsefalsefalse131), "html"nulltrue);
  206.                 echo "</div>
  207.               <div class=\"filter-group__options\">
  208.                 ";
  209.                 // line 133
  210.                 if ((twig_length_filter($this->envtwig_get_attribute($this->env$this->source$context["group"], "children", [], "any"falsefalsefalse133)) > 0)) {
  211.                     // line 134
  212.                     echo "                  ";
  213.                     $context['_parent'] = $context;
  214.                     $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env$this->source$context["group"], "children", [], "any"falsefalsefalse134));
  215.                     foreach ($context['_seq'] as $context["_key"] => $context["child"]) {
  216.                         // line 135
  217.                         echo "                    <label class=\"filter-option\">
  218.                       <input type=\"checkbox\"
  219.                              class=\"filter-option__checkbox\"
  220.                              name=\"category_filter[";
  221.                         // line 138
  222.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse138), "id", [], "any"falsefalsefalse138), "html"nulltrue);
  223.                         echo "][]\"
  224.                              value=\"";
  225.                         // line 139
  226.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["child"], "id", [], "any"falsefalsefalse139), "html"nulltrue);
  227.                         echo "\"
  228.                              data-category-id=\"";
  229.                         // line 140
  230.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["child"], "id", [], "any"falsefalsefalse140), "html"nulltrue);
  231.                         echo "\"
  232.                              data-group-id=\"";
  233.                         // line 141
  234.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse141), "id", [], "any"falsefalsefalse141), "html"nulltrue);
  235.                         echo "\">
  236.                       <span class=\"filter-option__label\">";
  237.                         // line 142
  238.                         echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["child"], "name", [], "any"falsefalsefalse142), "html"nulltrue);
  239.                         echo "</span>
  240.                     </label>
  241.                   ";
  242.                     }
  243.                     $_parent $context['_parent'];
  244.                     unset($context['_seq'], $context['_iterated'], $context['_key'], $context['child'], $context['_parent'], $context['loop']);
  245.                     $context array_intersect_key($context$_parent) + $_parent;
  246.                     // line 145
  247.                     echo "                ";
  248.                 } else {
  249.                     // line 146
  250.                     echo "                  ";
  251.                     // line 147
  252.                     echo "                  <label class=\"filter-option\">
  253.                     <input type=\"checkbox\"
  254.                            class=\"filter-option__checkbox\"
  255.                            name=\"category_filter[";
  256.                     // line 150
  257.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse150), "id", [], "any"falsefalsefalse150), "html"nulltrue);
  258.                     echo "][]\"
  259.                            value=\"";
  260.                     // line 151
  261.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse151), "id", [], "any"falsefalsefalse151), "html"nulltrue);
  262.                     echo "\"
  263.                            data-category-id=\"";
  264.                     // line 152
  265.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse152), "id", [], "any"falsefalsefalse152), "html"nulltrue);
  266.                     echo "\"
  267.                            data-group-id=\"";
  268.                     // line 153
  269.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse153), "id", [], "any"falsefalsefalse153), "html"nulltrue);
  270.                     echo "\">
  271.                     <span class=\"filter-option__label\">";
  272.                     // line 154
  273.                     echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->sourcetwig_get_attribute($this->env$this->source$context["group"], "parent", [], "any"falsefalsefalse154), "name", [], "any"falsefalsefalse154), "html"nulltrue);
  274.                     echo "</span>
  275.                   </label>
  276.                 ";
  277.                 }
  278.                 // line 157
  279.                 echo "              </div>
  280.             </div>
  281.           ";
  282.             }
  283.             $_parent $context['_parent'];
  284.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['group'], $context['_parent'], $context['loop']);
  285.             $context array_intersect_key($context$_parent) + $_parent;
  286.             // line 160
  287.             echo "        ";
  288.         }
  289.         // line 161
  290.         echo "        <button class=\"btn-primary btn-search w-100\">
  291.             <span>検索する</span>
  292.             <svg class=\"btn-search-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">
  293.             <rect width=\"24\" height=\"24\" rx=\"12\" fill=\"black\"/>
  294.             <path d=\"M16.252 12.001L16.249 12.0039L16.252 12.0068L11.7266 16.5312L10.5957 15.4004L13.1943 12.8027H7.72852V11.2031H13.1924L10.5957 8.60742L11.7266 7.47656L16.252 12.001Z\" fill=\"#FBE800\"/>
  295.             </svg>
  296.         </button>
  297.       </div>
  298.       <!-- bottom line -->
  299.       <div class=\"bottom-line container-mobile\"></div>
  300.       <!-- Product List Right -->
  301.       <div class=\"product-list-right\">
  302.         <div class=\"product-grid\" id=\"product-grid\">
  303.           ";
  304.         // line 174
  305.         if ((twig_get_attribute($this->env$this->source, (isset($context["pagination"]) || array_key_exists("pagination"$context) ? $context["pagination"] : (function () { throw new RuntimeError('Variable "pagination" does not exist.'174$this->source); })()), "totalItemCount", [], "any"falsefalsefalse174) > 0)) {
  306.             // line 175
  307.             echo "            ";
  308.             $context['_parent'] = $context;
  309.             $context['_seq'] = twig_ensure_traversable((isset($context["pagination"]) || array_key_exists("pagination"$context) ? $context["pagination"] : (function () { throw new RuntimeError('Variable "pagination" does not exist.'175$this->source); })()));
  310.             $context['loop'] = [
  311.               'parent' => $context['_parent'],
  312.               'index0' => 0,
  313.               'index'  => 1,
  314.               'first'  => true,
  315.             ];
  316.             if (is_array($context['_seq']) || (is_object($context['_seq']) && $context['_seq'] instanceof \Countable)) {
  317.                 $length count($context['_seq']);
  318.                 $context['loop']['revindex0'] = $length 1;
  319.                 $context['loop']['revindex'] = $length;
  320.                 $context['loop']['length'] = $length;
  321.                 $context['loop']['last'] = === $length;
  322.             }
  323.             foreach ($context['_seq'] as $context["_key"] => $context["Product"]) {
  324.                 // line 176
  325.                 echo "              <div class=\"product-item\">
  326.                 <a href=\"";
  327.                 // line 177
  328.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_detail", ["id" => twig_get_attribute($this->env$this->source$context["Product"], "id", [], "any"falsefalsefalse177)]), "html"nulltrue);
  329.                 echo "\" class=\"product-card-small\">
  330.                   <div class=\"product-card-small__image\">
  331.                     <img src=\"";
  332.                 // line 179
  333.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl($this->extensions['Eccube\Twig\Extension\EccubeExtension']->getNoImageProduct(twig_get_attribute($this->env$this->source$context["Product"], "main_list_image", [], "any"falsefalsefalse179)), "save_image"), "html"nulltrue);
  334.                 echo "\" alt=\"";
  335.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "name", [], "any"falsefalsefalse179), "html"nulltrue);
  336.                 echo "\" ";
  337.                 if ((twig_get_attribute($this->env$this->source$context["loop"], "index", [], "any"falsefalsefalse179) > 5)) {
  338.                     echo " loading=\"lazy\"";
  339.                 }
  340.                 echo ">
  341.                     <div class=\"product-card-small__arrow\">
  342.                         <img src=\"";
  343.                 // line 181
  344.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("assets/img/default/icons/icon-heart.svg"), "html"nulltrue);
  345.                 echo "\" alt=\"Favorite\" loading=\"lazy\">
  346.                     </div>
  347.                   </div>
  348.                 </a>
  349.                 <div class=\"product-item__info\">
  350.                   <a href=\"";
  351.                 // line 186
  352.                 echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getUrl("product_detail", ["id" => twig_get_attribute($this->env$this->source$context["Product"], "id", [], "any"falsefalsefalse186)]), "html"nulltrue);
  353.                 echo "\">
  354.                     <h4 class=\"product-item__title\" data-bs-toggle=\"tooltip\" data-bs-placement=\"top\" title=\"";
  355.                 // line 187
  356.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "name", [], "any"falsefalsefalse187), "html"nulltrue);
  357.                 echo "\">";
  358.                 echo twig_escape_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "name", [], "any"falsefalsefalse187), "html"nulltrue);
  359.                 echo "</h4>
  360.                   </a>
  361.                   <div class=\"product-item__price\">
  362.                     <span class=\"price-symbol\">¥</span>
  363.                     <span class=\"price-amount\">
  364.                       ";
  365.                 // line 192
  366.                 if (twig_get_attribute($this->env$this->source$context["Product"], "hasProductClass", [], "any"falsefalsefalse192)) {
  367.                     // line 193
  368.                     echo "                        ";
  369.                     if ((twig_get_attribute($this->env$this->source$context["Product"], "getPrice02IncTaxMin", [], "any"falsefalsefalse193) == twig_get_attribute($this->env$this->source$context["Product"], "getPrice02IncTaxMax", [], "any"falsefalsefalse193))) {
  370.                         // line 194
  371.                         echo "                          ";
  372.                         echo twig_escape_filter($this->envtwig_number_format_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "getPrice02IncTaxMin", [], "any"falsefalsefalse194)), "html"nulltrue);
  373.                         echo "
  374.                         ";
  375.                     } else {
  376.                         // line 196
  377.                         echo "                          ";
  378.                         echo twig_escape_filter($this->envtwig_number_format_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "getPrice02IncTaxMin", [], "any"falsefalsefalse196)), "html"nulltrue);
  379.                         echo " ~ ";
  380.                         echo twig_escape_filter($this->envtwig_number_format_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "getPrice02IncTaxMax", [], "any"falsefalsefalse196)), "html"nulltrue);
  381.                         echo "
  382.                         ";
  383.                     }
  384.                     // line 198
  385.                     echo "                      ";
  386.                 } else {
  387.                     // line 199
  388.                     echo "                        ";
  389.                     echo twig_escape_filter($this->envtwig_number_format_filter($this->envtwig_get_attribute($this->env$this->source$context["Product"], "getPrice02IncTaxMin", [], "any"falsefalsefalse199)), "html"nulltrue);
  390.                     echo "
  391.                       ";
  392.                 }
  393.                 // line 201
  394.                 echo "                    </span>
  395.                     <span class=\"price-tax\">(税込)</span>
  396.                   </div>
  397.                 </div>
  398.               </div>
  399.             ";
  400.                 ++$context['loop']['index0'];
  401.                 ++$context['loop']['index'];
  402.                 $context['loop']['first'] = false;
  403.                 if (isset($context['loop']['length'])) {
  404.                     --$context['loop']['revindex0'];
  405.                     --$context['loop']['revindex'];
  406.                     $context['loop']['last'] = === $context['loop']['revindex0'];
  407.                 }
  408.             }
  409.             $_parent $context['_parent'];
  410.             unset($context['_seq'], $context['_iterated'], $context['_key'], $context['Product'], $context['_parent'], $context['loop']);
  411.             $context array_intersect_key($context$_parent) + $_parent;
  412.             // line 207
  413.             echo "          ";
  414.         } else {
  415.             // line 208
  416.             echo "            <span>";
  417.             echo twig_escape_filter($this->env$this->extensions['Symfony\Bridge\Twig\Extension\TranslationExtension']->trans("front.product.search__product_not_found"), "html"nulltrue);
  418.             echo "</span>
  419.           ";
  420.         }
  421.         // line 210
  422.         echo "        </div>
  423.         <!-- Pagination -->
  424.         <div class=\"pagination-product-list-wrapper\">
  425.           <div class=\"pagination-product-list\" style=\"margin: 0 auto;\">
  426.             ";
  427.         // line 214
  428.         $this->loadTemplate("Block/_pagination.twig""Product/list.twig"214)->display(twig_array_merge($context, ["pages" => twig_get_attribute($this->env$this->source, (isset($context["pagination"]) || array_key_exists("pagination"$context) ? $context["pagination"] : (function () { throw new RuntimeError('Variable "pagination" does not exist.'214$this->source); })()), "paginationData", [], "any"falsefalsefalse214)]));
  429.         // line 215
  430.         echo "          </div>
  431.         </div>
  432.       </div>
  433.     </div>
  434.   </div>
  435.  </body>
  436. ";
  437.         
  438.         $__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02->leave($__internal_319393461309892924ff6e74d6d6e64287df64b63545b994e100d4ab223aed02_prof);
  439.         
  440.         $__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e->leave($__internal_085b0142806202599c7fe3b329164a92397d8978207a37e79d70b8c52599e33e_prof);
  441.     }
  442.     public function getTemplateName()
  443.     {
  444.         return "Product/list.twig";
  445.     }
  446.     public function isTraitable()
  447.     {
  448.         return false;
  449.     }
  450.     public function getDebugInfo()
  451.     {
  452.         return array (  466 => 215,  464 => 214,  458 => 210,  452 => 208,  449 => 207,  430 => 201,  424 => 199,  421 => 198,  413 => 196,  407 => 194,  404 => 193,  402 => 192,  392 => 187,  388 => 186,  380 => 181,  369 => 179,  364 => 177,  361 => 176,  343 => 175,  341 => 174,  326 => 161,  323 => 160,  315 => 157,  309 => 154,  305 => 153,  301 => 152,  297 => 151,  293 => 150,  288 => 147,  286 => 146,  283 => 145,  274 => 142,  270 => 141,  266 => 140,  262 => 139,  258 => 138,  253 => 135,  248 => 134,  246 => 133,  241 => 131,  238 => 130,  233 => 129,  231 => 128,  219 => 119,  215 => 118,  211 => 117,  203 => 111,  193 => 110,  96 => 21,  86 => 20,  73 => 17,  63 => 16,  52 => 11,  50 => 13,  37 => 11,);
  453.     }
  454.     public function getSourceContext()
  455.     {
  456.         return new Source("{#
  457. This file is part of EC-CUBE
  458. Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  459. http://www.ec-cube.co.jp/
  460. For the full copyright and license information, please view the LICENSE
  461. file that was distributed with this source code.
  462. #}
  463. {% extends 'default_frame.twig' %}
  464. {% set body_class = 'product_page' %}
  465. {# style #}
  466. {% block stylesheet %}
  467.     <link rel=\"stylesheet\" href=\"{{ asset('assets/css/product-list.css') }}\">
  468. {% endblock %}
  469. {% block javascript %}
  470. <script>
  471. (function() {
  472.     // Lấy URL hiện tại và tạo URLSearchParams
  473.     function getCurrentUrlParams() {
  474.         const urlParams = new URLSearchParams(window.location.search);
  475.         return urlParams;
  476.     }
  477.     // Cập nhật URL với category filters và reload
  478.     function updateCategoryFilters() {
  479.         const checkboxes = document.querySelectorAll('.filter-option__checkbox');
  480.         const urlParams = getCurrentUrlParams();
  481.         // Xóa tất cả category_filter[] cũ (có thể có nhiều giá trị)
  482.         const keysToDelete = [];
  483.         urlParams.forEach(function(value, key) {
  484.             if (key === 'category_filter[]' || key.startsWith('category_filter')) {
  485.                 keysToDelete.push(key);
  486.             }
  487.         });
  488.         keysToDelete.forEach(function(key) {
  489.             urlParams.delete(key);
  490.         });
  491.         // Thu thập category theo từng block tiêu chí.
  492.         // Trong cùng block là OR, giữa các block sẽ được backend xử lý là AND.
  493.         const selectedCategoriesByGroup = {};
  494.         checkboxes.forEach(function(checkbox) {
  495.             if (checkbox.checked) {
  496.                 const groupId = checkbox.dataset.groupId;
  497.                 if (!selectedCategoriesByGroup[groupId]) {
  498.                     selectedCategoriesByGroup[groupId] = [];
  499.                 }
  500.                 selectedCategoriesByGroup[groupId].push(checkbox.value);
  501.             }
  502.         });
  503.         Object.keys(selectedCategoriesByGroup).forEach(function(groupId) {
  504.             selectedCategoriesByGroup[groupId].forEach(function(categoryId) {
  505.                 urlParams.append('category_filter[' + groupId + '][]', categoryId);
  506.             });
  507.         });
  508.         // Reset về trang 1 khi filter
  509.         urlParams.set('pageno', '1');
  510.         // Tạo URL mới
  511.         const queryString = urlParams.toString();
  512.         const newUrl = queryString
  513.             ? window.location.pathname + '?' + queryString
  514.             : window.location.pathname;
  515.         // Reload page với query params mới
  516.         window.location.href = newUrl;
  517.     }
  518.     // Khôi phục trạng thái checkbox từ URL và xử lý nút search
  519.     document.addEventListener('DOMContentLoaded', function() {
  520.         const checkboxes = document.querySelectorAll('.filter-option__checkbox');
  521.         const searchButton = document.querySelector('.btn-search');
  522.         // Khôi phục trạng thái checkbox từ URL
  523.         const urlParams = getCurrentUrlParams();
  524.         const selectedCategories = [];
  525.         urlParams.forEach(function(value, key) {
  526.             if (key.startsWith('category_filter[')) {
  527.                 selectedCategories.push(value);
  528.             }
  529.         });
  530.         checkboxes.forEach(function(checkbox) {
  531.             // Set checked nếu category ID có trong URL
  532.             if (selectedCategories.includes(checkbox.value)) {
  533.                 checkbox.checked = true;
  534.             }
  535.             // Không lắng nghe sự kiện change trên checkbox nữa
  536.         });
  537.         // Lắng nghe sự kiện click trên nút search
  538.         if (searchButton) {
  539.             searchButton.addEventListener('click', function() {
  540.                 updateCategoryFilters();
  541.             });
  542.         }
  543.     });
  544. })();
  545. </script>
  546. {% endblock %}
  547. {% block main %}
  548.  <body>
  549.   <!-- breadcrumb section -->
  550.   <div class=\"breadcrumb-section\">
  551.     <div class=\"container-1360 border-box px-40\">
  552.       <nav class=\"breadcrumb\">
  553.         <a href=\"{{ url('homepage') }}\" class=\"breadcrumb__item text-black\">ホーム</a>
  554.         <img src=\"{{ asset('assets/img/default/icons/icon-breadcrumb-arrow.svg') }}\" alt=\">\" class=\"breadcrumb__separator\">
  555.         <a href=\"{{ url('product_list') }}\" class=\"breadcrumb__item text-black\">商品一覧</a>
  556.       </nav>
  557.     </div>
  558.   </div>
  559.   <!-- product list section -->
  560.   <div class=\"container-1200\">
  561.     <div class=\"product-list-wrapper\">
  562.       <div class=\"product-list-left\">
  563.         {% if searchable_categories is defined and searchable_categories|length > 0 %}
  564.           {% for group in searchable_categories %}
  565.             <div class=\"filter-group\">
  566.               <div class=\"filter-group__header\">{{ group.parent.name }}</div>
  567.               <div class=\"filter-group__options\">
  568.                 {% if group.children|length > 0 %}
  569.                   {% for child in group.children %}
  570.                     <label class=\"filter-option\">
  571.                       <input type=\"checkbox\"
  572.                              class=\"filter-option__checkbox\"
  573.                              name=\"category_filter[{{ group.parent.id }}][]\"
  574.                              value=\"{{ child.id }}\"
  575.                              data-category-id=\"{{ child.id }}\"
  576.                              data-group-id=\"{{ group.parent.id }}\">
  577.                       <span class=\"filter-option__label\">{{ child.name }}</span>
  578.                     </label>
  579.                   {% endfor %}
  580.                 {% else %}
  581.                   {# Nếu parent category cũng có is_searchable và không có children, hiển thị parent #}
  582.                   <label class=\"filter-option\">
  583.                     <input type=\"checkbox\"
  584.                            class=\"filter-option__checkbox\"
  585.                            name=\"category_filter[{{ group.parent.id }}][]\"
  586.                            value=\"{{ group.parent.id }}\"
  587.                            data-category-id=\"{{ group.parent.id }}\"
  588.                            data-group-id=\"{{ group.parent.id }}\">
  589.                     <span class=\"filter-option__label\">{{ group.parent.name }}</span>
  590.                   </label>
  591.                 {% endif %}
  592.               </div>
  593.             </div>
  594.           {% endfor %}
  595.         {% endif %}
  596.         <button class=\"btn-primary btn-search w-100\">
  597.             <span>検索する</span>
  598.             <svg class=\"btn-search-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">
  599.             <rect width=\"24\" height=\"24\" rx=\"12\" fill=\"black\"/>
  600.             <path d=\"M16.252 12.001L16.249 12.0039L16.252 12.0068L11.7266 16.5312L10.5957 15.4004L13.1943 12.8027H7.72852V11.2031H13.1924L10.5957 8.60742L11.7266 7.47656L16.252 12.001Z\" fill=\"#FBE800\"/>
  601.             </svg>
  602.         </button>
  603.       </div>
  604.       <!-- bottom line -->
  605.       <div class=\"bottom-line container-mobile\"></div>
  606.       <!-- Product List Right -->
  607.       <div class=\"product-list-right\">
  608.         <div class=\"product-grid\" id=\"product-grid\">
  609.           {% if pagination.totalItemCount > 0 %}
  610.             {% for Product in pagination %}
  611.               <div class=\"product-item\">
  612.                 <a href=\"{{ url('product_detail', {'id': Product.id}) }}\" class=\"product-card-small\">
  613.                   <div class=\"product-card-small__image\">
  614.                     <img src=\"{{ asset(Product.main_list_image|no_image_product, 'save_image') }}\" alt=\"{{ Product.name }}\" {% if loop.index > 5 %} loading=\"lazy\"{% endif %}>
  615.                     <div class=\"product-card-small__arrow\">
  616.                         <img src=\"{{ asset('assets/img/default/icons/icon-heart.svg') }}\" alt=\"Favorite\" loading=\"lazy\">
  617.                     </div>
  618.                   </div>
  619.                 </a>
  620.                 <div class=\"product-item__info\">
  621.                   <a href=\"{{ url('product_detail', {'id': Product.id}) }}\">
  622.                     <h4 class=\"product-item__title\" data-bs-toggle=\"tooltip\" data-bs-placement=\"top\" title=\"{{ Product.name }}\">{{ Product.name }}</h4>
  623.                   </a>
  624.                   <div class=\"product-item__price\">
  625.                     <span class=\"price-symbol\">¥</span>
  626.                     <span class=\"price-amount\">
  627.                       {% if Product.hasProductClass %}
  628.                         {% if Product.getPrice02IncTaxMin == Product.getPrice02IncTaxMax %}
  629.                           {{ Product.getPrice02IncTaxMin|number_format }}
  630.                         {% else %}
  631.                           {{ Product.getPrice02IncTaxMin|number_format }} ~ {{ Product.getPrice02IncTaxMax|number_format }}
  632.                         {% endif %}
  633.                       {% else %}
  634.                         {{ Product.getPrice02IncTaxMin|number_format }}
  635.                       {% endif %}
  636.                     </span>
  637.                     <span class=\"price-tax\">(税込)</span>
  638.                   </div>
  639.                 </div>
  640.               </div>
  641.             {% endfor %}
  642.           {% else %}
  643.             <span>{{ 'front.product.search__product_not_found'|trans }}</span>
  644.           {% endif %}
  645.         </div>
  646.         <!-- Pagination -->
  647.         <div class=\"pagination-product-list-wrapper\">
  648.           <div class=\"pagination-product-list\" style=\"margin: 0 auto;\">
  649.             {% include \"Block/_pagination.twig\" with {'pages': pagination.paginationData} %}
  650.           </div>
  651.         </div>
  652.       </div>
  653.     </div>
  654.   </div>
  655.  </body>
  656. {% endblock %}
  657. ""Product/list.twig""/var/www/html/app/template/default/Product/list.twig");
  658.     }
  659. }