\factory\Campaigns::get_clients(), ] ); } static public function get_campaigns_list() { $client_id = (int) \S::get( 'client_id' ); echo json_encode( [ 'campaigns' => \factory\Campaigns::get_campaigns_list( $client_id ) ] ); exit; } static public function get_campaign_ad_groups() { $campaign_id = (int) \S::get( 'campaign_id' ); if ( $campaign_id <= 0 ) { echo json_encode( [ 'ad_groups' => [] ] ); exit; } echo json_encode( [ 'ad_groups' => \factory\Campaigns::get_campaign_ad_groups( $campaign_id ) ] ); exit; } static public function get_campaign_phrase_details() { $campaign_id = (int) \S::get( 'campaign_id' ); $ad_group_id = (int) \S::get( 'ad_group_id' ); if ( $campaign_id <= 0 ) { echo json_encode( [ 'search_terms' => [], 'negative_keywords' => [] ] ); exit; } echo json_encode( [ 'search_terms' => \factory\Campaigns::get_campaign_search_terms( $campaign_id, $ad_group_id ), 'negative_keywords' => \factory\Campaigns::get_campaign_negative_keywords( $campaign_id, $ad_group_id ) ] ); exit; } static public function add_negative_keyword() { $search_term_id = (int) \S::get( 'search_term_id' ); $match_type = strtoupper( trim( (string) \S::get( 'match_type' ) ) ); $scope = strtolower( trim( (string) \S::get( 'scope' ) ) ); if ( $search_term_id <= 0 ) { echo json_encode( [ 'success' => false, 'message' => 'Nie podano frazy do wykluczenia.' ] ); exit; } if ( !in_array( $match_type, [ 'PHRASE', 'EXACT', 'BROAD' ], true ) ) { $match_type = 'PHRASE'; } if ( !in_array( $scope, [ 'campaign', 'ad_group' ], true ) ) { $scope = 'campaign'; } $context = \factory\Campaigns::get_search_term_context( $search_term_id ); if ( !$context ) { echo json_encode( [ 'success' => false, 'message' => 'Nie znaleziono danych frazy.' ] ); exit; } $customer_id = trim( (string) ( $context['google_ads_customer_id'] ?? '' ) ); $campaign_external_id = trim( (string) ( $context['external_campaign_id'] ?? '' ) ); $ad_group_external_id = trim( (string) ( $context['external_ad_group_id'] ?? '' ) ); $keyword_text = trim( (string) ( $context['search_term'] ?? '' ) ); $missing_data = ( $customer_id === '' || $keyword_text === '' ); if ( $scope === 'campaign' && $campaign_external_id === '' ) { $missing_data = true; } if ( $scope === 'ad_group' && $ad_group_external_id === '' ) { $missing_data = true; } if ( $missing_data ) { echo json_encode( [ 'success' => false, 'message' => 'Brak wymaganych danych Google Ads dla tej frazy.', 'debug' => [ 'customer_id' => $customer_id, 'campaign_external_id' => $campaign_external_id, 'ad_group_external_id' => $ad_group_external_id, 'keyword_text' => $keyword_text, 'scope' => $scope, 'context' => $context ] ] ); exit; } $api = new \services\GoogleAdsApi(); if ( !$api -> is_configured() ) { echo json_encode( [ 'success' => false, 'message' => 'Google Ads API nie jest skonfigurowane.' ] ); exit; } if ( $scope === 'campaign' ) { $api_result = $api -> add_negative_keyword_to_campaign( $customer_id, $campaign_external_id, $keyword_text, $match_type ); } else { $api_result = $api -> add_negative_keyword_to_ad_group( $customer_id, $ad_group_external_id, $keyword_text, $match_type ); } if ( !( $api_result['success'] ?? false ) ) { $last_error = \services\GoogleAdsApi::get_setting( 'google_ads_last_error' ); echo json_encode( [ 'success' => false, 'message' => 'Nie udalo sie zapisac frazy wykluczajacej w Google Ads.', 'error' => $last_error, 'debug' => [ 'customer_id' => $customer_id, 'campaign_external_id' => $campaign_external_id, 'ad_group_external_id' => $ad_group_external_id, 'keyword_text' => $keyword_text, 'match_type' => $match_type, 'scope' => $scope, 'api_result' => $api_result ] ] ); exit; } \factory\Campaigns::upsert_campaign_negative_keyword( (int) $context['db_campaign_id'], $scope === 'campaign' ? null : (int) $context['db_ad_group_id'], $scope, $keyword_text, $match_type ); $scope_label = $scope === 'campaign' ? 'kampanii' : 'grupy reklam'; echo json_encode( [ 'success' => true, 'message' => ( $api_result['duplicate'] ?? false ) ? 'Fraza byla juz wykluczona na poziomie ' . $scope_label . '.' : 'Fraza zostala dodana do wykluczajacych na poziomie ' . $scope_label . '.', 'duplicate' => (bool) ( $api_result['duplicate'] ?? false ), 'match_type' => $match_type, 'scope' => $scope, 'debug' => [ 'customer_id' => $customer_id, 'campaign_external_id' => $campaign_external_id, 'ad_group_external_id' => $ad_group_external_id, 'keyword_text' => $keyword_text, 'scope' => $scope, 'api_response' => $api_result['response'] ?? null, 'sent_operation' => $api_result['sent_operation'] ?? null, 'verification' => $api_result['verification'] ?? null ] ] ); exit; } }