query( 'SELECT * FROM products AS p INNER JOIN products_history AS ph ON p.id = ph.product_id WHERE p.client_id = ' . $client_id ) -> fetchAll( \PDO::FETCH_ASSOC ); $aggregated_data = []; foreach ( $db_result as $row ) { $product_id = $row['product_id']; if ( !isset( $aggregated_data[$client_id] ) ) { $aggregated_data[$client_id] = []; } if (!isset($aggregated_data[$client_id][$product_id])) { $aggregated_data[$client_id][$product_id] = [ 'product_id' => $product_id, 'name' => $row['name'], 'impressions' => 0, 'clicks' => 0, 'cost' => 0.0, 'conversions' => 0, 'conversions_value' => 0.0 ]; } $aggregated_data[$client_id][$product_id]['impressions'] += $row['impressions']; $aggregated_data[$client_id][$product_id]['clicks'] += $row['clicks']; $aggregated_data[$client_id][$product_id]['cost'] += $row['cost']; $aggregated_data[$client_id][$product_id]['conversions'] += $row['conversions']; $aggregated_data[$client_id][$product_id]['conversions_value'] += $row['conversions_value']; } $products_ids = $mdb -> select( 'products', 'id', [ 'client_id' => $client_id ] ); foreach ( $products_ids as $product_id ) { $products_ids_array[] = $product_id; } $mdb -> delete( 'products_temp', [ 'product_id' => $products_ids_array ] ); foreach ( $aggregated_data as $client_offers ) { foreach ( $client_offers as $offer_data ) { // Obliczamy wartości CPC oraz conversions_price $cpc = $offer_data['clicks'] > 0 ? round( $offer_data['cost'] / $offer_data['clicks'], 6 ) : 0; $roas = ($offer_data['conversions'] > 0 and $offer_data['cost']) ? round($offer_data['conversions_value'] / $offer_data['cost'], 2) * 100 : 0; $impressions_30 = \factory\Products::get_impressions_30( $offer_data['product_id'] ); if ( $impressions_30 <= 30 ) $custom_label_3 = 'product_zombie'; else $custom_label_3 = null; $offers_data_tmp = $mdb -> get( 'products_data', '*', [ 'product_id' => $offer_data['product_id'] ] ); if ( isset( $offers_data_tmp['id'] ) ) { if ( $custom_label_3 != $offers_data_tmp['custom_label_3'] ) $mdb -> insert( 'products_comments', [ 'product_id' => $offer_data['product_id'], 'comment' => 'Zmiana pola "custom_label_3" na: ' . $custom_label_3, 'type' => 1, 'date_add' => date( 'Y-m-d' ) ] ); $mdb -> update( 'products_data', [ 'custom_label_3' => $custom_label_3 ], [ 'id' => $offers_data_tmp['id'] ] ); } else { $mdb -> insert( 'products_data', [ 'product_id' => $offer_data['product_id'], 'custom_label_3' => $custom_label_3 ] ); if ( $custom_label_3 == 'product_zombie' ) { $mdb -> insert( 'products_comments', [ 'product_id' => $offer_data['product_id'], 'comment' => 'Zmiana pola "custom_label_3" na: product_zombie', 'type' => 1, 'date_add' => date( 'Y-m-d' ) ] ); } } // Zapisujemy każdy zsumowany wpis do offers_temp $clicks_30 = \factory\Products::get_clicks_30( $offer_data['product_id'] ); $mdb -> insert( 'products_temp', [ 'product_id' => $offer_data['product_id'], 'name' => $offer_data['name'], 'impressions' => $offer_data['impressions'], 'impressions_30' => $impressions_30, 'clicks' => $offer_data['clicks'], 'clicks_30' => $clicks_30, 'ctr' => round( $offer_data['clicks'] / $offer_data['impressions'], 4 ) * 100, 'cost' => $offer_data['cost'], 'conversions' => $offer_data['conversions'], 'conversions_value' => $offer_data['conversions_value'], 'cpc' => $cpc, 'roas' => $roas, ]); } } echo json_encode( [ 'result' => "Agregacja zakończona, dane zapisane do offers_temp." ] ); exit; } static public function cron_products_history_30() { global $mdb; $start_time = microtime(true); $client_id = \S::get( 'client_id' ); if ( !$client_id ) { echo json_encode( [ 'result' => "Nie podano ID klienta." ] ); exit; } $products = $mdb -> select( 'products', 'id', [ 'client_id' => $client_id ] ); foreach ( $products as $product ) { for ( $i = 0; $i < 30; $i++ ) { $date_to = date( 'Y-m-d', strtotime( '-' . (1 + $i) . ' days' ) ); $date_from = date( 'Y-m-d', strtotime( '-' . (31 + $i) . ' days' ) ); $data_updated = false; if ( $mdb -> count( 'products_history', [ 'AND' => [ 'product_id' => $product, 'date_add[>=]' => $date_from, 'date_add[<=]' => $date_to, 'updated' => 1 ] ] ) > 0 ) { $data_updated = true; } if ( $data_updated ) { self::cron_product_history_30_save( $product, $date_from, $date_to ); } } // $mdb -> update( 'products_history', [ 'updated' => 0 ], [ 'AND' => [ 'product_id' => $product, 'updated' => 1 ] ] ); } $end_time = microtime(true); $execution_time = $end_time - $start_time; echo json_encode( [ 'result' => "Agregacja zakończona, dane zapisane do offers_history_30. Czas wykonania skryptu: " . round($execution_time, 4) . " sekund." ] ); exit; } static public function cron_product_history_30_save( $product_id, $date_from, $date_to ) { global $mdb; $data = $mdb -> query( 'SELECT * FROM products_history WHERE product_id = ' . $product_id . ' AND date_add >= \'' . $date_from . '\' AND date_add <= \'' . $date_to . '\' ORDER BY date_add ASC' ) -> fetchAll( \PDO::FETCH_ASSOC ); // Inicjalizacja tablic do przechowywania danych $offers_data = []; // Grupowanie danych według produktów foreach ( $data as $entry ) { if ( !isset( $offers_data[$product_id] ) ) { $offers_data[$product_id] = [ 'impressions' => 0, 'clicks' => 0, 'cost' => 0.0, 'conversions' => 0, 'conversions_value' => 0.0, 'roas' => 0, 'days_counted' => [] ]; } // Sumowanie danych według produktu $offers_data[$product_id]['impressions'] += $entry['impressions']; $offers_data[$product_id]['clicks'] += $entry['clicks']; $offers_data[$product_id]['cost'] += $entry['cost']; $offers_data[$product_id]['conversions'] += $entry['conversions']; $offers_data[$product_id]['conversions_value'] += $entry['conversions_value']; $offers_data[$product_id]['days_counted'][] = $entry['date_add']; } foreach ( $offers_data as $offer ) { $day_count = count( $offer['days_counted'] ); $impressions = $offer['impressions'] / $day_count; $clicks = $offer['clicks'] / $day_count; $ctr = ( $clicks > 0 and $impressions ) ? round( $clicks / $impressions, 4 ) * 100 : 0; $cost = $offer['cost'] / $day_count; $conversions = $offer['conversions'] / $day_count; $conversions_value = $offer['conversions_value'] / $day_count; $roas = ( $conversions_value > 0 and $cost ) ? round( $conversions_value / $cost, 2 ) * 100 : 0; if ( $day_count > 14 ) { if ( $mdb -> count( 'products_history_30', [ 'AND' => [ 'product_id' => $product_id, 'date_add' => $date_to ] ] ) > 0 ) { $mdb -> update( 'products_history_30', [ 'impressions' => $impressions, 'clicks' => $clicks, 'ctr' => $ctr, 'cost' => $cost, 'conversions' => $conversions, 'conversions_value' => $conversions_value, 'roas' => $roas ], [ 'AND' => [ 'product_id' => $product_id, 'date_add' => $date_to ] ] ); } else { $mdb -> insert( 'products_history_30', [ 'product_id' => $product_id, 'impressions' => $impressions, 'clicks' => $clicks, 'ctr' => $ctr, 'cost' => $cost, 'conversions' => $conversions, 'conversions_value' => $conversions_value, 'roas' => $roas, 'date_add' => $date_to ] ); } } } } static public function cron_xml() { global $mdb; if ( !$client_id = \S::get( 'client_id' ) ) { echo json_encode( [ 'result' => "Nie podano ID klienta." ] ); exit; } $results = $mdb -> query( 'SELECT * FROM products AS p INNER JOIN products_data AS pd ON p.id = pd.product_id WHERE p.client_id = ' . $client_id ) -> fetchAll( \PDO::FETCH_ASSOC ); $doc = new \DOMDocument('1.0', 'UTF-8'); $xmlRoot = $doc->createElement('rss'); $xmlRoot = $doc->appendChild($xmlRoot); $xmlRoot->setAttribute('version', '2.0'); $xmlRoot->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:g', 'http://base.google.com/ns/1.0'); $channelNode = $xmlRoot->appendChild($doc->createElement('channel')); $channelNode->appendChild($doc->createElement('title', 'Custom Feed')); $channelNode->appendChild($doc->createElement('link', 'https://ads.pagedev.pl')); $fieldMappings = [ 'title' => 'g:title', 'custom_label_4' => 'g:custom_label_4', 'custom_label_3' => 'g:custom_label_3', ]; foreach ($results as $row) { $hasValidField = false; foreach ($fieldMappings as $dbField => $xmlTag) { if (!empty($row[$dbField])) { $hasValidField = true; break; } } if ( $hasValidField ) { $itemNode = $channelNode->appendChild($doc->createElement('item')); $offer_id = $mdb -> get( 'products', 'offer_id', [ 'id' => $row['product_id'] ] ); $p_gid = $itemNode->appendChild($doc->createElement('g:id', $offer_id)); foreach ($fieldMappings as $dbField => $xmlTag) { if (!empty($row[$dbField])) { $itemNode->appendChild($doc->createElement($xmlTag, $row[$dbField])); } } } } file_put_contents('xml/custom-feed-' . $_GET['client_id'] . '.xml', $doc->saveXML()); echo json_encode( [ 'result' => "Plik XML został wygenerowany https://adspro.projectpro.pl/xml/custom-feed-" . $_GET['client_id'] . ".xml." ] ); exit; } static public function cron_phrases() { global $mdb; if ( !$client_id = \S::get( 'client_id' ) ) { echo json_encode( [ 'result' => "Nie podano ID klienta." ] ); exit; } $data = $mdb -> query( 'SELECT * FROM phrases AS p INNER JOIN phrases_history AS ph ON p.id = ph.phrase_id WHERE p.client_id = ' . $client_id ) -> fetchAll( \PDO::FETCH_ASSOC ); $aggregated_data = []; foreach ( $data as $row ) { $phrase_id = $row['phrase_id']; if ( !isset( $aggregated_data[$client_id] ) ) { $aggregated_data[$client_id] = []; } if ( !isset( $aggregated_data[$client_id][$phrase_id] ) ) { $aggregated_data[$client_id][$phrase_id] = [ 'phrase_id' => $phrase_id, 'phrase' => $row['phrase'], 'impressions' => 0, 'clicks' => 0, 'cost' => 0.0, 'conversions' => 0, 'conversions_value' => 0.0 ]; } $aggregated_data[$client_id][$phrase_id]['impressions'] += $row['impressions']; $aggregated_data[$client_id][$phrase_id]['clicks'] += $row['clicks']; $aggregated_data[$client_id][$phrase_id]['cost'] += $row['cost']; $aggregated_data[$client_id][$phrase_id]['conversions'] += $row['conversions']; $aggregated_data[$client_id][$phrase_id]['conversions_value'] += $row['conversions_value']; } $phrases_ids = $mdb -> select( 'phrases', 'id', [ 'client_id' => $client_id ] ); foreach ( $phrases_ids as $phrase_id ) { $phrases_ids_array[] = $phrase_id -> id; } $mdb -> delete( 'phrases_temp', [ 'phrase_id' => $phrases_ids_array ] ); foreach ( $aggregated_data as $client_phrases ) { foreach ( $client_phrases as $phrase_data ) { $cpc = $phrase_data['clicks'] > 0 ? round( $phrase_data['cost'] / $phrase_data['clicks'], 6 ) : 0; $roas = ( $phrase_data['conversions'] > 0 and $phrase_data['cost'] ) ? round( $phrase_data['conversions_value'] / $phrase_data['cost'], 2 ) * 100 : 0; $mdb -> insert( 'phrases_temp', [ 'phrase_id' => $phrase_data['phrase_id'], 'phrase' => $phrase_data['phrase'], 'impressions' => $phrase_data['impressions'], 'clicks' => $phrase_data['clicks'], 'cost' => $phrase_data['cost'], 'conversions' => $phrase_data['conversions'], 'conversions_value' => $phrase_data['conversions_value'], 'cpc' => $cpc, 'roas' => $roas, ] ); } } echo json_encode( [ 'result' => "Agregacja zakończona, dane zapisane do phrases_temp." ] ); exit; } static public function cron_phrases_history_30() { global $mdb; $start_time = microtime( true ); // Rozpoczęcie mierzenia czasu $client_id = \S::get( 'client_id' ); // Pobranie ID klienta if ( !$client_id ) // Jeśli nie podano ID klienta { echo json_encode( [ 'result' => "Nie podano ID klienta." ] ); // Wyświetlenie komunikatu exit; // Zakończenie działania skryptu } // Pobranie bieżącej daty i daty sprzed 30 dni $phrases = $mdb -> query( 'SELECT * FROM phrases WHERE client_id = ' . $client_id ) -> fetchAll( \PDO::FETCH_ASSOC ); // Pobranie fraz dla danego klienta foreach ( $phrases as $phrase ) { for ( $i = 0; $i < 30; $i++ ) { $date_to = date( 'Y-m-d', strtotime( '-' . ( 1 + $i ) . ' days' ) ); $date_from = date( 'Y-m-d', strtotime( '-' . ( 31 + $i ) . ' days' ) ); $data_updated = false; if ( $mdb -> count( 'phrases_history', [ 'AND' => [ 'phrase_id' => $phrase['id'], 'date_add[>=]' => $date_from, 'date_add[<=]' => $date_to, 'updated' => 1 ] ] ) > 0 ) { $data_updated = true; } if ( $data_updated ) { self::cron_phrase_history_30_save( $phrase['id'], $date_from, $date_to ); } } $mdb -> update( 'phrases_history', [ 'updated' => 0 ], [ 'AND' => [ 'phrase_id' => $phrase['id'], 'updated' => 1 ] ] ); } $end_time = microtime( true ); // Zakończenie mierzenia czasu $execution_time = $end_time - $start_time; // Obliczenie czasu wykonania echo json_encode( [ 'result' => "Agregacja zakończona, dane zapisane do phrases_history_30. Czas wykonania skryptu: " . round( $execution_time, 4 ) . " sekund." ] ); // Wyświetlenie komunikatu exit; } static public function cron_phrase_history_30_save( $phrase_id, $date_from, $date_to ) { global $mdb; $data = $mdb -> query( 'SELECT * FROM phrases_history WHERE phrase_id = ' . $phrase_id . ' AND date_add >= \'' . $date_from . '\' AND date_add <= \'' . $date_to . '\' ORDER BY date_add ASC' ) -> fetchAll( \PDO::FETCH_ASSOC ); // Inicjalizacja tablic do przechowywania danych $phrases_data = []; // Grupowanie danych według fraz foreach ( $data as $entry ) { $phrase_id = $entry['phrase_id']; if ( !isset( $phrases_data[$phrase_id] ) ) { $phrases_data[$phrase_id] = [ 'impressions' => 0, 'clicks' => 0, 'cost' => 0.0, 'conversions' => 0, 'conversions_value' => 0.0, 'roas' => 0, 'days_counted' => [] ]; } // Sumowanie danych według fraz $phrases_data[$phrase_id]['impressions'] += $entry['impressions']; $phrases_data[$phrase_id]['clicks'] += $entry['clicks']; $phrases_data[$phrase_id]['cost'] += $entry['cost']; $phrases_data[$phrase_id]['conversions'] += $entry['conversions']; $phrases_data[$phrase_id]['conversions_value'] += $entry['conversions_value']; $phrases_data[$phrase_id]['days_counted'][] = $entry['date_add']; } foreach ( $phrases_data as $phrase ) { $day_count = count( $phrase['days_counted'] ); $impressions = $phrase['impressions'] / $day_count; $clicks = $phrase['clicks'] / $day_count; $cost = $phrase['cost'] / $day_count; $conversions = $phrase['conversions'] / $day_count; $conversions_value = $phrase['conversions_value'] / $day_count; $roas = ( $conversions_value > 0 and $cost ) ? round( $conversions_value / $cost, 2 ) * 100 : 0; if ( $day_count > 14 ) { if ( $mdb -> count( 'phrases_history_30', [ 'AND' => [ 'phrase_id' => $phrase_id, 'date_add' => $date_to ] ] ) > 0 ) { $mdb -> update( 'phrases_history_30', [ 'impressions' => $impressions, 'clicks' => $clicks, 'cost' => $cost, 'conversions' => $conversions, 'conversions_value' => $conversions_value, 'roas' => $roas ], [ 'AND' => [ 'phrase_id' => $phrase_id, 'date_add' => $date_to ] ] ); } else { $mdb -> insert( 'phrases_history_30', [ 'phrase_id' => $phrase_id, 'impressions' => $impressions, 'clicks' => $clicks, 'cost' => $cost, 'conversions' => $conversions, 'conversions_value' => $conversions_value, 'roas' => $roas, 'date_add' => $date_to ] ); } } } } }