- 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.
258 lines
7.6 KiB
PHP
258 lines
7.6 KiB
PHP
<?php
|
|
namespace factory;
|
|
class Campaigns
|
|
{
|
|
static public function get_clients()
|
|
{
|
|
global $mdb;
|
|
return $mdb -> select( 'clients', '*', [ 'ORDER' => [ 'name' => 'ASC' ] ] );
|
|
}
|
|
|
|
static public function get_campaigns_list( $client_id, $only_active = false )
|
|
{
|
|
global $mdb;
|
|
|
|
$client_id = (int) $client_id;
|
|
|
|
if ( !$only_active )
|
|
{
|
|
return $mdb -> select( 'campaigns', '*', [ 'client_id' => $client_id, 'ORDER' => [ 'campaign_name' => 'ASC' ] ] );
|
|
}
|
|
|
|
$latest_date = $mdb -> query(
|
|
'SELECT MAX( ch.date_add )
|
|
FROM campaigns_history AS ch
|
|
INNER JOIN campaigns AS c ON c.id = ch.campaign_id
|
|
WHERE c.client_id = :client_id
|
|
AND c.campaign_id <> 0',
|
|
[ ':client_id' => $client_id ]
|
|
) -> fetchColumn();
|
|
|
|
if ( !$latest_date )
|
|
{
|
|
return $mdb -> select( 'campaigns', '*', [ 'client_id' => $client_id, 'ORDER' => [ 'campaign_name' => 'ASC' ] ] );
|
|
}
|
|
|
|
return $mdb -> query(
|
|
'SELECT c.*
|
|
FROM campaigns AS c
|
|
LEFT JOIN campaigns_history AS ch
|
|
ON ch.campaign_id = c.id
|
|
AND ch.date_add = :latest_date
|
|
WHERE c.client_id = :client_id
|
|
AND ( c.campaign_id = 0 OR ch.id IS NOT NULL )
|
|
ORDER BY c.campaign_name ASC',
|
|
[
|
|
':client_id' => $client_id,
|
|
':latest_date' => $latest_date
|
|
]
|
|
) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
}
|
|
|
|
static public function get_campaign_history_data( $campaign_id, $start, $length, $revert = false )
|
|
{
|
|
global $mdb;
|
|
if ( $revert )
|
|
return $mdb -> select( 'campaigns_history', '*', [ 'campaign_id' => $campaign_id, 'LIMIT' => [ $start, $length ], 'ORDER' => [ 'date_add' => 'ASC' ] ] );
|
|
else
|
|
return $mdb -> select( 'campaigns_history', '*', [ 'campaign_id' => $campaign_id, 'LIMIT' => [ $start, $length ], 'ORDER' => [ 'date_add' => 'DESC' ] ] );
|
|
}
|
|
|
|
static public function get_records_total_campaign_history_data( $campaign_id )
|
|
{
|
|
global $mdb;
|
|
return $mdb -> count( 'campaigns_history', [ 'campaign_id' => $campaign_id ] );
|
|
}
|
|
|
|
static public function get_client_name( $client_id )
|
|
{
|
|
global $mdb;
|
|
return $mdb -> get( 'clients', 'name', [ 'id' => $client_id ] );
|
|
}
|
|
|
|
static public function get_campaign_ad_groups( $campaign_id )
|
|
{
|
|
global $mdb;
|
|
|
|
return $mdb -> query(
|
|
'SELECT
|
|
id,
|
|
campaign_id,
|
|
ad_group_id,
|
|
ad_group_name,
|
|
impressions_30,
|
|
clicks_30,
|
|
cost_30,
|
|
conversions_30,
|
|
conversion_value_30,
|
|
roas_30,
|
|
impressions_all_time,
|
|
clicks_all_time,
|
|
cost_all_time,
|
|
conversions_all_time,
|
|
conversion_value_all_time,
|
|
roas_all_time
|
|
FROM campaign_ad_groups
|
|
WHERE campaign_id = :campaign_id
|
|
ORDER BY clicks_30 DESC, clicks_all_time DESC, ad_group_name ASC',
|
|
[ ':campaign_id' => (int) $campaign_id ]
|
|
) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
}
|
|
|
|
static public function get_campaign_search_terms( $campaign_id, $ad_group_id = 0 )
|
|
{
|
|
global $mdb;
|
|
|
|
$sql = 'SELECT
|
|
st.id,
|
|
st.campaign_id,
|
|
st.ad_group_id,
|
|
ag.ad_group_name,
|
|
st.search_term,
|
|
st.impressions_30,
|
|
st.clicks_30,
|
|
st.cost_30,
|
|
st.conversions_30,
|
|
st.conversion_value_30,
|
|
st.roas_30,
|
|
st.impressions_all_time,
|
|
st.clicks_all_time,
|
|
st.cost_all_time,
|
|
st.conversions_all_time,
|
|
st.conversion_value_all_time,
|
|
st.roas_all_time
|
|
FROM campaign_search_terms AS st
|
|
LEFT JOIN campaign_ad_groups AS ag ON ag.id = st.ad_group_id
|
|
WHERE st.campaign_id = :campaign_id';
|
|
|
|
$params = [ ':campaign_id' => (int) $campaign_id ];
|
|
|
|
if ( (int) $ad_group_id > 0 )
|
|
{
|
|
$sql .= ' AND st.ad_group_id = :ad_group_id';
|
|
$params[':ad_group_id'] = (int) $ad_group_id;
|
|
}
|
|
|
|
$sql .= ' ORDER BY st.clicks_30 DESC, st.clicks_all_time DESC, st.search_term ASC';
|
|
|
|
return $mdb -> query( $sql, $params ) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
}
|
|
|
|
static public function get_campaign_negative_keywords( $campaign_id, $ad_group_id = 0 )
|
|
{
|
|
global $mdb;
|
|
|
|
$sql = 'SELECT
|
|
nk.id,
|
|
nk.campaign_id,
|
|
nk.ad_group_id,
|
|
ag.ad_group_name,
|
|
nk.scope,
|
|
nk.keyword_text,
|
|
nk.match_type
|
|
FROM campaign_negative_keywords AS nk
|
|
LEFT JOIN campaign_ad_groups AS ag ON ag.id = nk.ad_group_id
|
|
WHERE nk.campaign_id = :campaign_id';
|
|
|
|
$params = [ ':campaign_id' => (int) $campaign_id ];
|
|
|
|
if ( (int) $ad_group_id > 0 )
|
|
{
|
|
$sql .= ' AND ( nk.scope = \'campaign\' OR nk.ad_group_id = :ad_group_id )';
|
|
$params[':ad_group_id'] = (int) $ad_group_id;
|
|
}
|
|
|
|
$sql .= ' ORDER BY nk.scope ASC, nk.keyword_text ASC';
|
|
|
|
return $mdb -> query( $sql, $params ) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
}
|
|
|
|
static public function get_search_term_context( $search_term_row_id )
|
|
{
|
|
global $mdb;
|
|
|
|
return $mdb -> query(
|
|
'SELECT
|
|
st.id AS search_term_row_id,
|
|
st.search_term,
|
|
st.campaign_id AS db_campaign_id,
|
|
st.ad_group_id AS db_ad_group_id,
|
|
c.client_id,
|
|
c.campaign_id AS external_campaign_id,
|
|
c.advertising_channel_type,
|
|
ag.ad_group_id AS external_ad_group_id,
|
|
cl.google_ads_customer_id
|
|
FROM campaign_search_terms AS st
|
|
INNER JOIN campaigns AS c ON c.id = st.campaign_id
|
|
INNER JOIN clients AS cl ON cl.id = c.client_id
|
|
LEFT JOIN campaign_ad_groups AS ag ON ag.id = st.ad_group_id
|
|
WHERE st.id = :search_term_row_id
|
|
LIMIT 1',
|
|
[ ':search_term_row_id' => (int) $search_term_row_id ]
|
|
) -> fetch( \PDO::FETCH_ASSOC );
|
|
}
|
|
|
|
static public function upsert_campaign_negative_keyword( $campaign_id, $ad_group_id, $scope, $keyword_text, $match_type )
|
|
{
|
|
global $mdb;
|
|
|
|
$campaign_id = (int) $campaign_id;
|
|
$ad_group_id = $ad_group_id !== null ? (int) $ad_group_id : null;
|
|
$scope = $scope === 'campaign' ? 'campaign' : 'ad_group';
|
|
$keyword_text = trim( (string) $keyword_text );
|
|
$match_type = strtoupper( trim( (string) $match_type ) );
|
|
|
|
if ( $campaign_id <= 0 || $keyword_text === '' )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
$existing = $mdb -> query(
|
|
'SELECT id
|
|
FROM campaign_negative_keywords
|
|
WHERE campaign_id = :campaign_id
|
|
AND ( ( :ad_group_id IS NULL AND ad_group_id IS NULL ) OR ad_group_id = :ad_group_id )
|
|
AND scope = :scope
|
|
AND LOWER(keyword_text) = LOWER(:keyword_text)
|
|
AND UPPER(COALESCE(match_type, \'\')) = :match_type
|
|
LIMIT 1',
|
|
[
|
|
':campaign_id' => $campaign_id,
|
|
':ad_group_id' => $ad_group_id,
|
|
':scope' => $scope,
|
|
':keyword_text' => $keyword_text,
|
|
':match_type' => $match_type
|
|
]
|
|
) -> fetchColumn();
|
|
|
|
if ( $existing )
|
|
{
|
|
return (int) $existing;
|
|
}
|
|
|
|
$mdb -> insert( 'campaign_negative_keywords', [
|
|
'campaign_id' => $campaign_id,
|
|
'ad_group_id' => $ad_group_id,
|
|
'scope' => $scope,
|
|
'keyword_text' => $keyword_text,
|
|
'match_type' => $match_type,
|
|
'date_sync' => date( 'Y-m-d' )
|
|
] );
|
|
|
|
return (int) $mdb -> id();
|
|
}
|
|
|
|
static public function delete_campaign( $campaign_id )
|
|
{
|
|
global $mdb;
|
|
$mdb -> delete( 'campaigns_history', [ 'campaign_id' => $campaign_id ] );
|
|
return $mdb -> delete( 'campaigns', [ 'id' => $campaign_id ] );
|
|
}
|
|
|
|
static public function delete_history_entry( $history_id )
|
|
{
|
|
global $mdb;
|
|
return $mdb -> delete( 'campaigns_history', [ 'id' => $history_id ] );
|
|
}
|
|
}
|