Files
adsPRO/autoload/controls/class.Products.php

337 lines
11 KiB
PHP
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.
<?php
namespace controls;
class Products
{
static public function get_client_bestseller_min_roas() {
$client_id = \S::get( 'client_id' );
$min_roas = \factory\Products::get_client_bestseller_min_roas( $client_id );
if ( $min_roas )
{
echo json_encode( [ 'status' => 'ok', 'min_roas' => $min_roas ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function save_client_bestseller_min_roas() {
$client_id = \S::get( 'client_id' );
$min_roas = \S::get( 'min_roas' );
if ( \factory\Products::save_client_bestseller_min_roas( $client_id, $min_roas ) )
{
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function main_view()
{
return \Tpl::view( 'products/main_view', [
'clients' => \factory\Campaigns::get_clients(),
] );
}
static public function comment_add()
{
$product_id = \S::get( 'product_id' );
$date = \S::get( 'date' );
$comment = \S::get( 'comment' );
if ( \factory\Products::add_product_comment( $product_id, $comment, $date ) )
{
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function get_products()
{
$client_id = \S::get( 'client_id' );
$limit = \S::get( 'length' ) ? \S::get( 'length' ) : 10;
$start = \S::get( 'start' ) ? \S::get( 'start' ) : 0;
$order_dir = $_POST['order'][0]['dir'] ? strtoupper( $_POST['order'][0]['dir'] ) : 'DESC';
$order_name = $_POST['order'][0]['name'] ? $_POST['order'][0]['name'] : 'clicks';
$search = $_POST['search']['value'];
// ➊ MIN/MAX ROAS dla kontekstu klienta (opcjonalnie z filtrem search)
$bounds = \factory\Products::get_roas_bounds( $client_id, $search );
$roas_min = (float)$bounds['min'];
$roas_max = (float)$bounds['max'];
// zabezpieczenie przed dzieleniem przez 0
if ($roas_min === $roas_max) {
$roas_max = $roas_min + 0.000001;
}
// ➋ Helper do paska performance (lokalna funkcja)
$renderPerfBar = function (float $value, float $min, float $max): string
{
// normalizacja 0..1
$t = ($value - $min) / ($max - $min);
if ($t < 0) $t = 0;
if ($t > 1) $t = 1;
// szerokości
$minPx = 20; // minimalna długość paska
$maxPx = 120; // szerokość „toru”
$fill = (int)round($minPx + $t * ($maxPx - $minPx));
// kolor od #E74C3C (czerwony) do #2ECC71 (zielony)
$from = [231, 76, 60];
$to = [ 46,204,113];
$r = (int)round($from[0] + ($to[0] - $from[0]) * $t);
$g = (int)round($from[1] + ($to[1] - $from[1]) * $t);
$b = (int)round($from[2] + ($to[2] - $from[2]) * $t);
$hex = sprintf('#%02X%02X%02X', $r, $g, $b);
// prosty pasek (tor + wypełnienie)
return '<div class="roas-perf-wrap" title="Min: '.number_format($min,2).' | Max: '.number_format($max,2).'" style="margin-top:4px;width:'.$maxPx.'px;height:8px;background:#eee;border-radius:4px;overflow:hidden;">
<div class="roas-perf-fill" style="height:100%;width:'.$fill.'px;background:'.$hex.';"></div>
</div>';
};
$db_results = \factory\Products::get_products( $client_id, $search, $limit, $start, $order_name, $order_dir );
$recordsTotal = \factory\Products::get_records_total_products( $client_id, $search );
$data['draw'] = \S::get( 'draw' );
$data['recordsTotal'] = $recordsTotal;
$data['recordsFiltered'] = $recordsTotal;
foreach ( $db_results as $row )
{
$custom_class = '';
$custom_label_4 = \factory\Products::get_product_data( $row['product_id'], 'custom_label_4' );
$custom_name = \factory\Products::get_product_data( $row['product_id'], 'title' );
if ( $custom_name )
{
$row['name'] = $custom_name;
$custom_class = 'custom_name';
}
if ( $custom_label_4 == 'deleted' )
$custom_class = 'text-danger';
$custom_label_4_color = '';
if ( $custom_label_4 == 'bestseller' )
$custom_label_4_color = 'background-color:rgb(96, 119, 102); color: #FFF;';
else if ( $custom_label_4 == 'deleted' )
$custom_label_4_color = 'background-color:rgb(255, 0, 0); color: #FFF;';
else if ( $custom_label_4 == 'zombie' )
$custom_label_4_color = 'background-color:rgb(58, 58, 58); color: #FFF;';
else if ( $custom_label_4 == 'pla_single' )
$custom_label_4_color = 'background-color:rgb(49, 184, 9); color: #FFF;';
else if ( $custom_label_4 == 'pla' )
$custom_label_4_color = 'background-color:rgb(74, 63, 136); color: #FFF;';
else if ( $custom_label_4 == 'paused' )
$custom_label_4_color = 'background-color:rgb(143, 143, 143); color: #FFF;';
// ➌ ROAS liczba + pasek performance
$roasValue = (float)$row['roas'];
$roasNumeric = ($roasValue <= (float)$row['min_roas'])
? '<span class="text-danger text-bold">'.($roasValue).'</span>'
: $roasValue;
$roasPerfBar = $renderPerfBar($roasValue, $roas_min, $roas_max);
$roasCellHtml = '<div class="roas-cell">'.$roasNumeric.$roasPerfBar.'</div>';
$data['data'][] = [
$row['product_id'],
$row['offer_id'],
'<div class="table-product-title" product_id="' . $row['product_id'] . '">
<a href="/products/product_history/client_id=' . $client_id . '&product_id=' . $row['product_id'] . '" target="_blank" class="' . $custom_class . '">
' . $row['name'] . '
</a>
<span class="edit-product-title" product_id="' . $row['product_id'] . '">
<i class="fa fa-pencil"></i>
</span>
</div>',
$row['impressions'],
$row['impressions_30'],
'<span style="color: ' . ( $row['clicks'] > 200 ? ( $row['clicks'] > 400 ? '#0047ccff' : '#57b951' ) : '' ) . '">' . $row['clicks'] . '</span>',
$row['clicks_30'],
round( $row['ctr'], 2 ) . '%',
\S::number_display( $row['cost'] ),
\S::number_display( $row['cpc'] ),
round( $row['conversions'], 2 ),
\S::number_display( $row['conversions_value'] ),
$roasCellHtml,
'<input type="text" class="form-control min_roas" product_id="' . $row['product_id'] . '" value="' . $row['min_roas'] . '" style="width: 100px;">',
'',
'<input type="text" class="form-control custom_label_4" product_id="' . $row['product_id'] . '" value="' . $custom_label_4 . '" style="' . $custom_label_4_color . '">'
];
}
echo json_encode( $data );
exit;
}
static public function save_min_roas()
{
$product_id = \S::get( 'product_id' );
$min_roas = \S::get( 'min_roas' );
if ( \factory\Products::save_min_roas( $product_id, $min_roas ) )
{
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function save_custom_label_4()
{
$product_id = \S::get( 'product_id' );
$custom_label_4 = \S::get( 'custom_label_4' );
if ( \factory\Products::set_product_data( $product_id, 'custom_label_4', $custom_label_4 ) )
{
\factory\Products::add_product_comment( $product_id, 'Zmiana etykiety 4 na: ' . $custom_label_4 );
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
static public function product_history()
{
$client_id = \S::get( 'client_id' );
$product_id = \S::get( 'product_id' );
return \Tpl::view( 'products/product_history', [
'client_id' => $client_id,
'product_id' => $product_id,
'min_roas' => \factory\Products::get_min_roas( $product_id )
] );
}
static public function get_product_history_table()
{
$client_id= \S::get( 'client_id' );
$product_id = \S::get( 'product_id' );
$start = \S::get( 'start' ) ? \S::get( 'start' ) : 0;
$limit = \S::get( 'length' ) ? \S::get( 'length' ) : 10;
$db_results = \factory\Products::get_product_history( $client_id, $product_id, $start, $limit );
$recordsTotal = \factory\Products::get_records_total_product_history( $client_id, $product_id );
$data['draw'] = \S::get( 'draw' );
$data['recordsTotal'] = $recordsTotal;
$data['recordsFiltered'] = $recordsTotal;
foreach ( $db_results as $row )
{
$roas_value = ( $row['cost'] > 0) ? ( $row['conversions_value'] / $row['cost'] ) * 100 : 0;
$roas = number_format( $roas_value, 0, '.', '' ) . '%';
$data['data'][] = [
$row['id'],
$row['impressions'],
$row['clicks'],
round( $row['ctr'], 2 ) . '%',
\S::number_display( $row['cost'] ),
$row['conversions'],
\S::number_display( $row['conversions_value'] ),
$roas,
$row['date_add'],
];
}
echo json_encode( $data );
exit;
}
static public function get_product_history_table_chart()
{
$client_id = \S::get( 'client_id' );
$product_id = \S::get( 'product_id' );
$limit = \S::get( 'length' ) ? \S::get( 'length' ) : 360;
$start = \S::get( 'start' ) ? \S::get( 'start' ) : 0;
$db_results = \factory\Products::get_product_history_30( $client_id, $product_id, $start, $limit );
$impressions = [];
$clicks = [];
$cost = [];
$conversions = [];
$conversions_value = [];
$roas = [];
$dates = [];
foreach ( $db_results as $row )
{
$impressions[] = (int)$row['impressions'];
$clicks[] = (int)$row['clicks'];
$ctr[] = (float)$row['ctr'];
$cost[] = (float)$row['cost'];
$conversions[] = (int)$row['conversions'];
$conversions_value[] = (float)$row['conversions_value'];
$roas[] = (float)$row['roas_all_time'];
$dates[] = $row['date_add'];
}
$chart_data = [
[
'name' => 'Wyświetlenia',
'data' => $impressions,
'visible' => false
], [
'name' => 'Kliknięcia',
'data' => $clicks,
'visible' => false
], [
'name' => 'CTR',
'data' => $ctr,
'visible' => false
], [
'name' => 'Koszt',
'data' => $cost,
'visible' => false
], [
'name' => 'Konwersje',
'data' => $conversions,
'visible' => false
], [
'name' => 'Wartość konwersji',
'data' => $conversions_value,
'visible' => false
], [
'name' => 'ROAS',
'data' => $roas
]
];
echo json_encode([
'chart_data' => $chart_data,
'dates' => $dates,
'comments' => \factory\Products::get_product_comments( $product_id ),
]);
exit;
}
static public function save_custom_title()
{
$product_id = \S::get( 'product_id' );
$custom_title = \S::get( 'custom_title' );
if ( \factory\Products::set_product_data( $product_id, 'title', $custom_title ) )
{
\factory\Products::add_product_comment( $product_id, 'Zmiana nazwy produktu na: ' . $custom_title );
echo json_encode( [ 'status' => 'ok' ] );
}
else
echo json_encode( [ 'status' => 'error' ] );
exit;
}
}