fix: linki produktow z permutacja atrybutow w feedzie Google (v0.350)

Separator URL miedzy parami attr-val zmieniony z "/" na "_" w generatorze
feedu (ProductRepository::appendCombinationToXml). Wzorzec routingu
pp_routes rozszerzony do [0-9_-]+ w Helpers::htacces (oba warianty:
seo_link i fallback p-id-name). LayoutEngine konwertuje "_" -> "|"
przed wywolaniem ProductRepository::findCached — format DB pozostaje "|".
Partial product-attribute.php preselectuje wartosc z permutation_hash
URL (forced_value_id), co poprawia UX wejscia z linka feedu.

Suita: 834 -> 841 testow (+7), 2330 assertions.

Wymagane akcje na produkcji po deployu: regeneracja pp_routes
(Helpers::htacces), wyczyszczenie klucza pp_routes:all w Redis,
regeneracja google-feed.xml, resubmit feedu w GMC.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 01:58:29 +02:00
parent 0de47f4e62
commit fba215b372
15 changed files with 765 additions and 29 deletions

View File

@@ -2,17 +2,37 @@
global $lang_id;
$attributeRepo = new \Domain\Attribute\AttributeRepository( $GLOBALS['mdb'] );
$attribute_details = $attributeRepo->frontAttributeDetails( (int)$this -> attribute['id'], $lang_id );
$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;
}
}
}
if ( $attribute_details['type'] == 0 )
{
?>
<div class="attribute-container fradio-group attribute-<?= \Shared\Helpers\Helpers::seo( $attribute_details['language']['name'] );?>" level="<?= $this -> level;?>" order="<?= $this -> order;?>" attribute="<?= \Shared\Helpers\Helpers::seo( $attribute_details['language']['name'] );?>" attribute-name="<?= $attribute_details['language']['name'];?>">
<p class="attribute-label"><?= $attribute_details['language']['name'];?>:</p>
<? foreach ( $this -> attribute['values'] as $value ):?>
<? foreach ( $this -> attribute['values'] as $value ):
$is_active = $forced_value_id !== null
? ( (int)$value['id'] === $forced_value_id )
: (bool)$value['is_default'];
?>
<div class="fradio">
<input type="radio" id="<?= $this -> attribute['id'];?>-<?= $value['id'];?>" <? if ( $value['is_default'] ):?>checked="checked"<? endif;?> require="true" value="<?= $this -> attribute['id'];?>-<?= $value['id'];?>" name="<?= \Shared\Helpers\Helpers::seo( $attribute_details['language']['name'] );?>">
<input type="radio" id="<?= $this -> attribute['id'];?>-<?= $value['id'];?>" <? if ( $is_active ):?>checked="checked"<? endif;?> require="true" value="<?= $this -> attribute['id'];?>-<?= $value['id'];?>" name="<?= \Shared\Helpers\Helpers::seo( $attribute_details['language']['name'] );?>">
<label for="<?= $this -> attribute['id'];?>-<?= $value['id'];?>" order="<?= $this -> order;?>"><?= ( new \Domain\Attribute\AttributeRepository( $GLOBALS['mdb'] ) )->getAttributeValueById( $value['id'], $lang_id );?></label>
</div>
<? if ( $value['is_default'] ):?>
<? if ( $is_active ):?>
<script class="footer" type="text/javascript">
$( function()
{