Files
pomysloweprezenty.pl/changelog/2026-04-30-fix-permutation-url-feed.md
2026-04-30 01:43:17 +02:00

5.6 KiB
Raw Permalink Blame History

Fix: linki produktów z permutacją atrybutów w feedzie Google → strona główna

Problem

URL produktu z permutacją atrybutów wygenerowany do feedu Google miał format:

/slug-produktu/20-170/21-175

(dwa segmenty rozdzielone /). Google Merchant Center indeksował taki URL z feedu, ale przy wejściu użytkownika serwer nie dopasowywał go do żadnej trasy w pp_routes i index.php ładował domyślną stronę główną.

Przyczyna

permutation_hash jest przechowywany w bazie jako attr-val|attr-val (np. 20-170|21-175), a w generatorze feedu Google znak | był podmieniany na / przy budowaniu linku.

Dodatkowo wzorzec routingu w pp_routes dla URL produktu z permutacją to ^slug/([0-9-]+)$ — klasa [0-9-]+ nie obejmuje /, więc URL ze slashem nigdy się nie dopasuje.

Rozwiązanie

Separatorem między parami attr-val w URL jest teraz _. Przy odczycie $_GET['permutation_hash'] w warstwie front podstawiamy _ z powrotem na | przed zapytaniem do bazy.

Format URL po zmianie:

/slug-produktu/20-170_21-175

Pliki zmienione

1. autoload/Domain/Product/ProductRepository.php

W metodzie appendCombinationToXml (linie ~2372 i ~2374):

// było
str_replace( '|', '/', $combination['permutation_hash'] )

// jest
str_replace( '|', '_', $combination['permutation_hash'] )

Dotyczy obu gałęzi if/else (z seo_link i fallback p-id-name).

2. autoload/Shared/Helpers/Helpers.php

W generatorze tras dla produktów z permutacją (linie ~694 i ~699) — rozszerzony wzorzec regex o _:

// było
'pattern' => '^' . ... . '/([0-9-]+)$'

// jest
'pattern' => '^' . ... . '/([0-9_-]+)$'

Dotyczy obu wariantów (z seo_link i fallback p-id-name).

3. autoload/front/LayoutEngine.php

W bloku // PRODUKT (linia ~196) — konwersja _| przed przekazaniem do findCached:

// było
$product = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )
  ->findCached( \Shared\Helpers\Helpers::get( 'product' ), $lang_id, $_GET['permutation_hash'] ?? null );

// jest
$permutation_hash = isset( $_GET['permutation_hash'] ) ? str_replace( '_', '|', $_GET['permutation_hash'] ) : null;
$product = ( new \Domain\Product\ProductRepository( $GLOBALS['mdb'] ) )
  ->findCached( \Shared\Helpers\Helpers::get( 'product' ), $lang_id, $permutation_hash );

4. templates/shop-product/_partial/product-attribute.php

Domyślnie partial preselectuje wartości na podstawie flagi is_default. Po wejściu na URL z permutation_hash (np. z feedu Google) UI nadal pokazywał domyślną kombinację zamiast tej z URL. Dodane wymuszenie wyboru wartości na podstawie permutation_hash z URL — jeśli atrybut jest obecny w hashu, jego aktywna wartość pochodzi z URL; w przeciwnym razie zachowane stare zachowanie (is_default).

// na początku partiala — wyciągnięcie value_id dla bieżącego atrybutu z URL
$forced_value_id = null;
if ( isset( $_GET['permutation_hash'] ) && $_GET['permutation_hash'] !== '' )
{
  $pairs = explode( '|', str_replace( '_', '|', $_GET['permutation_hash'] ) );
  foreach ( $pairs as $pair )
  {
    $parts = explode( '-', $pair );
    if ( count( $parts ) == 2 && (int)$parts[0] === (int)$this -> attribute['id'] )
    {
      $forced_value_id = (int)$parts[1];
      break;
    }
  }
}

// w pętli foreach po values — zamiast bezpośrednio $value['is_default']:
$is_active = $forced_value_id !== null
  ? ( (int)$value['id'] === $forced_value_id )
  : (bool)$value['is_default'];

$is_active jest następnie używane do checked="checked" na inpucie i do emisji bloku <script> z fradio_label_click(...) (auto-refresh atrybutów), zamiast dotychczasowego $value['is_default'].

UWAGA: jeśli sklep ma własną wersję tego partiala w templates_user/shop-product/_partial/product-attribute.php, zmianę trzeba zaaplikować tam (Tpl::view ma priorytet templates_user/).

Po wgraniu zmian — wymagane akcje (kolejność istotna)

  1. Przegenerować pp_routes — uruchomić w adminie funkcję regenerującą routing (Helpers::htacces() / regeneracja sitemap), żeby nowe wzorce z _ trafiły do bazy. Bez tego stare wzorce [0-9-]+ zostaną w pp_routes i nadal nie zmatchują URL-a z _.

  2. Wyczyścić cache routingu — w index.php:63 cache key pp_routes:all trzyma routing przez 24h ($cache->set($cacheKey, $routes, 86400)). Skasować klucz w cache (Redis/plikowy) albo poczekać na expiry.

  3. Przegenerować feed Google — uruchomić cron cron/cron-xml.php (\admin\factory\ShopProduct::generate_google_feed_xml()), żeby google-feed.xml miał nowe linki z _.

  4. Resubmit feedu w GMC — po regeneracji feed musi się odświeżyć w Google Merchant Center (automatycznie wg harmonogramu albo ręcznie „Fetch now").

  5. Stare URL-e w GMC z / — same wypadną z indeksu po podmianie feedu. Opcjonalnie można dodać redirecty 301 z /slug/X-Y/Z-W na /slug/X-Y_Z-W, ale nie jest to konieczne — Google zaktualizuje linki z feedu.

Walidacja

  • Otworzyć URL produktu z permutacją w formacie /slug/20-170_21-175 — powinien załadować stronę produktu z wybraną kombinacją atrybutów.
  • Otworzyć https://domena/google-feed.xml i sprawdzić, że tagi <link> używają _ zamiast / między parami atrybutów.
  • W GMC sprawdzić, że feed się zaciągnął bez błędów typu „Landing page error".

Wdrożenie na innym sklepie (ten sam silnik)

Te same trzy zmiany w plikach + akcje 14. Kolejność: najpierw deploy kodu, potem regeneracja routingu, potem czyszczenie cache, potem regeneracja feedu, na końcu resubmit w GMC.