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

156 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 14. Kolejność: najpierw deploy kodu,
potem regeneracja routingu, potem czyszczenie cache, potem regeneracja feedu,
na końcu resubmit w GMC.