update
This commit is contained in:
309
api.php
309
api.php
@@ -58,7 +58,8 @@ function api_validate_api_key( $mdb )
|
||||
function api_get_product_by_offer_and_client( $mdb, $offer_id, $client_id )
|
||||
{
|
||||
return $mdb -> query(
|
||||
'SELECT p.id, p.title AS name, p.title_gmc AS title, p.google_product_category, p.custom_label_3, p.custom_label_4
|
||||
'SELECT p.id, p.title AS name, p.title_gmc AS title, p.google_product_category, p.custom_label_3, p.custom_label_4,
|
||||
p.unit_pricing_measure, p.unit_pricing_base_measure
|
||||
FROM products p
|
||||
JOIN clients cl ON p.client_id = cl.id
|
||||
WHERE p.offer_id = :offer_id
|
||||
@@ -114,6 +115,73 @@ function api_normalize_product_text( $value )
|
||||
return $value;
|
||||
}
|
||||
|
||||
function api_parse_unit_pricing_value( $value )
|
||||
{
|
||||
$raw = trim( (string) $value );
|
||||
if ( $raw === '' )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( !preg_match( '/^(\d+(?:\.\d+)?)\s+(ml|l|mg|g|kg|cl|m|cm|sqm|cbm|ct|szt)$/i', $raw, $matches ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return [
|
||||
'raw' => $raw,
|
||||
'amount' => (float) $matches[1],
|
||||
'unit' => strtolower( (string) $matches[2] )
|
||||
];
|
||||
}
|
||||
|
||||
function api_validate_unit_pricing_pair( $measure_raw, $base_raw )
|
||||
{
|
||||
$measure = api_parse_unit_pricing_value( $measure_raw );
|
||||
$base = api_parse_unit_pricing_value( $base_raw );
|
||||
|
||||
if ( $measure === false )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Invalid unit_pricing_measure format' ], 422 );
|
||||
}
|
||||
|
||||
if ( $base === false )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Invalid unit_pricing_base_measure format' ], 422 );
|
||||
}
|
||||
|
||||
if ( $measure === null && $base === null )
|
||||
{
|
||||
return [ null, null ];
|
||||
}
|
||||
|
||||
if ( $measure === null || $base === null )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Both unit_pricing fields must be provided together or both empty' ], 422 );
|
||||
}
|
||||
|
||||
if ( $measure['unit'] !== $base['unit'] )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'unit_pricing_measure and unit_pricing_base_measure must use the same unit' ], 422 );
|
||||
}
|
||||
|
||||
$standard_base = [
|
||||
'ml' => 100.0,
|
||||
'g' => 100.0,
|
||||
'l' => 1.0,
|
||||
'kg' => 1.0,
|
||||
'szt' => 1.0,
|
||||
'ct' => 1.0
|
||||
];
|
||||
|
||||
if ( isset( $standard_base[ $measure['unit'] ] ) && abs( $base['amount'] - $standard_base[ $measure['unit'] ] ) > 0.000001 )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Invalid unit_pricing_base_measure value for selected unit' ], 422 );
|
||||
}
|
||||
|
||||
return [ $measure['raw'], $base['raw'] ];
|
||||
}
|
||||
|
||||
function api_resolve_client( $mdb, $client_id, $google_ads_id )
|
||||
{
|
||||
if ( $client_id > 0 )
|
||||
@@ -401,6 +469,97 @@ if ( \S::get( 'action' ) == 'product_custom_label_4_get' )
|
||||
] );
|
||||
}
|
||||
|
||||
// Zmiana unit pricing dla produktu przez API
|
||||
if ( \S::get( 'action' ) == 'product_unit_pricing_set' )
|
||||
{
|
||||
api_validate_api_key( $mdb );
|
||||
|
||||
$offer_id = trim( (string) \S::get( 'offer_id' ) );
|
||||
$client_id_param = (int) \S::get( 'client_id' );
|
||||
$unit_pricing_measure_raw = (string) ( \S::get( 'unit_pricing_measure' ) ?? '' );
|
||||
$unit_pricing_base_measure_raw = (string) ( \S::get( 'unit_pricing_base_measure' ) ?? '' );
|
||||
|
||||
if ( $offer_id === '' || $client_id_param <= 0 )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Missing required params: offer_id, client_id' ], 422 );
|
||||
}
|
||||
|
||||
$product = api_get_product_by_offer_and_client( $mdb, $offer_id, $client_id_param );
|
||||
|
||||
if ( !$product )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Product not found' ], 404 );
|
||||
}
|
||||
|
||||
[ $unit_pricing_measure, $unit_pricing_base_measure ] = api_validate_unit_pricing_pair(
|
||||
$unit_pricing_measure_raw,
|
||||
$unit_pricing_base_measure_raw
|
||||
);
|
||||
|
||||
$updated = $mdb -> update(
|
||||
'products',
|
||||
[
|
||||
'unit_pricing_measure' => $unit_pricing_measure,
|
||||
'unit_pricing_base_measure' => $unit_pricing_base_measure,
|
||||
'unit_pricing_changed_at' => date( 'Y-m-d H:i:s' )
|
||||
],
|
||||
[ 'id' => (int) $product['id'] ]
|
||||
);
|
||||
|
||||
if ( $updated === false )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Failed to update unit_pricing' ], 500 );
|
||||
}
|
||||
|
||||
\factory\Products::add_product_comment(
|
||||
(int) $product['id'],
|
||||
'Zmiana unit_pricing na ' . ( $unit_pricing_measure !== null ? $unit_pricing_measure : '(puste)' )
|
||||
. ' / '
|
||||
. ( $unit_pricing_base_measure !== null ? $unit_pricing_base_measure : '(puste)' )
|
||||
. ' (API)'
|
||||
);
|
||||
|
||||
api_json_response( [
|
||||
'result' => 'ok',
|
||||
'product_id' => (int) $product['id'],
|
||||
'offer_id' => $offer_id,
|
||||
'unit_pricing_measure' => $unit_pricing_measure,
|
||||
'unit_pricing_base_measure' => $unit_pricing_base_measure
|
||||
] );
|
||||
}
|
||||
|
||||
// Odczyt unit pricing dla produktu przez API
|
||||
if ( \S::get( 'action' ) == 'product_unit_pricing_get' )
|
||||
{
|
||||
api_validate_api_key( $mdb );
|
||||
|
||||
$offer_id = trim( (string) \S::get( 'offer_id' ) );
|
||||
$client_id_param = (int) \S::get( 'client_id' );
|
||||
|
||||
if ( $offer_id === '' || $client_id_param <= 0 )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Missing required params: offer_id, client_id' ], 422 );
|
||||
}
|
||||
|
||||
$product = api_get_product_by_offer_and_client( $mdb, $offer_id, $client_id_param );
|
||||
|
||||
if ( !$product )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Product not found' ], 404 );
|
||||
}
|
||||
|
||||
$measure = trim( (string) ( $product['unit_pricing_measure'] ?? '' ) );
|
||||
$base = trim( (string) ( $product['unit_pricing_base_measure'] ?? '' ) );
|
||||
|
||||
api_json_response( [
|
||||
'result' => 'ok',
|
||||
'product_id' => (int) $product['id'],
|
||||
'offer_id' => $offer_id,
|
||||
'unit_pricing_measure' => $measure !== '' ? $measure : null,
|
||||
'unit_pricing_base_measure' => $base !== '' ? $base : null
|
||||
] );
|
||||
}
|
||||
|
||||
// Zmiana tytulu produktu przez API
|
||||
if ( \S::get( 'action' ) == 'product_title_set' )
|
||||
{
|
||||
@@ -616,6 +775,94 @@ if ( \S::get( 'action' ) == 'products_unoptimized_list' )
|
||||
] );
|
||||
}
|
||||
|
||||
// Lista produktow bez unit pricing dla kategorii beauty/cosmetics
|
||||
if ( \S::get( 'action' ) == 'products_get_missing_unit_pricing' )
|
||||
{
|
||||
api_validate_api_key( $mdb );
|
||||
|
||||
$client_id_param = (int) \S::get( 'client_id' );
|
||||
$top = (int) \S::get( 'top' );
|
||||
$category_filter = trim( (string) \S::get( 'category_filter' ) );
|
||||
|
||||
if ( $client_id_param <= 0 )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Missing required param: client_id' ], 422 );
|
||||
}
|
||||
|
||||
if ( $top <= 0 || $top > 200 )
|
||||
{
|
||||
$top = 50;
|
||||
}
|
||||
|
||||
$where_sql = 'p.client_id = :client_id
|
||||
AND TRIM( COALESCE( p.offer_id, \'\' ) ) <> \'\'
|
||||
AND (
|
||||
p.unit_pricing_measure IS NULL OR TRIM( p.unit_pricing_measure ) = \'\'
|
||||
OR p.unit_pricing_base_measure IS NULL OR TRIM( p.unit_pricing_base_measure ) = \'\'
|
||||
)';
|
||||
|
||||
$params = [ ':client_id' => $client_id_param, ':top' => $top ];
|
||||
|
||||
if ( $category_filter !== '' )
|
||||
{
|
||||
$where_sql .= ' AND p.google_product_category LIKE :category_filter';
|
||||
$params[':category_filter'] = '%' . $category_filter . '%';
|
||||
}
|
||||
else
|
||||
{
|
||||
$where_sql .= " AND (
|
||||
p.google_product_category LIKE '%Beauty%'
|
||||
OR p.google_product_category LIKE '%Health%'
|
||||
OR p.google_product_category LIKE '%Cosmetic%'
|
||||
OR p.google_product_category LIKE '%Skin Care%'
|
||||
OR p.google_product_category LIKE '%Higiena%'
|
||||
OR p.google_product_category LIKE '%Pielegnacj%'
|
||||
)";
|
||||
}
|
||||
|
||||
$rows = $mdb -> query(
|
||||
'SELECT p.id,
|
||||
p.offer_id,
|
||||
p.title AS default_name,
|
||||
p.title_gmc AS custom_title,
|
||||
p.google_product_category,
|
||||
p.unit_pricing_measure,
|
||||
p.unit_pricing_base_measure,
|
||||
COALESCE( SUM( pa.clicks_30 ), 0 ) AS clicks_30,
|
||||
COALESCE( SUM( pa.clicks_all_time ), 0 ) AS clicks_all_time
|
||||
FROM products p
|
||||
LEFT JOIN products_aggregate pa ON pa.product_id = p.id
|
||||
WHERE ' . $where_sql . '
|
||||
GROUP BY p.id
|
||||
ORDER BY clicks_all_time DESC, clicks_30 DESC
|
||||
LIMIT :top',
|
||||
$params
|
||||
) -> fetchAll( \PDO::FETCH_ASSOC );
|
||||
|
||||
$products = [];
|
||||
foreach ( (array) $rows as $row )
|
||||
{
|
||||
$products[] = [
|
||||
'product_id' => (int) ( $row['id'] ?? 0 ),
|
||||
'offer_id' => (string) ( $row['offer_id'] ?? '' ),
|
||||
'default_name' => trim( (string) ( $row['default_name'] ?? '' ) ),
|
||||
'custom_title' => trim( (string) ( $row['custom_title'] ?? '' ) ),
|
||||
'google_product_category' => trim( (string) ( $row['google_product_category'] ?? '' ) ),
|
||||
'unit_pricing_measure' => trim( (string) ( $row['unit_pricing_measure'] ?? '' ) ),
|
||||
'unit_pricing_base_measure' => trim( (string) ( $row['unit_pricing_base_measure'] ?? '' ) ),
|
||||
'clicks_30' => (int) ( $row['clicks_30'] ?? 0 ),
|
||||
'clicks_all_time' => (int) ( $row['clicks_all_time'] ?? 0 )
|
||||
];
|
||||
}
|
||||
|
||||
api_json_response( [
|
||||
'result' => 'ok',
|
||||
'client_id' => $client_id_param,
|
||||
'count' => count( $products ),
|
||||
'products' => $products
|
||||
] );
|
||||
}
|
||||
|
||||
// Odczyt minimalnego ROAS produktu przez API
|
||||
if ( \S::get( 'action' ) == 'product_min_roas_get' )
|
||||
{
|
||||
@@ -961,6 +1208,66 @@ if ( \S::get( 'action' ) == 'products_get_by_cl1' )
|
||||
] );
|
||||
}
|
||||
|
||||
// Lista produktów filtrowana po custom_label_4 (np. CL4=bestseller dla Shopping/Zombie pipeline)
|
||||
if ( \S::get( 'action' ) == 'products_get_by_cl4' )
|
||||
{
|
||||
api_validate_api_key( $mdb );
|
||||
|
||||
$client_id_param = (int) \S::get( 'client_id' );
|
||||
$cl4_value = trim( (string) \S::get( 'custom_label_4' ) );
|
||||
|
||||
if ( $client_id_param <= 0 )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Missing required param: client_id' ], 422 );
|
||||
}
|
||||
|
||||
if ( $cl4_value === '' )
|
||||
{
|
||||
api_json_response( [ 'result' => 'error', 'message' => 'Missing required param: custom_label_4' ], 422 );
|
||||
}
|
||||
|
||||
$rows = $mdb -> query(
|
||||
'SELECT p.id, p.offer_id, p.title AS name, p.title_gmc AS title, p.google_product_category,
|
||||
p.custom_label_1, p.custom_label_3, p.custom_label_4
|
||||
FROM products p
|
||||
WHERE p.client_id = :client_id
|
||||
AND p.custom_label_4 = :cl4
|
||||
ORDER BY p.offer_id',
|
||||
[
|
||||
':client_id' => $client_id_param,
|
||||
':cl4' => $cl4_value
|
||||
]
|
||||
) -> fetchAll( \PDO::FETCH_ASSOC );
|
||||
|
||||
$products = [];
|
||||
foreach ( $rows as $row )
|
||||
{
|
||||
$base_name = trim( (string) ( $row['name'] ?? '' ) );
|
||||
$custom_title = trim( (string) ( $row['title'] ?? '' ) );
|
||||
$title = $custom_title !== '' ? $custom_title : $base_name;
|
||||
$google_category = trim( (string) ( $row['google_product_category'] ?? '' ) );
|
||||
|
||||
$products[] = [
|
||||
'offer_id' => (string) ( $row['offer_id'] ?? '' ),
|
||||
'title' => $title,
|
||||
'default_name' => $base_name,
|
||||
'custom_title' => $custom_title !== '' ? $custom_title : null,
|
||||
'google_product_category' => $google_category !== '' ? $google_category : null,
|
||||
'custom_label_1' => trim( (string) ( $row['custom_label_1'] ?? '' ) ),
|
||||
'custom_label_3' => trim( (string) ( $row['custom_label_3'] ?? '' ) ),
|
||||
'custom_label_4' => trim( (string) ( $row['custom_label_4'] ?? '' ) )
|
||||
];
|
||||
}
|
||||
|
||||
api_json_response( [
|
||||
'result' => 'ok',
|
||||
'client_id' => $client_id_param,
|
||||
'custom_label_4' => $cl4_value,
|
||||
'count' => count( $products ),
|
||||
'products' => $products
|
||||
] );
|
||||
}
|
||||
|
||||
// Open Page Rank - zapis
|
||||
if ( \S::get( 'action' ) == 'domain_opr_save' )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user