Files
adsPRO/autoload/controls/class.Api.php
Jacek Pyziak 4635cefcbb feat: update font to Roboto across templates and add campaign/ad group filters in product views
- Changed font from Open Sans to Roboto in layout files.
- Added campaign and ad group filters in products main view.
- Enhanced product history to include campaign and ad group IDs.
- Updated migrations to support new campaign and ad group dimensions in product statistics.
- Introduced new migration files for managing campaign types and dropping obsolete columns.
2026-02-18 01:21:22 +01:00

520 lines
19 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace controls;
class Api
{
static public function campaigns_data_save()
{
global $mdb;
$json = file_get_contents( 'php://input' );
$data = json_decode( $json, true );
if ( $data['clientId'] and $data['date'] )
{
foreach ( $data['data'] as $campaign )
{
if ( !$mdb -> count( 'campaigns', [ 'AND' => [ 'client_id' => $data['clientId'], 'campaign_id' => $campaign['campaignId'] ] ] ) )
{
$campaign_data['client_id'] = $data['clientId'];
$campaign_data['campaign_id'] = $campaign['campaignId'];
$campaign_data['campaign_name'] = $campaign['camapignName'];
$mdb -> insert( 'campaigns', [
'client_id' => $data['clientId'],
'campaign_id' => $campaign['campaignId'],
'campaign_name' => $campaign['camapignName']
] );
$campaign_id = $mdb -> id();
}
else
{
$campaign_id = $mdb -> get( 'campaigns', 'id', [ 'AND' => [ 'client_id' => $data['clientId'], 'campaign_id' => $campaign['campaignId'] ] ] );
}
if ( $campaign_id )
{
$campaign_history_data = [];
$campaign_history_data['roas_30_days'] = $campaign['roas30Days'];
$campaign_history_data['roas_all_time'] = $campaign['roasAllTime'];
$campaign_history_data['budget'] = str_replace( ' zł', '' , $campaign['budget'] );
$campaign_history_data['money_spent'] = floatval( preg_replace(['/[^0-9,]/', '/,/'], ['', '.'], $campaign['spend30Days'] ) );
$campaign_history_data['conversion_value'] = preg_replace( '/[^\d,.-]/', '', $campaign['conversionValue30Days'] );
if ( isset( $campaign['biddingStrategy'] ) and $campaign['biddingStrategy'] == 'MAXIMIZE_CONVERSIONS' )
{
$campaign_history_data['bidding_strategy'] = 'Maksymalizacja liczby konwersji';
}
else if ( isset( $campaign['biddingStrategy'] ) and $campaign['biddingStrategy'] == 'MAXIMIZE_CONVERSION_VALUE' )
{
$campaign_history_data['bidding_strategy'] = 'Maksymalizacja wartości konwersji';
}
else if ( isset( $campaign['biddingStrategy'] ) and $campaign['biddingStrategy'] == 'TARGET_ROAS' )
{
$campaign_history_data['bidding_strategy'] = 'Docelowy ROAS';
}
else if ( isset( $campaign['biddingStrategy'] ) )
{
$campaign_history_data['bidding_strategy'] = $campaign['biddingStrategy'];
}
else
{
$campaign_history_data['bidding_strategy'] = 'brak';
}
if ( isset( $campaign['targetRoas'] ) and (float)$campaign['targetRoas'] > 0 )
{
$campaign_history_data['bidding_strategy'] .= ' | docelowy ROAS: ' . ( (float)$campaign['targetRoas'] * 100 ) . '%';
}
if ( $mdb -> count( 'campaigns_history', [ 'AND' => [ 'campaign_id' => $campaign_id, 'date_add' => $data['date'] ] ] ) )
{
$mdb -> update( 'campaigns_history', $campaign_history_data, [ 'AND' => [ 'campaign_id' => $campaign_id, 'date_add' => $data['date'] ] ] );
}
else
{
$campaign_history_data['campaign_id'] = $campaign_id;
$campaign_history_data['date_add'] = $data['date'];
$mdb -> insert( 'campaigns_history', $campaign_history_data );
}
}
}
}
echo json_encode( [ 'status' => 'ok' ] );
exit;
}
static public function phrases_data_save()
{
global $mdb;
$json = file_get_contents( 'php://input' );
$data = json_decode( $json, true );
if ( $data['client_id'] and $data['date'] )
{
foreach ( $data['data'] as $phrase )
{
$phrase_data = [];
if ( !$mdb -> count( 'phrases', [ 'AND' => [ 'client_id' => $data['client_id'], 'phrase' => $phrase['Query'] ] ] ) )
{
$phrase_data['phrase'] = $phrase['Query'];
$mdb -> insert( 'phrases', [
'client_id' => $data['client_id'],
'phrase' => $phrase['Query']
] );
$phrase_id = $mdb -> id();
}
else
{
$phrase_id = $mdb -> get( 'phrases', 'id', [ 'AND' => [ 'client_id' => $data['client_id'], 'phrase' => $phrase['Query'] ] ] );
}
if ( $phrase_id )
{
$phrase_data['impressions'] = $phrase['Impressions'];
$phrase_data['clicks'] = $phrase['Clicks'];
$phrase_data['cost'] = $phrase['Cost'];
$phrase_data['conversions'] = $phrase['Conversions'];
$phrase_data['conversions_value'] = preg_replace( '/[^\d,.-]/', '', $phrase['ConversionValue'] );
$phrase_data['updated'] = 1;
if ( $mdb -> count( 'phrases_history', [ 'AND' => [ 'phrase_id' => $phrase_id, 'date_add' => $data['date'] ] ] ) )
{
$phrase_data_old = [];
$phrase_data_old = $mdb -> get( 'phrases_history', '*', [ 'AND' => [ 'phrase_id' => $phrase_id, 'date_add' => $data['date'] ] ] );
if (
$phrase_data_old['impressions'] == $phrase_data['impressions']
and $phrase_data_old['clicks'] == $phrase_data['clicks']
and number_format((float)str_replace(',', '.', $phrase_data_old['cost']), 5) == number_format((float)$phrase_data['cost'], 5)
and $phrase_data_old['conversions'] == $phrase_data['conversions']
and number_format((float)str_replace(',', '.', $phrase_data_old['conversions_value']), 5) == number_format((float)$phrase_data['conversions_value'], 5)
) {
continue;
}
$mdb -> update( 'phrases_history', [
'impressions' => $phrase_data['impressions'],
'clicks' => $phrase_data['clicks'],
'cost' => $phrase_data['cost'],
'conversions' => $phrase_data['conversions'],
'conversions_value' => $phrase_data['conversions_value'],
'updated' => 1
], [
'AND' => [ 'phrase_id' => $phrase_id, 'date_add' => $data['date'] ]
] );
}
else
{
$mdb -> insert( 'phrases_history', [
'phrase_id' => $phrase_id,
'date_add' => $data['date'],
'impressions' => $phrase_data['impressions'],
'clicks' => $phrase_data['clicks'],
'cost' => $phrase_data['cost'],
'conversions' => $phrase_data['conversions'],
'conversions_value' => $phrase_data['conversions_value'],
'updated' => 1
] );
}
}
}
}
echo json_encode( [ 'status' => 'ok' ] );
exit;
}
static public function products_data_save()
{
global $mdb;
$json = file_get_contents( 'php://input' );
$data = json_decode( $json, true );
// file_put_contents( 'tmp/products_data_save.txt', print_r( $data, true ) );
if ( $data['client_id'] and $data['date'] )
{
foreach ( $data['data'] as $offer )
{
$offer_data = [];
if ( !$mdb -> count( 'products', [ 'AND' => [ 'client_id' => $data['client_id'], 'offer_id' => $offer['OfferId'] ] ] ) )
{
$offer_data['client_id'] = $data['client_id'];
$offer_data['offer_id'] = $offer['OfferId'];
$offer_data['offer_name'] = $offer['ProductTitle'];
$mdb -> insert( 'products', [
'client_id' => $data['client_id'],
'offer_id' => $offer['OfferId'],
'name' => $offer['ProductTitle']
] );
$offer_id = $mdb -> id();
}
else
{
$offer_id = $mdb -> get( 'products', 'id', [ 'AND' => [ 'client_id' => $data['client_id'], 'offer_id' => $offer['OfferId'] ] ] );
$offer_current_name = $mdb -> get( 'products', 'name', [ 'AND' => [ 'client_id' => $data['client_id'], 'offer_id' => $offer['OfferId'] ] ] );
if ( $offer_current_name != $offer['ProductTitle'] and $data['date'] == date( 'Y-m-d', strtotime( '-1 days', time() ) ) )
{
$mdb -> update( 'products', [ 'name' => $offer['ProductTitle'] ], [ 'AND' => [ 'client_id' => $data['client_id'], 'offer_id' => $offer['OfferId'] ] ] );
}
}
if ( $offer_id )
{
$offer_data['impressions'] = $offer['Impressions'];
$offer_data['clicks'] = $offer['Clicks'];
$offer_data['ctr'] = round( $offer['Clicks'] / $offer['Impressions'], 4 ) * 100;
$offer_data['cost'] = preg_replace( '/[^\d,.-]/', '', $offer['Cost'] );
$offer_data['conversions'] = $offer['Conversions'];
$offer_data['conversions_value'] = preg_replace( '/[^\d,.-]/', '', $offer['ConversionValue'] );
$offer_data['updated'] = 1;
if ( $mdb -> count( 'products_history', [ 'AND' => [ 'product_id' => $offer_id, 'date_add' => $data['date'] ] ] ) )
{
$offer_data_old = [];
$offer_data_old = $mdb -> get( 'products_history', '*', [ 'AND' => [ 'product_id' => $offer_id, 'date_add' => $data['date'] ] ] );
if (
$offer_data_old['impressions'] == $offer_data['impressions']
and $offer_data_old['clicks'] == $offer_data['clicks']
and number_format((float)str_replace(',', '.', $offer_data_old['cost']), 5) == number_format((float)$offer_data['cost'], 5)
and $offer_data_old['conversions'] == $offer_data['conversions']
and number_format((float)str_replace(',', '.', $offer_data_old['conversions_value']), 5) == number_format((float)$offer_data['conversions_value'], 5)
) {
continue;
}
$mdb -> update( 'products_history', [
'impressions' => $offer_data['impressions'],
'clicks' => $offer_data['clicks'],
'ctr' => $offer_data['ctr'],
'cost' => $offer_data['cost'],
'conversions' => $offer_data['conversions'],
'conversions_value' => $offer_data['conversions_value'],
'updated' => 1
], [
'AND' => [ 'product_id' => $offer_id, 'date_add' => $data['date'] ]
] );
}
else
{
$mdb -> insert( 'products_history', [
'product_id' => $offer_id,
'date_add' => $data['date'],
'impressions' => $offer_data['impressions'],
'clicks' => $offer_data['clicks'],
'ctr' => $offer_data['ctr'],
'cost' => $offer_data['cost'],
'conversions' => $offer_data['conversions'],
'conversions_value' => $offer_data['conversions_value'],
'updated' => 1
] );
}
}
}
}
echo json_encode( [ 'status' => 'ok' ] );
exit;
}
static public function products_data_import()
{
global $mdb;
$json = file_get_contents( 'php://input' );
$data = json_decode( $json, true );
if ( !is_array( $data ) || empty( $data['client_id'] ) || empty( $data['date'] ) || !isset( $data['data'] ) || !is_array( $data['data'] ) )
{
echo json_encode( [ 'status' => 'error', 'message' => 'Nieprawidlowe dane wejsciowe. Oczekiwano: client_id, date, data[].' ] );
exit;
}
$client_id = (int) $data['client_id'];
$date = date( 'Y-m-d', strtotime( $data['date'] ) );
if ( !$mdb -> count( 'clients', [ 'id' => $client_id ] ) )
{
echo json_encode( [ 'status' => 'error', 'message' => 'Nie znaleziono klienta o podanym ID.' ] );
exit;
}
$processed = 0;
$skipped = 0;
$touched_scopes = [];
foreach ( $data['data'] as $offer )
{
$offer_external_id = trim( (string) ( $offer['OfferId'] ?? '' ) );
if ( $offer_external_id === '' )
{
$skipped++;
continue;
}
$product_title = trim( (string) ( $offer['ProductTitle'] ?? '' ) );
if ( $product_title === '' )
{
$product_title = $offer_external_id;
}
if ( !$mdb -> count( 'products', [ 'AND' => [ 'client_id' => $client_id, 'offer_id' => $offer_external_id ] ] ) )
{
$mdb -> insert( 'products', [
'client_id' => $client_id,
'offer_id' => $offer_external_id,
'name' => $product_title
] );
$product_id = $mdb -> id();
}
else
{
$product_id = $mdb -> get( 'products', 'id', [ 'AND' => [ 'client_id' => $client_id, 'offer_id' => $offer_external_id ] ] );
$offer_current_name = $mdb -> get( 'products', 'name', [ 'AND' => [ 'client_id' => $client_id, 'offer_id' => $offer_external_id ] ] );
if ( $offer_current_name != $product_title and $date == date( 'Y-m-d', strtotime( '-1 days', time() ) ) )
{
$mdb -> update( 'products', [ 'name' => $product_title ], [ 'AND' => [ 'client_id' => $client_id, 'offer_id' => $offer_external_id ] ] );
}
}
if ( !$product_id )
{
$skipped++;
continue;
}
$campaign_external_id = (int) self::normalize_number( $offer['CampaignId'] ?? ( $offer['campaign_id'] ?? 0 ) );
$campaign_name = trim( (string) ( $offer['CampaignName'] ?? ( $offer['campaign_name'] ?? '' ) ) );
$ad_group_external_id = (int) self::normalize_number( $offer['AdGroupId'] ?? ( $offer['ad_group_id'] ?? 0 ) );
$ad_group_name = trim( (string) ( $offer['AdGroupName'] ?? ( $offer['ad_group_name'] ?? '' ) ) );
$scope = \controls\Cron::resolve_products_scope_ids(
$client_id,
$campaign_external_id,
$campaign_name,
$ad_group_external_id,
$ad_group_name,
$date
);
$db_campaign_id = (int) ( $scope['campaign_id'] ?? 0 );
$db_ad_group_id = (int) ( $scope['ad_group_id'] ?? 0 );
$impressions = (int) round( self::normalize_number( $offer['Impressions'] ?? 0 ) );
$clicks = (int) round( self::normalize_number( $offer['Clicks'] ?? 0 ) );
$cost = self::normalize_number( $offer['Cost'] ?? 0 );
$conversions = self::normalize_number( $offer['Conversions'] ?? 0 );
$conversion_value = self::normalize_number( $offer['ConversionValue'] ?? 0 );
$ctr = ( $impressions > 0 ) ? round( $clicks / $impressions, 4 ) * 100 : 0;
$offer_data = [
'impressions' => $impressions,
'clicks' => $clicks,
'ctr' => $ctr,
'cost' => $cost,
'conversions' => $conversions,
'conversions_value' => $conversion_value,
'updated' => 1,
'campaign_id' => $db_campaign_id,
'ad_group_id' => $db_ad_group_id
];
if ( $mdb -> count( 'products_history', [ 'AND' => [
'product_id' => $product_id,
'campaign_id' => $db_campaign_id,
'ad_group_id' => $db_ad_group_id,
'date_add' => $date
] ] ) )
{
$offer_data_old = $mdb -> get( 'products_history', '*', [ 'AND' => [
'product_id' => $product_id,
'campaign_id' => $db_campaign_id,
'ad_group_id' => $db_ad_group_id,
'date_add' => $date
] ] );
if (
$offer_data_old['impressions'] == $offer_data['impressions']
and $offer_data_old['clicks'] == $offer_data['clicks']
and number_format( (float) str_replace( ',', '.', $offer_data_old['cost'] ), 5 ) == number_format( (float) $offer_data['cost'], 5 )
and (float) $offer_data_old['conversions'] == (float) $offer_data['conversions']
and number_format( (float) str_replace( ',', '.', $offer_data_old['conversions_value'] ), 5 ) == number_format( (float) $offer_data['conversions_value'], 5 )
)
{
$scope_key = (int) $product_id . '|' . $db_campaign_id . '|' . $db_ad_group_id;
$touched_scopes[ $scope_key ] = [
'product_id' => (int) $product_id,
'campaign_id' => $db_campaign_id,
'ad_group_id' => $db_ad_group_id
];
$processed++;
continue;
}
$mdb -> update( 'products_history', $offer_data, [
'AND' => [
'product_id' => $product_id,
'campaign_id' => $db_campaign_id,
'ad_group_id' => $db_ad_group_id,
'date_add' => $date
]
] );
}
else
{
$offer_data['product_id'] = $product_id;
$offer_data['date_add'] = $date;
$mdb -> insert( 'products_history', $offer_data );
}
$scope_key = (int) $product_id . '|' . $db_campaign_id . '|' . $db_ad_group_id;
$touched_scopes[ $scope_key ] = [
'product_id' => (int) $product_id,
'campaign_id' => $db_campaign_id,
'ad_group_id' => $db_ad_group_id
];
$processed++;
}
$history_30_rows = 0;
foreach ( $touched_scopes as $scope )
{
$product_id = (int) ( $scope['product_id'] ?? 0 );
$campaign_id = (int) ( $scope['campaign_id'] ?? 0 );
$ad_group_id = (int) ( $scope['ad_group_id'] ?? 0 );
\controls\Cron::cron_product_history_30_save( $product_id, $date, $campaign_id, $ad_group_id );
$mdb -> update( 'products_history', [ 'updated' => 0 ], [ 'AND' => [
'product_id' => $product_id,
'campaign_id' => $campaign_id,
'ad_group_id' => $ad_group_id,
'date_add' => $date
] ] );
$history_30_rows++;
}
$temp_rows = \controls\Cron::rebuild_products_temp_for_client( $client_id );
echo json_encode( [
'status' => 'ok',
'client_id' => $client_id,
'date' => $date,
'processed' => $processed,
'skipped' => $skipped,
'history_30_products' => $history_30_rows,
'products_temp_rows' => $temp_rows
] );
exit;
}
static private function rebuild_products_temp_for_client( $client_id )
{
return \controls\Cron::rebuild_products_temp_for_client( $client_id );
}
static private function normalize_number( $value )
{
if ( $value === null || $value === '' )
{
return 0.0;
}
if ( is_int( $value ) || is_float( $value ) )
{
return (float) $value;
}
$value = trim( (string) $value );
if ( $value === '' )
{
return 0.0;
}
$value = preg_replace( '/[^\d,.\-]/', '', $value );
if ( $value === '' || $value === '-' || $value === ',' || $value === '.' )
{
return 0.0;
}
$has_comma = strpos( $value, ',' ) !== false;
$has_dot = strpos( $value, '.' ) !== false;
if ( $has_comma && $has_dot )
{
$last_comma = strrpos( $value, ',' );
$last_dot = strrpos( $value, '.' );
if ( $last_comma > $last_dot )
{
$value = str_replace( '.', '', $value );
$value = str_replace( ',', '.', $value );
}
else
{
$value = str_replace( ',', '', $value );
}
}
else
{
$value = str_replace( ',', '.', $value );
}
return (float) $value;
}
}