if (!empty($models)) { $shopPartsTypesModel = new shopPartsTypesModel('extra'); // === 1) Полный список в шаблонные переменные (для совместимости с текущим шаблоном) $view = wa()->getView(); $view->assign('models_table', $models); // БЕЗ array_slice — весь список $view->assign('models', $models); // БЕЗ array_slice — весь список $view->assign('imagesUrl', wa()->getDataUrl('plugins/parts/images/', true, 'site')); $view->assign('types', $shopPartsTypesModel->getAll()); $view->assign('original_code', $original_code); $tmp_path = 'plugins/parts/templates/list_model.html'; $template_path = wa()->getDataPath($tmp_path, false, 'shop', true); if (!file_exists($template_path)) { $template_path = wa()->getAppPath($tmp_path, 'shop'); } // === 2) Быстрый рендер через файловый кэш готового HTML вкладки // Кэш на товар + код + бренды (если участвуют в фильтрации) $brand_key = is_array($brand) ? implode('|', $brand) : (string)$brand; $cache_rel = 'plugins/parts/cache/product_tab_models/' . (int)$frontend_product['id'] . '_' . md5((string)$original_code . '|' . $brand_key) . '.html'; $cache_abs = wa()->getDataPath($cache_rel, true, 'shop'); // создаст папки при необходимости $need_refresh = (bool)waRequest::get('refresh_models', 0, 'int'); $tab_html = ''; if (!$need_refresh && file_exists($cache_abs)) { // Быстрый путь: читаем готовый HTML вкладки из кэша $tab_html = @file_get_contents($cache_abs); } if ($tab_html === '' || $tab_html === false) { // Медленный путь только один раз: шаблон рендерится и кэшируется $tab_html = $view->fetch($template_path); // Пишем в кэш атомарно @file_put_contents($cache_abs, $tab_html, LOCK_EX); } // === 3) Вставляем готовый HTML во вкладку, без повторного fetch $pages = $frontend_product['pages']; $pages[] = array( 'id' => 'parts', 'name' => 'Підходить до моделей ('.count($models).')', 'content' => $tab_html ); $frontend_product['pages'] = $pages; $frontend_product['has_parts'] = true; } Помилка #500