Hallo, ich bin gestern auch auf das Navigator-Problem gestoßen. Bei der Fehlersuche habe ich herausgefunden, dass in der Session "lastListingSql" gespeichert wird. Das habe ich mir zunutze gemacht und, ich sag mal "mittelmäßig dirty", in den Navigator eingebaut. Diese gespeicherte Query scheint im Shop nirgendwo mehr wieder aufgerufen zu werden. Zumindest konnte ich nichts finden. Ich weiß nicht, ob sich die Sache negativ auf die Performance, Sicherheit oder Stabilität auswirkt. In meiner Test-Umgebung, sowie im offlinegeschalteten Onlineshop funktioniert es einwandfrei. Man kann sogar in den Suchergebnissen blättern. Auch springt bei er verlinkten Artikeln wieder zurück. Ich habe außer einem eigenen Theme, sowie 8 eigenen Modulen, sonst nichts aktiviert. Wenn Interesse besteht, kann ich die überladenen Dateien posten. Ich muss vorher aber noch ein paar Modifikationen in gleichen Klassen, die nicht dazu gehören, entfernen. Vielleicht kann man das Ganze dann gemeinsam weiterspinnen, oder direkt canceln, wenn's Bedenken gibt. Abschließend ein paar Screenshots. Viele Grüße, Michael.
Gut, hier die Dateien: GXModules/Schleifer/Navigator/Shop/Overloads/ProductNavigatorThemeContentView/ProductNavigatorOverload.inc.php PHP: <?php/* -------------------------------------------------------------- ProductNavigatorOverload.inc.php 2021-09-28 --------------------------------------------------------------* Class ProductNavigatorThemeContentView*/class ProductNavigatorOverload extends ProductNavigatorOverload_parent{ /** * @return string Returns the products sql string */ protected function _generateSql() { if (empty($_SESSION['last_listing_sql'])) { $_SESSION['last_listing_sql'] = parent::_generateSql(); } return $_SESSION['last_listing_sql']; } public function prepare_data() { $this->seoBoost = MainFactory::create_object('GMSEOBoost', [], true); $this->boostProducts = $this->seoBoost->boost_products; $resultArray = $this->_getProductInfo(); $this->_prepareAssignData($resultArray['productsArray'], $resultArray['actualKey']); $this->_assignData();// BEGIN OWN CODE // Generates smarty property CATEGORIES_NAME $query = "SELECT COALESCE (NULLIF(categories_heading_title,''), categories_name) AS categories_name FROM categories_description WHERE categories_id = '" . (int)$this->categoryId . "' AND language_id = '" . (int)$this->languageId . "'"; $result = xtc_db_query($query); while ($row = xtc_db_fetch_array($result)) { $cName = $row['categories_name']; } $this->set_content_data('CATEGORIES_NAME', $cName); // Generates smarty property PRODUCT_POSITION $this->set_content_data('PRODUCT_POSITION', $resultArray['actualKey']+1); // Generates smarty property SEARCH_RESULT true or false if (strpos($_SESSION['last_listing_sql'],'products_name LIKE') !== false) { $this->set_content_data('SEARCH_RESULT', 1); } else { $this->set_content_data('SEARCH_RESULT', 0); } }} GXModules/Schleifer/Navigator/Shop/Overloads/IndexThemeContentView/IndexOverload.inc.php PHP: <?php/* -------------------------------------------------------------- IndexOverload.inc.php 2021-09-30 --------------------------------------------------------------* Class IndexThemeContentView*/class IndexOverload extends IndexOverload_parent{ protected function load_center_modules() { parent::load_center_modules(); $_SESSION['last_listing_sql'] = ""; }} GXModules/Schleifer/Navigator/Shop/Overloads/LiveSearchAjaxHandler/SearchHandlerOverload.inc.php PHP: <?php/* -------------------------------------------------------------- SearchHandlerOverload.inc.php 2021-09-30 --------------------------------------------------------------* Class SearchHandlerOverload** @see SearchHandlerContentView*/class SearchHandlerOverload extends SearchHandlerOverload_parent{ function proceed() { parent::proceed(); $_SESSION['last_listing_sql'] = ""; }} GXModules/Schleifer/Navigator/Shop/Overloads/ProductListingContentControl/ProductListingOverload.inc.php PHP: <?php/* -------------------------------------------------------------- ProductListingOverload.inc.php 2021-09-30 --------------------------------------------------------------* Class ProductListingOverload** @see ProductListingContentControl*/class ProductListingOverload extends ProductListingOverload_parent{ public function extend_proceed($p_action) { parent::extend_proceed($p_action); $_SESSION['last_listing_sql'] = $this->sql_query; }} <your_theme>/html/custom/product_info_navigator_modifications.html HTML: {load_language_text section="product_navigator"} {block name="product_info_navigator"} <div id="product_navigation" class="panel-pagination"> <nav> {block name="product_info_navigator_pagination"} <ul class="pagination"> {if $PREVIOUS!=''} {block name="product_info_navigator_pagination_previous"} <li> <a href="{$PREVIOUS}">{$txt.text_back}</a> </li> {/block} {else} {block name="product_info_navigator_pagination_previous"} <li> <a class="nolink">{$txt.text_back}</a> </li> {/block} {/if} {block name="product_info_navigator_pagination_position"} <li> <a class="position">{$PRODUCT_POSITION}</a> </li> {/block} {if $NEXT!=''} {block name="product_info_navigator_pagination_next"} <li> <a href="{$NEXT}">{$txt.text_next}</a> </li> {/block} {else} {block name="product_info_navigator_pagination_next"} <li> <a class="nolink">{$txt.text_next}</a> </li> {/block} {/if} </ul> {/block} {if $SEARCH_RESULT == '1'} {if $PRODUCTS_COUNT > '1'} {block name="product_info_navigator_products_count"} <span><strong>{$PRODUCTS_COUNT}</strong> {$txt.search_results}</span> {/block} {else} {block name="product_info_navigator_products_count"} <span><strong>{$PRODUCTS_COUNT}</strong> {$txt.single_search_result}</span> {/block} {/if} {else} {if $PRODUCTS_COUNT > '1'} {block name="product_info_navigator_products_count"} <span><strong>{$PRODUCTS_COUNT}</strong> {$txt.products} ({$CATEGORIES_NAME})</span> {/block} {else} {block name="product_info_navigator_products_count"} <span><strong>{$PRODUCTS_COUNT}</strong> {$txt.single_product} ({$CATEGORIES_NAME})</span> {/block} {/if} {/if} </nav> </div> {/block} lang/german/user_sections/product_navigator.lang.inc.php PHP: <?php/* -------------------------------------------------------------- product_navigator.lang.inc.php 2021-09-30 --------------------------------------------------------------*/$t_language_text_section_content_array = array( 'search_results' => 'Products in this search result.', 'single_search_result' => 'Product in this search result.', 'products' => 'Products in this category.', 'single_product' => 'Product in this category.',); PHP: <?php/* -------------------------------------------------------------- product_navigator.lang.inc.php 2021-09-30 --------------------------------------------------------------*/$t_language_text_section_content_array = array( 'search_results' => 'Produkte in diesem Suchergebnis.', 'single_search_result' => 'Produkt in diesem Suchergebnis.', 'products' => 'Produkte in dieser Kategorie.', 'single_product' => 'Produkt in dieser Kategorie.',); lang/english/user_sections/product_navigator.lang.inc.php Und noch das CSS (zumindest passend für mein Theme): Code: #product_navigation .nolink:hover, #product_navigation .position { background-image: linear-gradient(rgb(238, 238, 238) 0px, rgb(222, 222, 222) 100%) !important; color: rgb(102, 102, 102) !important; } #product_navigation .nolink, #product_navigation .nolink:hover { color: #bbb !important; } Was mir aufgefallen ist, was noch nicht funktioniert: - wenn man nach dem Eingeben des Suchbegriffs in der Schnellsuche, zu schnell Enter drückt, löscht der SearchHandlerOverload wieder das lastListingSql - wenn man einen Cross-Selling-Artikel anklickt, funktioniert es nicht Momentan weiß ich nicht, wie ich o.g. einfach erkennen und darauf reagieren kann. Eine Idee wäre, dafür einen Controller zu schreiben. Bisher leider nie gemacht. Grüße und eine schönes Wochenende, Michael EDIT: Shop-Version 4.4.0.3
@Schleifer Nur als Tipp man kann auch Sprachdateien in GXModules/Schleifer/Navigator/Shop/TextPhrases/ und HTML in GXModules/Schleifer/Navigator/Shop/Themes/All/ hinterlegen, sodass alles im GXModules liegt und dies als eigeneständiges Modul läuft. Wenn du auch noch eine GXModule.json Datei in GXModules/Schleifer/Navigator/ mitlieferst, kann man das Modul sogar im Modul-Center Installieren und die Dateien werden nur vom Shop geladen, wenn das Modul im Modul-Center installiert ist. (Link nur für registrierte Nutzer sichtbar.)
Das ging irgendwie an mir vorbei, danke. Soweit schon umgesetzt, aber: Derzeit habe ich class SearchHandlerOverload extends SearchHandlerOverload_parent schon einmal für etwas anderes benutzt. Wenn ich dies nun im "sauber getrennten" Modul erneut benutze, kommt logischerweise folgender fehler: Cannot declare class SearchHandlerOverload, because the name is already in use in... Benenne ich die Klasse um, passiert nichts. Was muss ich tun? Stehe gerade etwas auf dem Schlauch. Ich würde das Modul noch etwas weiter verbessern, templatekompatibel machen, schauen, wie weit es abwärtskompatibel ist, und dann hochladen.
@Schleifer Du kannst eine Klasse mehfach überladen, musst nur einen einzigartigen Namen wählen. Wenn du z.B. class NavigationSearchHandlerOverload extends NavigationSearchHandlerOverload_parent nutzt, muss die Datei auch NavigationSearchHandlerOverload.inc.php lauten damit diese vom Shop auch benutzt wird. Wähle also einen einzigartigen Namen für deine Klasse um keine Konflikte mit anderen Modulen zu haben.