update
This commit is contained in:
155
changelog/2026-04-30-fix-permutation-url-feed.md
Normal file
155
changelog/2026-04-30-fix-permutation-url-feed.md
Normal file
@@ -0,0 +1,155 @@
|
||||
# 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):
|
||||
|
||||
```php
|
||||
// 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 `_`:
|
||||
|
||||
```php
|
||||
// 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`:
|
||||
|
||||
```php
|
||||
// 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`).
|
||||
|
||||
```php
|
||||
// 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 1–4. Kolejność: najpierw deploy kodu,
|
||||
potem regeneracja routingu, potem czyszczenie cache, potem regeneracja feedu,
|
||||
na końcu resubmit w GMC.
|
||||
Reference in New Issue
Block a user