feat: Add product name retrieval and enhance supplemental feed offer ID normalization
This commit is contained in:
4
.vscode/ftp-kr.sync.cache.json
vendored
4
.vscode/ftp-kr.sync.cache.json
vendored
@@ -431,8 +431,8 @@
|
||||
},
|
||||
"index.php": {
|
||||
"type": "-",
|
||||
"size": 4267,
|
||||
"lmtime": 1772117836613,
|
||||
"size": 4599,
|
||||
"lmtime": 1772382133382,
|
||||
"modified": false
|
||||
},
|
||||
"install.php": {
|
||||
|
||||
9
AGENTS.md
Normal file
9
AGENTS.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# AGENTS.md
|
||||
|
||||
## Sposób pracy
|
||||
- Pisz do mnie po polsku, zwięźle i krótko, ale merytorycznie
|
||||
|
||||
## Wprowadzanie zmian
|
||||
- Przeanalizuj wprowadzone zadanie
|
||||
- Przedstaw plan
|
||||
- Po akceptacji wdróź plan
|
||||
@@ -621,12 +621,14 @@ class Products
|
||||
static public function get_product_data() {
|
||||
$product_id = \S::get( 'product_id' );
|
||||
|
||||
$product_name = \factory\Products::get_product_name( $product_id );
|
||||
$product_title = \factory\Products::get_product_data( $product_id, 'title' );
|
||||
$product_description = \factory\Products::get_product_data( $product_id, 'description' );
|
||||
$google_product_category = \factory\Products::get_product_data( $product_id, 'google_product_category' );
|
||||
$product_url = \factory\Products::get_product_data( $product_id, 'product_url' );
|
||||
|
||||
echo json_encode( [ 'status' => 'ok', 'product_details' => [
|
||||
'name' => $product_name,
|
||||
'title' => $product_title,
|
||||
'description' => $product_description,
|
||||
'google_product_category' => $google_product_category,
|
||||
|
||||
@@ -519,6 +519,19 @@ class Products
|
||||
return $mdb -> get( 'products', $field, [ 'id' => $product_id ] );
|
||||
}
|
||||
|
||||
static public function get_product_name( $product_id )
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
$product_id = (int) $product_id;
|
||||
if ( $product_id <= 0 )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $mdb -> get( 'products', 'name', [ 'id' => $product_id ] );
|
||||
}
|
||||
|
||||
static public function get_product_merchant_context( $product_id )
|
||||
{
|
||||
global $mdb;
|
||||
|
||||
@@ -43,17 +43,18 @@ class SupplementalFeed
|
||||
$written = 0;
|
||||
foreach ( $products as $row )
|
||||
{
|
||||
$offer_id = self::normalize_feed_offer_id( $row['offer_id'] ?? '' );
|
||||
$title = self::sanitize_for_tsv( $row['title'] ?? '' );
|
||||
$description = self::sanitize_for_tsv( $row['description'] ?? '' );
|
||||
$category = trim( (string) ( $row['google_product_category'] ?? '' ) );
|
||||
|
||||
if ( $title === '' && $description === '' && $category === '' )
|
||||
if ( $offer_id === '' || ( $title === '' && $description === '' && $category === '' ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
fwrite( $fp, implode( "\t", [
|
||||
$row['offer_id'],
|
||||
$offer_id,
|
||||
$title,
|
||||
$description,
|
||||
$category
|
||||
@@ -116,4 +117,29 @@ class SupplementalFeed
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizuje offer_id do formatu oczekiwanego przez feed supplemental.
|
||||
* - usuwa ewentualny prefix channel:lang:country:
|
||||
* - dla Shopify wymusza wielkie litery kodu kraju: shopify_PL_...
|
||||
*/
|
||||
static private function normalize_feed_offer_id( $offer_id )
|
||||
{
|
||||
$offer_id = trim( (string) $offer_id );
|
||||
if ( $offer_id === '' ) return '';
|
||||
|
||||
$offer_id = trim( $offer_id, " \t\n\r\0\x0B'\"" );
|
||||
|
||||
if ( preg_match( '/^[a-z_]+:[a-z]{2,8}:[a-z]{2,8}:(.+)$/i', $offer_id, $matches ) )
|
||||
{
|
||||
$offer_id = trim( (string) ( $matches[1] ?? '' ) );
|
||||
}
|
||||
|
||||
if ( preg_match( '/^shopify_([a-z]{2})_(.+)$/i', $offer_id, $matches ) )
|
||||
{
|
||||
$offer_id = 'shopify_' . strtoupper( (string) $matches[1] ) . '_' . (string) $matches[2];
|
||||
}
|
||||
|
||||
return $offer_id;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
id title description google_product_category
|
||||
shopify_pl_8476788261204_46803770409300 GS żarówka LED E27 7W ciepłobiała zestaw 10 sztuk
|
||||
shopify_pl_8454714753364_46732986483028 GS żarówka LED 7W E27 barwa ciepła biała
|
||||
shopify_pl_8454759842132_46733043466580 Kobi Light żarówka LED E27 7W barwa neutralna biała 4000K 600lm 2425
|
||||
shopify_pl_8459153473876_46746440270164 Kobi Light żarówka LED świecowa E14 1,5W 150 lm zimnobiała 6000K 2425
|
||||
shopify_pl_8476790358356_46803775684948 Kobi Light żarówki LED E27 7W 4000K neutralne białe zestaw 10 sztuk 2425
|
||||
shopify_PL_8476788261204_46803770409300 GS żarówka LED E27 7W ciepłobiała zestaw 10 sztuk
|
||||
shopify_PL_8454714753364_46732986483028 GS żarówka LED 7W E27 barwa ciepła biała
|
||||
shopify_PL_8454759842132_46733043466580 Kobi Light żarówka LED E27 7W barwa neutralna biała 4000K 600lm 2425
|
||||
shopify_PL_8459153473876_46746440270164 Kobi Light żarówka LED świecowa E14 1,5W 150 lm zimnobiała 6000K 2425
|
||||
shopify_PL_8476790358356_46803775684948 Kobi Light żarówki LED E27 7W 4000K neutralne białe zestaw 10 sztuk 2425
|
||||
|
||||
|
@@ -1559,7 +1559,13 @@ $( function()
|
||||
( AI_CLAUDE_ENABLED ? '<button type="button" class="btn btn-sm btn-ai-suggest btn-ai-claude" data-field="title" data-provider="claude" title="Zaproponuj tytuł przez Claude"><i class="fa-solid fa-brain"></i> Claude</button>' : '' ) +
|
||||
( AI_GEMINI_ENABLED ? '<button type="button" class="btn btn-sm btn-ai-suggest btn-ai-gemini" data-field="title" data-provider="gemini" title="Zaproponuj tytuł przez Gemini"><i class="fa-solid fa-diamond"></i> Gemini</button>' : '' ) +
|
||||
'</div>' +
|
||||
'<small class="js-title-char-count">0/150 znaków</small>' +
|
||||
'<div class="original-title-row" style="display:flex;align-items:center;gap:8px;margin-top:6px;">' +
|
||||
'<small class="text-muted">Oryginalny tytul:</small>' +
|
||||
'<small class="js-original-product-title" style="flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;" title="' + escape_html( current_product_name ) + '">' + escape_html( current_product_name ) + '</small>' +
|
||||
'<button type="button" class="btn btn-xs btn-default js-copy-original-title" title="Kopiuj oryginalny tytul" aria-label="Kopiuj oryginalny tytul">' +
|
||||
'<i class="fa-regular fa-copy"></i>' +
|
||||
'</button>' +
|
||||
'</div>' +
|
||||
'<div class="title-ai-alternatives" style="margin-top:8px;display:none;"></div>' +
|
||||
'</div>' +
|
||||
'<div class="form-group">' +
|
||||
@@ -1652,18 +1658,18 @@ $( function()
|
||||
var jc = this;
|
||||
var $form = this.$content.find( 'form' );
|
||||
var $inputField = this.$content.find( '.name' );
|
||||
var $charCount = this.$content.find( '.js-title-char-count' );
|
||||
var $originalTitle = this.$content.find( '.js-original-product-title' );
|
||||
var $description = this.$content.find( '.description' );
|
||||
var $productUrl = this.$content.find( '.product-url' );
|
||||
var $googleCategory = this.$content.find( '.google-category' );
|
||||
var $titleAlternatives = this.$content.find( '.title-ai-alternatives' );
|
||||
var originalProductName = current_product_name;
|
||||
var product_id = $inputField.attr( 'product_id' );
|
||||
|
||||
function set_title_value( value ) {
|
||||
value = String( value || '' );
|
||||
$inputField.val( value );
|
||||
var len = value.length;
|
||||
$charCount.text( len + '/150 znaków' );
|
||||
$inputField.toggleClass( 'is-invalid', len > 150 );
|
||||
}
|
||||
|
||||
@@ -1713,6 +1719,10 @@ $( function()
|
||||
success: function( response ) {
|
||||
var data = JSON.parse( response );
|
||||
if ( data.status == 'ok' ) {
|
||||
if ( data.product_details.name ) {
|
||||
originalProductName = String( data.product_details.name );
|
||||
$originalTitle.text( originalProductName ).attr( 'title', originalProductName );
|
||||
}
|
||||
if ( data.product_details.title ) {
|
||||
set_title_value( data.product_details.title );
|
||||
}
|
||||
@@ -1744,7 +1754,6 @@ $( function()
|
||||
|
||||
$inputField.on( 'input', function() {
|
||||
var len = $( this ).val().length;
|
||||
$charCount.text( len + '/150 znaków' );
|
||||
$( this ).toggleClass( 'is-invalid', len > 150 );
|
||||
});
|
||||
|
||||
@@ -1831,12 +1840,49 @@ $( function()
|
||||
: '<i class="fa-solid fa-list"></i> Pokaż alternatywy (' + $list.find( '.js-title-alt-apply' ).length + ')'
|
||||
);
|
||||
} );
|
||||
|
||||
this.$content.on( 'click', '.js-title-alt-apply', function() {
|
||||
var selectedTitle = $( this ).attr( 'data-title-alt' ) || '';
|
||||
set_title_value( selectedTitle );
|
||||
} );
|
||||
|
||||
this.$content.on( 'click', '.js-copy-original-title', function() {
|
||||
var originalTitle = $.trim( String( originalProductName || '' ) );
|
||||
|
||||
if ( !originalTitle ) {
|
||||
show_toast( 'Brak oryginalnego tytulu do skopiowania.', 'error' );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( navigator.clipboard && typeof navigator.clipboard.writeText === 'function' ) {
|
||||
navigator.clipboard.writeText( originalTitle )
|
||||
.then( function() {
|
||||
show_toast( 'Oryginalny tytul skopiowany.', 'success' );
|
||||
} )
|
||||
.catch( function() {
|
||||
show_toast( 'Nie udalo sie skopiowac tytulu.', 'error' );
|
||||
} );
|
||||
return;
|
||||
}
|
||||
|
||||
var $tmp = $( '<textarea>' ).css({
|
||||
position: 'fixed',
|
||||
opacity: 0,
|
||||
pointerEvents: 'none'
|
||||
}).val( originalTitle ).appendTo( 'body' );
|
||||
|
||||
$tmp.trigger( 'focus' );
|
||||
$tmp.trigger( 'select' );
|
||||
|
||||
try {
|
||||
var copied = document.execCommand( 'copy' );
|
||||
show_toast( copied ? 'Oryginalny tytul skopiowany.' : 'Nie udalo sie skopiowac tytulu.', copied ? 'success' : 'error' );
|
||||
} catch ( err ) {
|
||||
show_toast( 'Nie udalo sie skopiowac tytulu.', 'error' );
|
||||
}
|
||||
|
||||
$tmp.remove();
|
||||
} );
|
||||
|
||||
$form.on( 'submit', function( e ) {
|
||||
e.preventDefault();
|
||||
jc.$$formSubmit.trigger( 'click' );
|
||||
|
||||
Reference in New Issue
Block a user