initialize( $channel )->write_log( $message, $level ); } /** * Dump the content in the screen. * * @param mixed $var Content. * @param bool $exit Exit. * * @return void */ public static function dump( $var, bool $exit = false ) { echo '
';
if ( is_array( $var ) || is_object( $var ) ) {
echo esc_html( print_r( $var, true ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.debugging_print_r
} elseif ( is_string( $var ) ) {
echo esc_html( 'string(' . strlen( $var ) . ') "' . $var . "\";\n" );
} else {
ob_start();
var_dump( $var ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.debugging_var_dump
echo esc_html( ob_get_clean() );
}
echo "\n";
if ( $exit ) {
exit; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
/**
* Menu Page URL.
*
* @param string $page_slug Page Slug.
* @param array $parameters Parameter.
*
* @return string
*/
public static function menu_page_url( string $page_slug, array $parameters = array() ): string {
if ( is_array( $parameters ) && count( $parameters ) ) {
return admin_url( '/admin.php?page=' . $page_slug ) . '&' . http_build_query( $parameters );
}
return admin_url( '/admin.php?page=' . $page_slug );
}
/**
* Encrypt a String.
*
* @param string $string String.
*
* @return string
*/
public static function encrypt( string $string ): string {
$secret_key = wp_create_nonce();
$secret_iv = self::generate_secret();
$encrypt_method = 'AES-128-CBC';
$key = hash( 'sha256', $secret_key );
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
return base64_encode( openssl_encrypt( $string, $encrypt_method, $key, 0, $iv ) );
}
/**
* Generate Secret.
*
* @return mixed
*/
public static function generate_secret() {
$session = sanitize_text_field( $_SESSION );
if ( ! empty( $session['adfuz_secret'] ) ) {
return $session['adfuz_secret'];
}
$session['adfuz_secret'] = self::get_random_string( 5 );
return $session['adfuz_secret'];
}
/**
* Sanitize Text Field
*
* @param mixed $var Variable.
*
* @return mixed
*/
public static function sanitize_text_field( $var ) {
if ( is_array( $var ) ) {
return array_map( array( 'self', 'sanitize_text_field' ), $var );
}
return is_scalar( $var ) ? \sanitize_text_field( $var ) : $var;
}
/**
* Get Random String.
*
* @param int $length Length.
*
* @return string
*/
public static function get_random_string( int $length = 10 ): string {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$characters_length = strlen( $characters );
$random_string = '';
for ( $i = 0; $i < $length; $i++ ) {
$random_string .= $characters[ wp_rand( 0, $characters_length - 1 ) ];
}
return $random_string;
}
/**
* Decrypt a String.
*
* @param string $string String.
*
* @return false|string
*/
public static function decrypt( $string ) {
$secret_key = wp_create_nonce();
$secret_iv = self::generate_secret();
$encrypt_method = 'AES-128-CBC';
$key = hash( 'sha256', $secret_key );
$iv = substr( hash( 'sha256', $secret_iv ), 0, 16 );
return openssl_decrypt( base64_decode( $string ), $encrypt_method, $key, 0, $iv );
}
/**
* Verify Nonce.
*
* @param mixed $request Request.
*
* @return void
*/
public static function verifyNonce( $request = null, $permission = null ): void {
if ( null === $request ) {
$request = isset( $_REQUEST ) ? wp_unslash( $_REQUEST ) : array();
}
$nonce_key = 'adfuz_nonce';
$nonce_raw = $request[ $nonce_key ] ?? null;
if ( empty( $nonce_raw ) ) {
self::handle_failure( __( 'Invalid Request - 700', 'ad-fuz' ) );
}
// WordPress requires this specific combination before wp_verify_nonce.
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $nonce_raw ) ), $nonce_key ) ) {
self::handle_failure( __( 'Invalid Request - 701', 'ad-fuz' ) );
}
}
/**
* Check Capability.
*
* @param string $capability Capability.
*
* @return void
*/
public static function checkCapability( $capabilities = array( 'manage_options' ) ) {
$capabilities = (array) $capabilities;
foreach ( $capabilities as $capability ) {
if ( current_user_can( $capability ) ) {
return $capability;
}
}
self::handle_failure( __( 'You do not have permission to perform this action.', 'ad-fuz' ) );
}
/**
* Get array value by path.
*
* @param array $array Array value.
* @param string $path Array path.
*
* @return mixed|null
*/
protected static function get_array_value_by_path( $array, $path ) {
$keys = explode( '.', $path );
foreach ( $keys as $key ) {
if ( ! is_array( $array ) || ! array_key_exists( $key, $array ) ) {
return null;
}
$array = $array[ $key ];
}
return $array;
}
/**
* Handle Nonce Failure.
*
* @param string $message Message.
*
* @return void
*/
protected static function handle_failure( $message ) {
if ( wp_doing_ajax() ) {
wp_send_json_error( array( 'message' => esc_html( $message ) ) );
} else {
wp_die( esc_html( $message ) );
}
}
/**
* Set value to Array.
*
* @param mixed $target Target.
* @param mixed $key Key.
* @param mixed $value Value.
* @param bool $overwrite Overwrite.
*
* @return array|mixed
*/
public static function set( array &$target, $key, $value, bool $overwrite = true ) {
$segments = is_array( $key ) ? $key : explode( '.', $key );
$segment = array_shift( $segments );
if ( $segment === '*' ) {
if ( ! self::accessible( $target ) ) {
$target = array();
}
if ( $segments ) {
foreach ( $target as &$inner ) {
set( $inner, $segments, $value, $overwrite );
}
} elseif ( $overwrite ) {
foreach ( $target as &$inner ) {
$inner = $value;
}
}
} elseif ( self::accessible( $target ) ) {
if ( $segments ) {
if ( ! self::exists( $target, $segment ) ) {
$target[ $segment ] = array();
}
set( $target[ $segment ], $segments, $value, $overwrite );
} elseif ( $overwrite || ! self::exists( $target, $segment ) ) {
$target[ $segment ] = $value;
}
} elseif ( is_object( $target ) ) {
if ( $segments ) {
if ( ! isset( $target->{$segment} ) ) {
$target->{$segment} = array();
}
set( $target->{$segment}, $segments, $value, $overwrite );
} elseif ( $overwrite || ! isset( $target->{$segment} ) ) {
$target->{$segment} = $value;
}
} else {
$target = array();
if ( $segments ) {
set( $target[ $segment ], $segments, $value, $overwrite );
} elseif ( $overwrite ) {
$target[ $segment ] = $value;
}
}
return $target;
}
/**
* Accessible.
*
* @param mixed $value Value.
*
* @return bool
*/
public static function accessible( $value ): bool {
return is_array( $value ) || $value instanceof ArrayAccess;
}
/**
* Exists or not.
*
* @param mixed $array Array.
* @param mixed $key Key.
*
* @return bool
*/
public static function exists( $array, $key ): bool {
if ( $array instanceof ArrayAccess ) {
return $array->offsetExists( $key );
}
return array_key_exists( $key, $array );
}
/**
* Convert Array to String.
*
* @param array $data Data.
* @param string $prefix Prefix.
*
* @return string
*/
public static function array_to_string( $data, $prefix = '' ): string {
$dataAttribute = '';
foreach ( $data as $key => $value ) {
$escapedKey = htmlspecialchars( $key, ENT_QUOTES, 'UTF-8' );
$escapedValue = htmlspecialchars( $value, ENT_QUOTES, 'UTF-8' );
$dataAttribute .= $prefix . "$escapedKey='$escapedValue' ";
}
return $dataAttribute;
}
public static function with_html_attr( $find, $data, $attr = '', $append = '' ): string {
$value = self::get( $find, $data, '' );
if ( empty( $attr ) ) {
$parts = explode( '.', $find );
$attr = end( $parts );
}
if ( ! empty( $append ) ) {
$value .= ' ' . $append;
}
return ! empty( $value ) ? $attr . '="' . $value . '"' : '';
}
/**
* Get Value.
*
* @param string $key Key.
* @param mixed $target Target.
* @param string|null|array $default Default.
* @param bool $sanitize Sanitize.
*
* @return array|\Closure|mixed|string|null
*/
public static function get( string $key, $target = null, $default = null, bool $sanitize = true ) {
if ( $target === null && ! isset( $_REQUEST ) ) {
return $default;
}
if ( null === $target ) {
// Route through Request::input() so sanitization is applied correctly.
// Direct $_REQUEST access is intentionally avoided here.
$request = Request::get_instance();
$parts = explode( '.', $key );
$first = array_shift( $parts );
$value = $request->input( $first, 'request', $default );
if ( empty( $parts ) ) {
return $value;
}
$target = $value;
}
foreach ( explode( '.', $key ) as $segment ) {
if ( is_array( $target ) ) {
if ( ! array_key_exists( $segment, $target ) ) {
return self::get_value( $default, $sanitize );
}
$target = $target[ $segment ];
} elseif ( $target instanceof ArrayAccess ) {
if ( ! isset( $target[ $segment ] ) ) {
return self::get_value( $default, $sanitize );
}
$target = $target[ $segment ];
} elseif ( is_object( $target ) ) {
if ( ! isset( $target->{$segment} ) ) {
return self::get_value( $default, $sanitize );
}
$target = $target->{$segment};
} else {
return self::get_value( $default, $sanitize );
}
}
return self::get_value( $target, $sanitize );
}
/**
* Get Value.
*
* @param \Closure | array | string $value Value.
* @param bool $sanitize Sanitize.
*
* @return mixed
*/
public static function get_value( $value, bool $sanitize = true ) {
return ( $value instanceof Closure ) ? $value() : ( $sanitize ? sanitize_text_field( $value ) : $value );
}
public static function devices( $device_id = null ) {
$devices = array(
'mobile' => 'Mobile',
'tablet' => 'Tablet',
'desktop' => 'Desktop',
'laptop' => 'Laptop',
'smarttv' => 'Smart TV',
);
return $device_id ? ( $devices[ $device_id ] ?? '' ) : $devices;
}
public static function ad_sequence( $sequence_id = null ) {
$sequences = array(
'random' => 'Random Order',
'sequential' => 'Sequential Order',
'priority' => 'Priority Order',
);
$sequences = apply_filters( 'adfuz/ads/ad_sequence/sequence', $sequences );
return $sequence_id ? ( $sequences[ $sequence_id ] ?? '' ) : $sequences;
}
public static function currency( $currency_id = null ) {
$currency_list = array(
'ALL' => array(
'name' => 'Albanian Lek',
'symbol' => 'Lek',
),
'DZD' => array(
'name' => 'Algerian Dinar',
'symbol' => 'دج',
),
'AOA' => array(
'name' => 'Angolan Kwanza',
'symbol' => 'Kz',
),
'ARS' => array(
'name' => 'Argentine Peso',
'symbol' => '$',
),
'AMD' => array(
'name' => 'Armenian Dram',
'symbol' => '֏',
),
'AWG' => array(
'name' => 'Aruban Florin',
'symbol' => 'ƒ',
),
'AUD' => array(
'name' => 'Australian Dollar',
'symbol' => '$',
),
'AZN' => array(
'name' => 'Azerbaijani Manat',
'symbol' => 'm',
),
'BSD' => array(
'name' => 'Bahamian Dollar',
'symbol' => 'B$',
),
'BHD' => array(
'name' => 'Bahraini Dinar',
'symbol' => '.د.ب',
),
'BDT' => array(
'name' => 'Bangladeshi Taka',
'symbol' => '৳',
),
'BBD' => array(
'name' => 'Barbadian Dollar',
'symbol' => 'Bds$',
),
'BYR' => array(
'name' => 'Belarusian Ruble',
'symbol' => 'Br',
),
'BEF' => array(
'name' => 'Belgian Franc',
'symbol' => 'fr',
),
'BZD' => array(
'name' => 'Belize Dollar',
'symbol' => '$',
),
'BMD' => array(
'name' => 'Bermudan Dollar',
'symbol' => '$',
),
'BTN' => array(
'name' => 'Bhutanese Ngultrum',
'symbol' => 'Nu.',
),
'BTC' => array(
'name' => 'Bitcoin',
'symbol' => '฿',
),
'BOB' => array(
'name' => 'Bolivian Boliviano',
'symbol' => 'Bs.',
),
'BAM' => array(
'name' => 'Bosnia',
'symbol' => 'KM',
),
'BWP' => array(
'name' => 'Botswanan Pula',
'symbol' => 'P',
),
'BRL' => array(
'name' => 'Brazilian Real',
'symbol' => 'R$',
),
'GBP' => array(
'name' => 'British Pound Sterling',
'symbol' => '£',
),
'BND' => array(
'name' => 'Brunei Dollar',
'symbol' => 'B$',
),
'BGN' => array(
'name' => 'Bulgarian Lev',
'symbol' => 'Лв.',
),
'BIF' => array(
'name' => 'Burundian Franc',
'symbol' => 'FBu',
),
'KHR' => array(
'name' => 'Cambodian Riel',
'symbol' => 'KHR',
),
'CAD' => array(
'name' => 'Canadian Dollar',
'symbol' => '$',
),
'CVE' => array(
'name' => 'Cape Verdean Escudo',
'symbol' => '$',
),
'KYD' => array(
'name' => 'Cayman Islands Dollar',
'symbol' => '$',
),
'XOF' => array(
'name' => 'CFA Franc BCEAO',
'symbol' => 'CFA',
),
'XAF' => array(
'name' => 'CFA Franc BEAC',
'symbol' => 'FCFA',
),
'XPF' => array(
'name' => 'CFP Franc',
'symbol' => '₣',
),
'CLP' => array(
'name' => 'Chilean Peso',
'symbol' => '$',
),
'CLF' => array(
'name' => 'Chilean Unit of Account',
'symbol' => 'CLF',
),
'CNY' => array(
'name' => 'Chinese Yuan',
'symbol' => '¥',
),
'COP' => array(
'name' => 'Colombian Peso',
'symbol' => '$',
),
'KMF' => array(
'name' => 'Comorian Franc',
'symbol' => 'CF',
),
'CDF' => array(
'name' => 'Congolese Franc',
'symbol' => 'FC',
),
'CRC' => array(
'name' => 'Costa Rican Colón',
'symbol' => '₡',
),
'HRK' => array(
'name' => 'Croatian Kuna',
'symbol' => 'kn',
),
'CUC' => array(
'name' => 'Cuban Convertible Peso',
'symbol' => '$, CUC',
),
'CZK' => array(
'name' => 'Czech Republic Koruna',
'symbol' => 'Kč',
),
'DKK' => array(
'name' => 'Danish Krone',
'symbol' => 'Kr.',
),
'DJF' => array(
'name' => 'Djiboutian Franc',
'symbol' => 'Fdj',
),
'DOP' => array(
'name' => 'Dominican Peso',
'symbol' => '$',
),
'XCD' => array(
'name' => 'East Caribbean Dollar',
'symbol' => '$',
),
'EGP' => array(
'name' => 'Egyptian Pound',
'symbol' => 'ج.م',
),
'ERN' => array(
'name' => 'Eritrean Nakfa',
'symbol' => 'Nfk',
),
'EEK' => array(
'name' => 'Estonian Kroon',
'symbol' => 'kr',
),
'ETB' => array(
'name' => 'Ethiopian Birr',
'symbol' => 'Nkf',
),
'EUR' => array(
'name' => 'Euro',
'symbol' => '€',
),
'FKP' => array(
'name' => 'Falkland Islands Pound',
'symbol' => '£',
),
'FJD' => array(
'name' => 'Fijian Dollar',
'symbol' => 'FJ$',
),
'GMD' => array(
'name' => 'Gambian Dalasi',
'symbol' => 'D',
),
'GEL' => array(
'name' => 'Georgian Lari',
'symbol' => 'ლ',
),
'DEM' => array(
'name' => 'German Mark',
'symbol' => 'DM',
),
'GHS' => array(
'name' => 'Ghanaian Cedi',
'symbol' => 'GH₵',
),
'GIP' => array(
'name' => 'Gibraltar Pound',
'symbol' => '£',
),
'GRD' => array(
'name' => 'Greek Drachma',
'symbol' => '₯, Δρχ, Δρ',
),
'GTQ' => array(
'name' => 'Guatemalan Quetzal',
'symbol' => 'Q',
),
'GNF' => array(
'name' => 'Guinean Franc',
'symbol' => 'FG',
),
'GYD' => array(
'name' => 'Guyanaese Dollar',
'symbol' => '$',
),
'HTG' => array(
'name' => 'Haitian Gourde',
'symbol' => 'G',
),
'HNL' => array(
'name' => 'Honduran Lempira',
'symbol' => 'L',
),
'HKD' => array(
'name' => 'Hong Kong Dollar',
'symbol' => '$',
),
'HUF' => array(
'name' => 'Hungarian Forint',
'symbol' => 'Ft',
),
'ISK' => array(
'name' => 'Icelandic Króna',
'symbol' => 'kr',
),
'INR' => array(
'name' => 'Indian Rupee',
'symbol' => '₹',
),
'IDR' => array(
'name' => 'Indonesian Rupiah',
'symbol' => 'Rp',
),
'IRR' => array(
'name' => 'Iranian Rial',
'symbol' => '﷼',
),
'IQD' => array(
'name' => 'Iraqi Dinar',
'symbol' => 'د.ع',
),
'ILS' => array(
'name' => 'Israeli New Sheqel',
'symbol' => '₪',
),
'ITL' => array(
'name' => 'Italian Lira',
'symbol' => 'L,£',
),
'JMD' => array(
'name' => 'Jamaican Dollar',
'symbol' => 'J$',
),
'JPY' => array(
'name' => 'Japanese Yen',
'symbol' => '¥',
),
'JOD' => array(
'name' => 'Jordanian Dinar',
'symbol' => 'ا.د',
),
'KZT' => array(
'name' => 'Kazakhstani Tenge',
'symbol' => 'лв',
),
'KES' => array(
'name' => 'Kenyan Shilling',
'symbol' => 'KSh',
),
'KWD' => array(
'name' => 'Kuwaiti Dinar',
'symbol' => 'ك.د',
),
'KGS' => array(
'name' => 'Kyrgystani Som',
'symbol' => 'лв',
),
'LAK' => array(
'name' => 'Laotian Kip',
'symbol' => '₭',
),
'LVL' => array(
'name' => 'Latvian Lats',
'symbol' => 'Ls',
),
'LBP' => array(
'name' => 'Lebanese Pound',
'symbol' => '£',
),
'LSL' => array(
'name' => 'Lesotho Loti',
'symbol' => 'L',
),
'LRD' => array(
'name' => 'Liberian Dollar',
'symbol' => '$',
),
'LYD' => array(
'name' => 'Libyan Dinar',
'symbol' => 'د.ل',
),
'LTC' => array(
'name' => 'Litecoin',
'symbol' => 'Ł',
),
'LTL' => array(
'name' => 'Lithuanian Litas',
'symbol' => 'Lt',
),
'MOP' => array(
'name' => 'Macanese Pataca',
'symbol' => '$',
),
'MKD' => array(
'name' => 'Macedonian Denar',
'symbol' => 'ден',
),
'MGA' => array(
'name' => 'Malagasy Ariary',
'symbol' => 'Ar',
),
'MWK' => array(
'name' => 'Malawian Kwacha',
'symbol' => 'MK',
),
'MYR' => array(
'name' => 'Malaysian Ringgit',
'symbol' => 'RM',
),
'MVR' => array(
'name' => 'Maldivian Rufiyaa',
'symbol' => 'Rf',
),
'MRO' => array(
'name' => 'Mauritanian Ouguiya',
'symbol' => 'MRU',
),
'MUR' => array(
'name' => 'Mauritian Rupee',
'symbol' => '₨',
),
'MXN' => array(
'name' => 'Mexican Peso',
'symbol' => '$',
),
'MDL' => array(
'name' => 'Moldovan Leu',
'symbol' => 'L',
),
'MNT' => array(
'name' => 'Mongolian Tugrik',
'symbol' => '₮',
),
'MAD' => array(
'name' => 'Moroccan Dirham',
'symbol' => 'MAD',
),
'MZM' => array(
'name' => 'Mozambican Metical',
'symbol' => 'MT',
),
'MMK' => array(
'name' => 'Myanmar Kyat',
'symbol' => 'K',
),
'NAD' => array(
'name' => 'Namibian Dollar',
'symbol' => '$',
),
'NPR' => array(
'name' => 'Nepalese Rupee',
'symbol' => '₨',
),
'ANG' => array(
'name' => 'Netherlands Antillean Guilder',
'symbol' => 'ƒ',
),
'TWD' => array(
'name' => 'New Taiwan Dollar',
'symbol' => '$',
),
'NZD' => array(
'name' => 'New Zealand Dollar',
'symbol' => '$',
),
'NIO' => array(
'name' => 'Nicaraguan Córdoba',
'symbol' => 'C$',
),
'NGN' => array(
'name' => 'Nigerian Naira',
'symbol' => '₦',
),
'KPW' => array(
'name' => 'North Korean Won',
'symbol' => '₩',
),
'NOK' => array(
'name' => 'Norwegian Krone',
'symbol' => 'kr',
),
'OMR' => array(
'name' => 'Omani Rial',
'symbol' => '.ع.ر',
),
'PKR' => array(
'name' => 'Pakistani Rupee',
'symbol' => '₨',
),
'PAB' => array(
'name' => 'Panamanian Balboa',
'symbol' => 'B/.',
),
'PGK' => array(
'name' => 'Papua New Guinean Kina',
'symbol' => 'K',
),
'PYG' => array(
'name' => 'Paraguayan Guarani',
'symbol' => '₲',
),
'PEN' => array(
'name' => 'Peruvian Nuevo Sol',
'symbol' => 'S/.',
),
'PHP' => array(
'name' => 'Philippine Peso',
'symbol' => '₱',
),
'PLN' => array(
'name' => 'Polish Zloty',
'symbol' => 'zł',
),
'QAR' => array(
'name' => 'Qatari Rial',
'symbol' => 'ق.ر',
),
'RON' => array(
'name' => 'Romanian Leu',
'symbol' => 'lei',
),
'RUB' => array(
'name' => 'Russian Ruble',
'symbol' => '₽',
),
'RWF' => array(
'name' => 'Rwandan Franc',
'symbol' => 'FRw',
),
'SVC' => array(
'name' => 'Salvadoran Colón',
'symbol' => '₡',
),
'WST' => array(
'name' => 'Samoan Tala',
'symbol' => 'SAT',
),
'STD' => array(
'name' => 'São Tomé and Príncipe Dobra',
'symbol' => 'Db',
),
'SAR' => array(
'name' => 'Saudi Riyal',
'symbol' => '﷼',
),
'RSD' => array(
'name' => 'Serbian Dinar',
'symbol' => 'din',
),
'SCR' => array(
'name' => 'Seychellois Rupee',
'symbol' => 'SRe',
),
'SLL' => array(
'name' => 'Sierra Leonean Leone',
'symbol' => 'Le',
),
'SGD' => array(
'name' => 'Singapore Dollar',
'symbol' => '$',
),
'SKK' => array(
'name' => 'Slovak Koruna',
'symbol' => 'Sk',
),
'SBD' => array(
'name' => 'Solomon Islands Dollar',
'symbol' => 'Si$',
),
'SOS' => array(
'name' => 'Somali Shilling',
'symbol' => 'Sh.so.',
),
'ZAR' => array(
'name' => 'South African Rand',
'symbol' => 'R',
),
'KRW' => array(
'name' => 'South Korean Won',
'symbol' => '₩',
),
'SSP' => array(
'name' => 'South Sudanese Pound',
'symbol' => '£',
),
'XDR' => array(
'name' => 'Special Drawing Rights',
'symbol' => 'SDR',
),
'LKR' => array(
'name' => 'Sri Lankan Rupee',
'symbol' => 'Rs',
),
'SHP' => array(
'name' => 'St. Helena Pound',
'symbol' => '£',
),
'SDG' => array(
'name' => 'Sudanese Pound',
'symbol' => '.س.ج',
),
'SRD' => array(
'name' => 'Surinamese Dollar',
'symbol' => '$',
),
'SZL' => array(
'name' => 'Swazi Lilangeni',
'symbol' => 'E',
),
'SEK' => array(
'name' => 'Swedish Krona',
'symbol' => 'kr',
),
'CHF' => array(
'name' => 'Swiss Franc',
'symbol' => 'CHf',
),
'SYP' => array(
'name' => 'Syrian Pound',
'symbol' => 'LS',
),
'TJS' => array(
'name' => 'Tajikistani Somoni',
'symbol' => 'SM',
),
'TZS' => array(
'name' => 'Tanzanian Shilling',
'symbol' => 'TSh',
),
'THB' => array(
'name' => 'Thai Baht',
'symbol' => '฿',
),
'TOP' => array(
'name' => "Tongan Pa'anga",
'symbol' => '$',
),
'TTD' => array(
'name' => 'Trinidad & Tobago Dollar',
'symbol' => '$',
),
'TND' => array(
'name' => 'Tunisian Dinar',
'symbol' => 'ت.د',
),
'TRY' => array(
'name' => 'Turkish Lira',
'symbol' => '₺',
),
'TMT' => array(
'name' => 'Turkmenistani Manat',
'symbol' => 'T',
),
'UGX' => array(
'name' => 'Ugandan Shilling',
'symbol' => 'USh',
),
'UAH' => array(
'name' => 'Ukrainian Hryvnia',
'symbol' => '₴',
),
'AED' => array(
'name' => 'United Arab Emirates Dirham',
'symbol' => 'إ.د',
),
'UYU' => array(
'name' => 'Uruguayan Peso',
'symbol' => '$',
),
'USD' => array(
'name' => 'US Dollar',
'symbol' => '$',
),
'UZS' => array(
'name' => 'Uzbekistan Som',
'symbol' => 'лв',
),
'VUV' => array(
'name' => 'Vanuatu Vatu',
'symbol' => 'VT',
),
'VEF' => array(
'name' => 'Venezuelan BolÃvar',
'symbol' => 'Bs',
),
'VND' => array(
'name' => 'Vietnamese Dong',
'symbol' => '₫',
),
'YER' => array(
'name' => 'Yemeni Rial',
'symbol' => '﷼',
),
'ZMK' => array(
'name' => 'Zambian Kwacha',
'symbol' => 'ZK',
),
);
return $currency_id ? ( $currency_list[ $currency_id ] ?? '' ) : $currency_list;
}
public static function countries( $country_code = null ) {
$countries = array(
'AF' => array(
'name' => 'Afghanistan',
'continent' => 'Asia',
),
'AX' => array(
'name' => 'Åland Islands',
'continent' => 'Europe',
),
'AL' => array(
'name' => 'Albania',
'continent' => 'Europe',
),
'DZ' => array(
'name' => 'Algeria',
'continent' => 'Africa',
),
'AS' => array(
'name' => 'American Samoa',
'continent' => 'Oceania',
),
'AD' => array(
'name' => 'Andorra',
'continent' => 'Europe',
),
'AO' => array(
'name' => 'Angola',
'continent' => 'Africa',
),
'AI' => array(
'name' => 'Anguilla',
'continent' => 'North America',
),
'AQ' => array(
'name' => 'Antarctica',
'continent' => 'Antarctica',
),
'AG' => array(
'name' => 'Antigua and Barbuda',
'continent' => 'North America',
),
'AR' => array(
'name' => 'Argentina',
'continent' => 'South America',
),
'AM' => array(
'name' => 'Armenia',
'continent' => 'Asia',
),
'AW' => array(
'name' => 'Aruba',
'continent' => 'North America',
),
'AU' => array(
'name' => 'Australia',
'continent' => 'Oceania',
),
'AT' => array(
'name' => 'Austria',
'continent' => 'Europe',
),
'AZ' => array(
'name' => 'Azerbaijan',
'continent' => 'Asia',
),
'BS' => array(
'name' => 'Bahamas',
'continent' => 'North America',
),
'BH' => array(
'name' => 'Bahrain',
'continent' => 'Asia',
),
'BD' => array(
'name' => 'Bangladesh',
'continent' => 'Asia',
),
'BB' => array(
'name' => 'Barbados',
'continent' => 'North America',
),
'BY' => array(
'name' => 'Belarus',
'continent' => 'Europe',
),
'BE' => array(
'name' => 'Belgium',
'continent' => 'Europe',
),
'BZ' => array(
'name' => 'Belize',
'continent' => 'North America',
),
'BJ' => array(
'name' => 'Benin',
'continent' => 'Africa',
),
'BM' => array(
'name' => 'Bermuda',
'continent' => 'North America',
),
'BT' => array(
'name' => 'Bhutan',
'continent' => 'Asia',
),
'BO' => array(
'name' => 'Bolivia',
'continent' => 'South America',
),
'BA' => array(
'name' => 'Bosnia and Herzegovina',
'continent' => 'Europe',
),
'BW' => array(
'name' => 'Botswana',
'continent' => 'Africa',
),
'BV' => array(
'name' => 'Bouvet Island',
'continent' => 'Antarctica',
),
'BR' => array(
'name' => 'Brazil',
'continent' => 'South America',
),
'IO' => array(
'name' => 'British Indian Ocean Territory',
'continent' => 'Asia',
),
'BN' => array(
'name' => 'Brunei Darussalam',
'continent' => 'Asia',
),
'BG' => array(
'name' => 'Bulgaria',
'continent' => 'Europe',
),
'BF' => array(
'name' => 'Burkina Faso',
'continent' => 'Africa',
),
'BI' => array(
'name' => 'Burundi',
'continent' => 'Africa',
),
'KH' => array(
'name' => 'Cambodia',
'continent' => 'Asia',
),
'CM' => array(
'name' => 'Cameroon',
'continent' => 'Africa',
),
'CA' => array(
'name' => 'Canada',
'continent' => 'North America',
),
'CV' => array(
'name' => 'Cape Verde',
'continent' => 'Africa',
),
'KY' => array(
'name' => 'Cayman Islands',
'continent' => 'North America',
),
'CF' => array(
'name' => 'Central African Republic',
'continent' => 'Africa',
),
'TD' => array(
'name' => 'Chad',
'continent' => 'Africa',
),
'CL' => array(
'name' => 'Chile',
'continent' => 'South America',
),
'CN' => array(
'name' => 'China',
'continent' => 'Asia',
),
'CX' => array(
'name' => 'Christmas Island',
'continent' => 'Asia',
),
'CC' => array(
'name' => 'Cocos (Keeling] Islands',
'continent' => 'Asia',
),
'CO' => array(
'name' => 'Colombia',
'continent' => 'South America',
),
'KM' => array(
'name' => 'Comoros',
'continent' => 'Africa',
),
'CG' => array(
'name' => 'Congo',
'continent' => 'Africa',
),
'CD' => array(
'name' => 'The Democratic Republic of The Congo',
'continent' => 'Africa',
),
'CK' => array(
'name' => 'Cook Islands',
'continent' => 'Oceania',
),
'CR' => array(
'name' => 'Costa Rica',
'continent' => 'North America',
),
'CI' => array(
'name' => "Cote D'ivoire",
'continent' => 'Africa',
),
'HR' => array(
'name' => 'Croatia',
'continent' => 'Europe',
),
'CU' => array(
'name' => 'Cuba',
'continent' => 'North America',
),
'CY' => array(
'name' => 'Cyprus',
'continent' => 'Asia',
),
'CZ' => array(
'name' => 'Czech Republic',
'continent' => 'Europe',
),
'DK' => array(
'name' => 'Denmark',
'continent' => 'Europe',
),
'DJ' => array(
'name' => 'Djibouti',
'continent' => 'Africa',
),
'DM' => array(
'name' => 'Dominica',
'continent' => 'North America',
),
'DO' => array(
'name' => 'Dominican Republic',
'continent' => 'North America',
),
'EC' => array(
'name' => 'Ecuador',
'continent' => 'South America',
),
'EG' => array(
'name' => 'Egypt',
'continent' => 'Africa',
),
'SV' => array(
'name' => 'El Salvador',
'continent' => 'North America',
),
'GQ' => array(
'name' => 'Equatorial Guinea',
'continent' => 'Africa',
),
'ER' => array(
'name' => 'Eritrea',
'continent' => 'Africa',
),
'EE' => array(
'name' => 'Estonia',
'continent' => 'Europe',
),
'ET' => array(
'name' => 'Ethiopia',
'continent' => 'Africa',
),
'FK' => array(
'name' => 'Falkland Islands (Malvinas]',
'continent' => 'South America',
),
'FO' => array(
'name' => 'Faroe Islands',
'continent' => 'Europe',
),
'FJ' => array(
'name' => 'Fiji',
'continent' => 'Oceania',
),
'FI' => array(
'name' => 'Finland',
'continent' => 'Europe',
),
'FR' => array(
'name' => 'France',
'continent' => 'Europe',
),
'GF' => array(
'name' => 'French Guiana',
'continent' => 'South America',
),
'PF' => array(
'name' => 'French Polynesia',
'continent' => 'Oceania',
),
'TF' => array(
'name' => 'French Southern Territories',
'continent' => 'Antarctica',
),
'GA' => array(
'name' => 'Gabon',
'continent' => 'Africa',
),
'GM' => array(
'name' => 'Gambia',
'continent' => 'Africa',
),
'GE' => array(
'name' => 'Georgia',
'continent' => 'Asia',
),
'DE' => array(
'name' => 'Germany',
'continent' => 'Europe',
),
'GH' => array(
'name' => 'Ghana',
'continent' => 'Africa',
),
'GI' => array(
'name' => 'Gibraltar',
'continent' => 'Europe',
),
'GR' => array(
'name' => 'Greece',
'continent' => 'Europe',
),
'GL' => array(
'name' => 'Greenland',
'continent' => 'North America',
),
'GD' => array(
'name' => 'Grenada',
'continent' => 'North America',
),
'GP' => array(
'name' => 'Guadeloupe',
'continent' => 'North America',
),
'GU' => array(
'name' => 'Guam',
'continent' => 'Oceania',
),
'GT' => array(
'name' => 'Guatemala',
'continent' => 'North America',
),
'GG' => array(
'name' => 'Guernsey',
'continent' => 'Europe',
),
'GN' => array(
'name' => 'Guinea',
'continent' => 'Africa',
),
'GW' => array(
'name' => 'Guinea-bissau',
'continent' => 'Africa',
),
'GY' => array(
'name' => 'Guyana',
'continent' => 'South America',
),
'HT' => array(
'name' => 'Haiti',
'continent' => 'North America',
),
'HM' => array(
'name' => 'Heard Island and Mcdonald Islands',
'continent' => 'Antarctica',
),
'VA' => array(
'name' => 'Holy See (Vatican City State]',
'continent' => 'Europe',
),
'HN' => array(
'name' => 'Honduras',
'continent' => 'North America',
),
'HK' => array(
'name' => 'Hong Kong',
'continent' => 'Asia',
),
'HU' => array(
'name' => 'Hungary',
'continent' => 'Europe',
),
'IS' => array(
'name' => 'Iceland',
'continent' => 'Europe',
),
'IN' => array(
'name' => 'India',
'continent' => 'Asia',
),
'ID' => array(
'name' => 'Indonesia',
'continent' => 'Asia',
),
'IR' => array(
'name' => 'Iran',
'continent' => 'Asia',
),
'IQ' => array(
'name' => 'Iraq',
'continent' => 'Asia',
),
'IE' => array(
'name' => 'Ireland',
'continent' => 'Europe',
),
'IM' => array(
'name' => 'Isle of Man',
'continent' => 'Europe',
),
'IL' => array(
'name' => 'Israel',
'continent' => 'Asia',
),
'IT' => array(
'name' => 'Italy',
'continent' => 'Europe',
),
'JM' => array(
'name' => 'Jamaica',
'continent' => 'North America',
),
'JP' => array(
'name' => 'Japan',
'continent' => 'Asia',
),
'JE' => array(
'name' => 'Jersey',
'continent' => 'Europe',
),
'JO' => array(
'name' => 'Jordan',
'continent' => 'Asia',
),
'KZ' => array(
'name' => 'Kazakhstan',
'continent' => 'Asia',
),
'KE' => array(
'name' => 'Kenya',
'continent' => 'Africa',
),
'KI' => array(
'name' => 'Kiribati',
'continent' => 'Oceania',
),
'KP' => array(
'name' => "Democratic People's Republic of Korea",
'continent' => 'Asia',
),
'KR' => array(
'name' => 'Republic of Korea',
'continent' => 'Asia',
),
'KW' => array(
'name' => 'Kuwait',
'continent' => 'Asia',
),
'KG' => array(
'name' => 'Kyrgyzstan',
'continent' => 'Asia',
),
'LA' => array(
'name' => "Lao People's Democratic Republic",
'continent' => 'Asia',
),
'LV' => array(
'name' => 'Latvia',
'continent' => 'Europe',
),
'LB' => array(
'name' => 'Lebanon',
'continent' => 'Asia',
),
'LS' => array(
'name' => 'Lesotho',
'continent' => 'Africa',
),
'LR' => array(
'name' => 'Liberia',
'continent' => 'Africa',
),
'LY' => array(
'name' => 'Libya',
'continent' => 'Africa',
),
'LI' => array(
'name' => 'Liechtenstein',
'continent' => 'Europe',
),
'LT' => array(
'name' => 'Lithuania',
'continent' => 'Europe',
),
'LU' => array(
'name' => 'Luxembourg',
'continent' => 'Europe',
),
'MO' => array(
'name' => 'Macao',
'continent' => 'Asia',
),
'MK' => array(
'name' => 'Macedonia',
'continent' => 'Europe',
),
'MG' => array(
'name' => 'Madagascar',
'continent' => 'Africa',
),
'MW' => array(
'name' => 'Malawi',
'continent' => 'Africa',
),
'MY' => array(
'name' => 'Malaysia',
'continent' => 'Asia',
),
'MV' => array(
'name' => 'Maldives',
'continent' => 'Asia',
),
'ML' => array(
'name' => 'Mali',
'continent' => 'Africa',
),
'MT' => array(
'name' => 'Malta',
'continent' => 'Europe',
),
'MH' => array(
'name' => 'Marshall Islands',
'continent' => 'Oceania',
),
'MQ' => array(
'name' => 'Martinique',
'continent' => 'North America',
),
'MR' => array(
'name' => 'Mauritania',
'continent' => 'Africa',
),
'MU' => array(
'name' => 'Mauritius',
'continent' => 'Africa',
),
'YT' => array(
'name' => 'Mayotte',
'continent' => 'Africa',
),
'MX' => array(
'name' => 'Mexico',
'continent' => 'North America',
),
'FM' => array(
'name' => 'Micronesia',
'continent' => 'Oceania',
),
'MD' => array(
'name' => 'Moldova',
'continent' => 'Europe',
),
'MC' => array(
'name' => 'Monaco',
'continent' => 'Europe',
),
'MN' => array(
'name' => 'Mongolia',
'continent' => 'Asia',
),
'ME' => array(
'name' => 'Montenegro',
'continent' => 'Europe',
),
'MS' => array(
'name' => 'Montserrat',
'continent' => 'North America',
),
'MA' => array(
'name' => 'Morocco',
'continent' => 'Africa',
),
'MZ' => array(
'name' => 'Mozambique',
'continent' => 'Africa',
),
'MM' => array(
'name' => 'Myanmar',
'continent' => 'Asia',
),
'NA' => array(
'name' => 'Namibia',
'continent' => 'Africa',
),
'NR' => array(
'name' => 'Nauru',
'continent' => 'Oceania',
),
'NP' => array(
'name' => 'Nepal',
'continent' => 'Asia',
),
'NL' => array(
'name' => 'Netherlands',
'continent' => 'Europe',
),
'AN' => array(
'name' => 'Netherlands Antilles',
'continent' => 'North America',
),
'NC' => array(
'name' => 'New Caledonia',
'continent' => 'Oceania',
),
'NZ' => array(
'name' => 'New Zealand',
'continent' => 'Oceania',
),
'NI' => array(
'name' => 'Nicaragua',
'continent' => 'North America',
),
'NE' => array(
'name' => 'Niger',
'continent' => 'Africa',
),
'NG' => array(
'name' => 'Nigeria',
'continent' => 'Africa',
),
'NU' => array(
'name' => 'Niue',
'continent' => 'Oceania',
),
'NF' => array(
'name' => 'Norfolk Island',
'continent' => 'Oceania',
),
'MP' => array(
'name' => 'Northern Mariana Islands',
'continent' => 'Oceania',
),
'NO' => array(
'name' => 'Norway',
'continent' => 'Europe',
),
'OM' => array(
'name' => 'Oman',
'continent' => 'Asia',
),
'PK' => array(
'name' => 'Pakistan',
'continent' => 'Asia',
),
'PW' => array(
'name' => 'Palau',
'continent' => 'Oceania',
),
'PS' => array(
'name' => 'Palestinia',
'continent' => 'Asia',
),
'PA' => array(
'name' => 'Panama',
'continent' => 'North America',
),
'PG' => array(
'name' => 'Papua New Guinea',
'continent' => 'Oceania',
),
'PY' => array(
'name' => 'Paraguay',
'continent' => 'South America',
),
'PE' => array(
'name' => 'Peru',
'continent' => 'South America',
),
'PH' => array(
'name' => 'Philippines',
'continent' => 'Asia',
),
'PN' => array(
'name' => 'Pitcairn',
'continent' => 'Oceania',
),
'PL' => array(
'name' => 'Poland',
'continent' => 'Europe',
),
'PT' => array(
'name' => 'Portugal',
'continent' => 'Europe',
),
'PR' => array(
'name' => 'Puerto Rico',
'continent' => 'North America',
),
'QA' => array(
'name' => 'Qatar',
'continent' => 'Asia',
),
'RE' => array(
'name' => 'Reunion',
'continent' => 'Africa',
),
'RO' => array(
'name' => 'Romania',
'continent' => 'Europe',
),
'RU' => array(
'name' => 'Russian Federation',
'continent' => 'Europe',
),
'RW' => array(
'name' => 'Rwanda',
'continent' => 'Africa',
),
'SH' => array(
'name' => 'Saint Helena',
'continent' => 'Africa',
),
'KN' => array(
'name' => 'Saint Kitts and Nevis',
'continent' => 'North America',
),
'LC' => array(
'name' => 'Saint Lucia',
'continent' => 'North America',
),
'PM' => array(
'name' => 'Saint Pierre and Miquelon',
'continent' => 'North America',
),
'VC' => array(
'name' => 'Saint Vincent and The Grenadines',
'continent' => 'North America',
),
'WS' => array(
'name' => 'Samoa',
'continent' => 'Oceania',
),
'SM' => array(
'name' => 'San Marino',
'continent' => 'Europe',
),
'ST' => array(
'name' => 'Sao Tome and Principe',
'continent' => 'Africa',
),
'SA' => array(
'name' => 'Saudi Arabia',
'continent' => 'Asia',
),
'SN' => array(
'name' => 'Senegal',
'continent' => 'Africa',
),
'RS' => array(
'name' => 'Serbia',
'continent' => 'Europe',
),
'SC' => array(
'name' => 'Seychelles',
'continent' => 'Africa',
),
'SL' => array(
'name' => 'Sierra Leone',
'continent' => 'Africa',
),
'SG' => array(
'name' => 'Singapore',
'continent' => 'Asia',
),
'SK' => array(
'name' => 'Slovakia',
'continent' => 'Europe',
),
'SI' => array(
'name' => 'Slovenia',
'continent' => 'Europe',
),
'SB' => array(
'name' => 'Solomon Islands',
'continent' => 'Oceania',
),
'SO' => array(
'name' => 'Somalia',
'continent' => 'Africa',
),
'ZA' => array(
'name' => 'South Africa',
'continent' => 'Africa',
),
'GS' => array(
'name' => 'South Georgia and The South Sandwich Islands',
'continent' => 'Antarctica',
),
'ES' => array(
'name' => 'Spain',
'continent' => 'Europe',
),
'LK' => array(
'name' => 'Sri Lanka',
'continent' => 'Asia',
),
'SD' => array(
'name' => 'Sudan',
'continent' => 'Africa',
),
'SR' => array(
'name' => 'Suriname',
'continent' => 'South America',
),
'SJ' => array(
'name' => 'Svalbard and Jan Mayen',
'continent' => 'Europe',
),
'SZ' => array(
'name' => 'Swaziland',
'continent' => 'Africa',
),
'SE' => array(
'name' => 'Sweden',
'continent' => 'Europe',
),
'CH' => array(
'name' => 'Switzerland',
'continent' => 'Europe',
),
'SY' => array(
'name' => 'Syrian Arab Republic',
'continent' => 'Asia',
),
'TW' => array(
'name' => 'Taiwan, Province of China',
'continent' => 'Asia',
),
'TJ' => array(
'name' => 'Tajikistan',
'continent' => 'Asia',
),
'TZ' => array(
'name' => 'Tanzania, United Republic of',
'continent' => 'Africa',
),
'TH' => array(
'name' => 'Thailand',
'continent' => 'Asia',
),
'TL' => array(
'name' => 'Timor-leste',
'continent' => 'Asia',
),
'TG' => array(
'name' => 'Togo',
'continent' => 'Africa',
),
'TK' => array(
'name' => 'Tokelau',
'continent' => 'Oceania',
),
'TO' => array(
'name' => 'Tonga',
'continent' => 'Oceania',
),
'TT' => array(
'name' => 'Trinidad and Tobago',
'continent' => 'North America',
),
'TN' => array(
'name' => 'Tunisia',
'continent' => 'Africa',
),
'TR' => array(
'name' => 'Turkey',
'continent' => 'Asia',
),
'TM' => array(
'name' => 'Turkmenistan',
'continent' => 'Asia',
),
'TC' => array(
'name' => 'Turks and Caicos Islands',
'continent' => 'North America',
),
'TV' => array(
'name' => 'Tuvalu',
'continent' => 'Oceania',
),
'UG' => array(
'name' => 'Uganda',
'continent' => 'Africa',
),
'UA' => array(
'name' => 'Ukraine',
'continent' => 'Europe',
),
'AE' => array(
'name' => 'United Arab Emirates',
'continent' => 'Asia',
),
'GB' => array(
'name' => 'United Kingdom',
'continent' => 'Europe',
),
'US' => array(
'name' => 'United States',
'continent' => 'North America',
),
'UM' => array(
'name' => 'United States Minor Outlying Islands',
'continent' => 'Oceania',
),
'UY' => array(
'name' => 'Uruguay',
'continent' => 'South America',
),
'UZ' => array(
'name' => 'Uzbekistan',
'continent' => 'Asia',
),
'VU' => array(
'name' => 'Vanuatu',
'continent' => 'Oceania',
),
'VE' => array(
'name' => 'Venezuela',
'continent' => 'South America',
),
'VN' => array(
'name' => 'Viet Nam',
'continent' => 'Asia',
),
'VG' => array(
'name' => 'Virgin Islands, British',
'continent' => 'North America',
),
'VI' => array(
'name' => 'Virgin Islands, U.S.',
'continent' => 'North America',
),
'WF' => array(
'name' => 'Wallis and Futuna',
'continent' => 'Oceania',
),
'EH' => array(
'name' => 'Western Sahara',
'continent' => 'Africa',
),
'YE' => array(
'name' => 'Yemen',
'continent' => 'Asia',
),
'ZM' => array(
'name' => 'Zambia',
'continent' => 'Africa',
),
'ZW' => array(
'name' => 'Zimbabwe',
'continent' => 'Africa',
),
);
return $country_code ? ( $countries[ $country_code ] ?? '' ) : $countries;
}
public static function ad_format( $ad_format_id = null ) {
$ad_formats = array(
// ─────────────────────────────────────────────
// Banner
// ─────────────────────────────────────────────
'banner' => array(
'name' => 'Banner',
'description' => 'Displays a standard banner ad.',
'status' => 'active',
'placement_type' => 'positional',
'max_spaces' => null,
),
// ─────────────────────────────────────────────
// Slider
// ─────────────────────────────────────────────
'slider' => array(
'name' => 'Slider',
'description' => 'Displays a slider with multiple ads.',
'status' => 'active',
'placement_type' => 'positional',
'max_spaces' => null,
),
// ─────────────────────────────────────────────
// POPUP
// ─────────────────────────────────────────────
'popup' => array(
'name' => 'Popup',
'description' => 'Shows a popup ad on page load or user action.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 1,
// 'conversion_note' => __(
// 'Use a 600×400 px landscape banner (JPEG/PNG under 150 KB). '
// . 'A bold headline + single CTA converts best. '
// . 'Set the trigger delay to 3–5 s — early enough to catch attention, late enough not to annoy visitors. '
// . 'Include a discount code or urgency message ("Limited time offer!") to maximise click-through.',
// 'ad-fuz'
// ),
'settings' => array(
'delay' => array(
'label' => __( 'Trigger Delay (seconds)', 'ad-fuz' ),
'hint' => __( 'How many seconds after page load before the popup appears (0 = instant).', 'ad-fuz' ),
'type' => 'number',
'default' => 3,
'min' => 0,
'max' => 30,
'sanitize' => fn( $v ) => max( 0, min( 30, absint( $v ) ) ),
),
'overlay_color' => array(
'label' => __( 'Overlay Background Color', 'ad-fuz' ),
'hint' => __( 'Color of the semi-transparent backdrop behind the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'overlay_opacity' => array(
'label' => __( 'Overlay Opacity (%)', 'ad-fuz' ),
'hint' => __( 'Backdrop opacity from 0 (transparent) to 100 (solid).', 'ad-fuz' ),
'type' => 'number',
'default' => 60,
'min' => 0,
'max' => 100,
'sanitize' => fn( $v ) => max( 0, min( 100, absint( $v ) ) ),
),
'box_bg_color' => array(
'label' => __( 'Popup Box Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the popup box itself.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'box_padding' => array(
'label' => __( 'Popup Box Padding (px)', 'ad-fuz' ),
'hint' => __( 'Padding inside the popup box.', 'ad-fuz' ),
'type' => 'number',
'default' => 20,
'min' => 0,
'max' => 100,
'sanitize' => fn( $v ) => max( 0, min( 100, absint( $v ) ) ),
),
'box_radius' => array(
'label' => __( 'Popup Box Border Radius (px)', 'ad-fuz' ),
'hint' => __( 'Rounded corners for the popup box.', 'ad-fuz' ),
'type' => 'number',
'default' => 12,
'min' => 0,
'max' => 50,
'sanitize' => fn( $v ) => max( 0, min( 50, absint( $v ) ) ),
),
'box_width' => array(
'label' => __( 'Popup Box Width (px)', 'ad-fuz' ),
'hint' => __( 'Width of the popup box in pixels.', 'ad-fuz' ),
'type' => 'number',
'default' => 600,
'min' => 300,
'max' => 1200,
'sanitize' => fn( $v ) => max( 300, min( 1200, absint( $v ) ) ),
),
'box_max_width' => array(
'label' => __( 'Popup Box Max Width (vw)', 'ad-fuz' ),
'hint' => __( 'Maximum width of the popup box as a percentage of viewport width.', 'ad-fuz' ),
'type' => 'number',
'default' => 90,
'min' => 50,
'max' => 100,
'sanitize' => fn( $v ) => max( 50, min( 100, absint( $v ) ) ),
),
'title_color' => array(
'label' => __( 'Title Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad title text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'desc_color' => array(
'label' => __( 'Description Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad description text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'cta_color' => array(
'label' => __( 'CTA Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#2271b1',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#2271b1',
),
'cta_text_color' => array(
'label' => __( 'CTA Button Text Color', 'ad-fuz' ),
'hint' => __( 'Text color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'close_color' => array(
'label' => __( 'Close Button Color', 'ad-fuz' ),
'hint' => __( 'Color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'close_bg_color' => array(
'label' => __( 'Close Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => 'transparent',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: 'transparent',
),
),
),
// ─────────────────────────────────────────────
// EXIT POPUP
// ─────────────────────────────────────────────
'exit_popup' => array(
'name' => 'Exit Popup',
'description' => 'Triggers a popup when the user tries to leave the page.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 1,
// 'conversion_note' => __(
// 'Use a 600×400 px landscape banner. '
// . 'Last-chance offers ("Wait! Get 20% off") can recover 10–15% of abandoning users. '
// . 'Keep copy short: one bold headline + one CTA button. '
// . 'Avoid heavy imagery — keep file size under 150 KB so it renders before the user navigates away.',
// 'ad-fuz'
// ),
'settings' => array(
'overlay_color' => array(
'label' => __( 'Overlay Background Color', 'ad-fuz' ),
'hint' => __( 'Color of the semi-transparent backdrop behind the exit popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'overlay_opacity' => array(
'label' => __( 'Overlay Opacity (%)', 'ad-fuz' ),
'hint' => __( 'Backdrop opacity from 0 (transparent) to 100 (solid).', 'ad-fuz' ),
'type' => 'number',
'default' => 60,
'min' => 0,
'max' => 100,
'sanitize' => fn( $v ) => max( 0, min( 100, absint( $v ) ) ),
),
'box_bg_color' => array(
'label' => __( 'Popup Box Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the popup box itself.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'box_padding' => array(
'label' => __( 'Popup Box Padding (px)', 'ad-fuz' ),
'hint' => __( 'Padding inside the popup box.', 'ad-fuz' ),
'type' => 'number',
'default' => 20,
'min' => 0,
'max' => 100,
'sanitize' => fn( $v ) => max( 0, min( 100, absint( $v ) ) ),
),
'box_radius' => array(
'label' => __( 'Popup Box Border Radius (px)', 'ad-fuz' ),
'hint' => __( 'Rounded corners for the popup box.', 'ad-fuz' ),
'type' => 'number',
'default' => 12,
'min' => 0,
'max' => 50,
'sanitize' => fn( $v ) => max( 0, min( 50, absint( $v ) ) ),
),
'box_width' => array(
'label' => __( 'Popup Box Width (px)', 'ad-fuz' ),
'hint' => __( 'Width of the popup box in pixels.', 'ad-fuz' ),
'type' => 'number',
'default' => 600,
'min' => 300,
'max' => 1200,
'sanitize' => fn( $v ) => max( 300, min( 1200, absint( $v ) ) ),
),
'box_max_width' => array(
'label' => __( 'Popup Box Max Width (vw)', 'ad-fuz' ),
'hint' => __( 'Maximum width of the popup box as a percentage of viewport width.', 'ad-fuz' ),
'type' => 'number',
'default' => 90,
'min' => 50,
'max' => 100,
'sanitize' => fn( $v ) => max( 50, min( 100, absint( $v ) ) ),
),
'title_color' => array(
'label' => __( 'Title Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad title text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'desc_color' => array(
'label' => __( 'Description Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad description text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'cta_color' => array(
'label' => __( 'CTA Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#2271b1',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#2271b1',
),
'cta_text_color' => array(
'label' => __( 'CTA Button Text Color', 'ad-fuz' ),
'hint' => __( 'Text color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'close_color' => array(
'label' => __( 'Close Button Color', 'ad-fuz' ),
'hint' => __( 'Color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'close_bg_color' => array(
'label' => __( 'Close Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => 'transparent',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: 'transparent',
),
),
),
// ─────────────────────────────────────────────
// BACKGROUND
// ─────────────────────────────────────────────
'background' => array(
'name' => 'Background',
'description' => 'Sets the background of the page as an advertisement.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 1,
// 'conversion_note' => __(
// 'Provide a high-resolution image of at least 1920×1080 px (16:9, JPEG 80% quality). '
// . 'Use a light or subtly blurred image so it does not compete with page content. '
// . 'For video backgrounds, use a muted MP4 under 5 MB — autoplay only works when muted. '
// . 'Pair with a prominent on-page CTA since the background itself is the ad canvas.',
// 'ad-fuz'
// ),
// No behaviour settings needed — the background is purely visual,
// driven entirely by the ad's media URL.
// 'settings' => array(),
),
// ─────────────────────────────────────────────
// CORNER PEEL
// ─────────────────────────────────────────────
'corner_peel' => array(
'name' => 'Corner Peel',
'description' => 'Displays a peel effect in the corner revealing the ad.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 4,
'positions' => array(
'top_left' => 'Top Left',
'top_right' => 'Top Right',
'bottom_left' => 'Bottom Left',
'bottom_right' => 'Bottom Right',
),
// 'conversion_note' => __(
// 'Use the IAB Medium Rectangle (300×250 px) inside the expanded peel — '
// . 'it is the most widely accepted ad size and fills the expanded area cleanly. '
// . 'Set Peek Size to 100–120 px: noticeable without being disruptive. '
// . 'Works great for coupon reveals and teaser creatives — use curiosity-driven copy on the peel tab.',
// 'ad-fuz'
// ),
'settings' => array(
'peek_size' => array(
'label' => __( 'Peek Size (px)', 'ad-fuz' ),
'hint' => __( 'Size of the folded corner triangle shown before hover (default 120px, Min:60px and Max:200px).', 'ad-fuz' ),
'type' => 'number',
'default' => 120,
'min' => 60,
'max' => 200,
'sanitize' => fn( $v ) => max( 60, min( 200, absint( $v ) ) ),
),
'expand_width' => array(
'label' => __( 'Expanded Width (px)', 'ad-fuz' ),
'hint' => __( 'Width of the peel when fully expanded on hover (default 300px, Min:150px and Max:500px).', 'ad-fuz' ),
'type' => 'number',
'default' => 300,
'min' => 150,
'max' => 500,
'sanitize' => fn( $v ) => max( 150, min( 500, absint( $v ) ) ),
),
'expand_height' => array(
'label' => __( 'Expanded Height (px)', 'ad-fuz' ),
'hint' => __( 'Height of the peel when fully expanded on hover (default 250px, Min:100px and Max:500px).', 'ad-fuz' ),
'type' => 'number',
'default' => 250,
'min' => 100,
'max' => 500,
'sanitize' => fn( $v ) => max( 100, min( 500, absint( $v ) ) ),
),
),
),
// ─────────────────────────────────────────────
// SCROLL TRIGGER
// ─────────────────────────────────────────────
'scroll_trigger' => array(
'name' => 'Scroll Trigger',
'description' => 'Shows the ad after the user scrolls a certain distance.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 1,
// 'conversion_note' => __(
// 'For desktop use a 728×90 px Leaderboard; for mobile use a 320×50 px Mobile Banner. '
// . 'Triggering at 50% scroll depth targets engaged, mid-content readers. '
// . 'Keep creative simple with a clear CTA — the visitor is reading, not browsing. '
// . 'Bottom Center placement is the least intrusive and has the highest acceptance rate.',
// 'ad-fuz'
// ),
'settings' => array(
'scroll_depth' => array(
'label' => __( 'Scroll Depth (%)', 'ad-fuz' ),
'hint' => __( 'Page scroll percentage that triggers the ad (0–100).', 'ad-fuz' ),
'type' => 'number',
'default' => 50,
'min' => 5,
'max' => 100,
'sanitize' => fn( $v ) => max( 5, min( 100, absint( $v ) ) ),
),
'position' => array(
'label' => __( 'Ad Position', 'ad-fuz' ),
'hint' => __( 'Where the scroll-triggered ad appears on screen.', 'ad-fuz' ),
'type' => 'select',
'default' => 'bottom_center',
'options' => array(
'bottom_center' => __( 'Bottom Center', 'ad-fuz' ),
'bottom_left' => __( 'Bottom Left', 'ad-fuz' ),
'bottom_right' => __( 'Bottom Right', 'ad-fuz' ),
),
'sanitize' => fn( $v ) => in_array( $v, array( 'bottom_center', 'bottom_left', 'bottom_right' ), true ) ? $v : 'bottom_center',
),
'box_bg_color' => array(
'label' => __( 'Box Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the scroll trigger box.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'box_padding' => array(
'label' => __( 'Box Padding (px)', 'ad-fuz' ),
'hint' => __( 'Padding inside the scroll trigger box.', 'ad-fuz' ),
'type' => 'number',
'default' => 16,
'min' => 0,
'max' => 50,
'sanitize' => fn( $v ) => max( 0, min( 50, absint( $v ) ) ),
),
'box_radius' => array(
'label' => __( 'Box Border Radius (px)', 'ad-fuz' ),
'hint' => __( 'Rounded corners for the scroll trigger box.', 'ad-fuz' ),
'type' => 'number',
'default' => 12,
'min' => 0,
'max' => 50,
'sanitize' => fn( $v ) => max( 0, min( 50, absint( $v ) ) ),
),
'box_shadow' => array(
'label' => __( 'Box Shadow', 'ad-fuz' ),
'hint' => __( 'CSS box shadow for the scroll trigger box.', 'ad-fuz' ),
'type' => 'text',
'default' => '0 4px 24px rgba(0,0,0,0.18)',
'sanitize' => fn( $v ) => sanitize_text_field( $v ),
),
'title_color' => array(
'label' => __( 'Title Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad title text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'desc_color' => array(
'label' => __( 'Description Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad description text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'cta_color' => array(
'label' => __( 'CTA Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#2271b1',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#2271b1',
),
'cta_text_color' => array(
'label' => __( 'CTA Button Text Color', 'ad-fuz' ),
'hint' => __( 'Text color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'close_color' => array(
'label' => __( 'Close Button Color', 'ad-fuz' ),
'hint' => __( 'Color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'close_bg_color' => array(
'label' => __( 'Close Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => 'transparent',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: 'transparent',
),
),
),
// ─────────────────────────────────────────────
// INTERSTITIAL
// ─────────────────────────────────────────────
'interstitial' => array(
'name' => 'Interstitial',
'description' => 'Full-screen ad shown between content or during transitions.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 1,
// 'conversion_note' => __(
// 'Design at 1080×1920 px for portrait mobile or 1280×720 px for landscape desktop. '
// . 'Always allow a skip after 5 s — this complies with Google\'s Better Ads Standards and avoids ranking penalties. '
// . 'Use a single bold CTA with high-contrast colours against the black backdrop. '
// . 'High-impact visuals (product hero shots, full-bleed photography) maximise recall and CTR.',
// 'ad-fuz'
// ),
'settings' => array(
'skip_after' => array(
'label' => __( 'Skip After (seconds)', 'ad-fuz' ),
'hint' => __( 'Seconds the visitor must wait before the Skip button appears (1–60).', 'ad-fuz' ),
'type' => 'number',
'default' => 5,
'min' => 1,
'max' => 60,
'sanitize' => fn( $v ) => max( 1, min( 60, absint( $v ) ) ),
),
'title_color' => array(
'label' => __( 'Title Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the overlay title text — make sure it contrasts with the black background.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'desc_color' => array(
'label' => __( 'Description Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the overlay description text.', 'ad-fuz' ),
'type' => 'color',
'default' => '#cccccc',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#cccccc',
),
'bg_color' => array(
'label' => __( 'Background Color', 'ad-fuz' ),
'hint' => __( 'Background color for the interstitial overlay.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'content_width' => array(
'label' => __( 'Content Width (%)', 'ad-fuz' ),
'hint' => __( 'Width of the ad content as a percentage of viewport width.', 'ad-fuz' ),
'type' => 'number',
'default' => 80,
'min' => 50,
'max' => 100,
'sanitize' => fn( $v ) => max( 50, min( 100, absint( $v ) ) ),
),
'content_max_width' => array(
'label' => __( 'Content Max Width (px)', 'ad-fuz' ),
'hint' => __( 'Maximum width of the ad content in pixels.', 'ad-fuz' ),
'type' => 'number',
'default' => 1200,
'min' => 400,
'max' => 2000,
'sanitize' => fn( $v ) => max( 400, min( 2000, absint( $v ) ) ),
),
),
),
// ─────────────────────────────────────────────
// COUNTDOWN
// ─────────────────────────────────────────────
'countdown' => array(
'name' => 'Countdown',
'description' => 'Displays an ad with a countdown before allowing action.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 1,
// 'conversion_note' => __(
// 'Use a 600×400 px banner with a contrasting countdown badge colour. '
// . 'Urgency-driven creatives — flash sales, limited seats, expiring discounts — can lift conversions by up to 30%. '
// . 'Auto-close after the timer creates the smoothest UX; only show a manual close button when compliance requires it. '
// . 'Keep countdown duration under 15 s — longer timers frustrate users and increase bounce.',
// 'ad-fuz'
// ),
'settings' => array(
'duration' => array(
'label' => __( 'Countdown Duration (seconds)', 'ad-fuz' ),
'hint' => __( 'How long the countdown runs before the close button appears (3–60).', 'ad-fuz' ),
'type' => 'number',
'default' => 10,
'min' => 3,
'max' => 60,
'sanitize' => fn( $v ) => max( 3, min( 60, absint( $v ) ) ),
),
'auto_close' => array(
'label' => __( 'Auto Close After Timer', 'ad-fuz' ),
'hint' => __( 'Automatically close the ad once the countdown completes. If disabled, a close button appears instead.', 'ad-fuz' ),
'type' => 'toggle',
'default' => '1',
'sanitize' => fn( $v ) => $v ? '1' : '0',
),
'badge_color' => array(
'label' => __( 'Badge Background Color', 'ad-fuz' ),
'hint' => __( 'Color of the countdown timer badge shown above the ad.', 'ad-fuz' ),
'type' => 'color',
'default' => '#e53e3e',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#e53e3e',
),
'badge_text_color' => array(
'label' => __( 'Badge Text Color', 'ad-fuz' ),
'hint' => __( 'Color of the number/text inside the countdown badge.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'overlay_color' => array(
'label' => __( 'Overlay Background Color', 'ad-fuz' ),
'hint' => __( 'Color of the overlay backdrop behind the countdown ad.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'overlay_opacity' => array(
'label' => __( 'Overlay Opacity (%)', 'ad-fuz' ),
'hint' => __( 'Backdrop opacity from 0 (transparent) to 100 (solid).', 'ad-fuz' ),
'type' => 'number',
'default' => 65,
'min' => 0,
'max' => 100,
'sanitize' => fn( $v ) => max( 0, min( 100, absint( $v ) ) ),
),
'box_bg_color' => array(
'label' => __( 'Popup Box Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the popup box itself.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'box_padding' => array(
'label' => __( 'Popup Box Padding (px)', 'ad-fuz' ),
'hint' => __( 'Padding inside the popup box.', 'ad-fuz' ),
'type' => 'number',
'default' => 20,
'min' => 0,
'max' => 100,
'sanitize' => fn( $v ) => max( 0, min( 100, absint( $v ) ) ),
),
'box_radius' => array(
'label' => __( 'Popup Box Border Radius (px)', 'ad-fuz' ),
'hint' => __( 'Rounded corners for the popup box.', 'ad-fuz' ),
'type' => 'number',
'default' => 12,
'min' => 0,
'max' => 50,
'sanitize' => fn( $v ) => max( 0, min( 50, absint( $v ) ) ),
),
'box_width' => array(
'label' => __( 'Popup Box Width (px)', 'ad-fuz' ),
'hint' => __( 'Width of the popup box in pixels.', 'ad-fuz' ),
'type' => 'number',
'default' => 600,
'min' => 300,
'max' => 1200,
'sanitize' => fn( $v ) => max( 300, min( 1200, absint( $v ) ) ),
),
'box_max_width' => array(
'label' => __( 'Popup Box Max Width (vw)', 'ad-fuz' ),
'hint' => __( 'Maximum width of the popup box as a percentage of viewport width.', 'ad-fuz' ),
'type' => 'number',
'default' => 90,
'min' => 50,
'max' => 100,
'sanitize' => fn( $v ) => max( 50, min( 100, absint( $v ) ) ),
),
'title_color' => array(
'label' => __( 'Title Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad title text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#000000',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#000000',
),
'desc_color' => array(
'label' => __( 'Description Font Color', 'ad-fuz' ),
'hint' => __( 'Color of the ad description text inside the popup.', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'cta_color' => array(
'label' => __( 'CTA Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#2271b1',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#2271b1',
),
'cta_text_color' => array(
'label' => __( 'CTA Button Text Color', 'ad-fuz' ),
'hint' => __( 'Text color of the CTA button.', 'ad-fuz' ),
'type' => 'color',
'default' => '#ffffff',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#ffffff',
),
'close_color' => array(
'label' => __( 'Close Button Color', 'ad-fuz' ),
'hint' => __( 'Color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => '#666666',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: '#666666',
),
'close_bg_color' => array(
'label' => __( 'Close Button Background Color', 'ad-fuz' ),
'hint' => __( 'Background color of the close button (X).', 'ad-fuz' ),
'type' => 'color',
'default' => 'transparent',
'sanitize' => fn( $v ) => sanitize_hex_color( $v ) ?: 'transparent',
),
),
),
// ─────────────────────────────────────────────
// EDGE BAR
// ─────────────────────────────────────────────
'edge_bar' => array(
'name' => 'Edge Bar',
'description' => 'A fixed bar anchored to any edge of the screen.',
'status' => 'active',
'placement_type' => 'global',
'max_spaces' => 4,
'positions' => array(
'top' => 'Top',
'bottom' => 'Bottom',
'left' => 'Left',
'right' => 'Right',
),
// 'conversion_note' => __(
// 'For horizontal bars (Top/Bottom) use a 1200×90 px strip or a standard 728×90 px Leaderboard centred inside it. '
// . 'For vertical bars (Left/Right) use a 120×600 px Wide Skyscraper. '
// . 'Keep messaging brief — 5–8 words + one CTA button. '
// . 'Enabling the Hide/Show toggle significantly reduces user annoyance and lowers bounce rate.',
// 'ad-fuz'
// ),
'settings' => array(
'show_toggle' => array(
'label' => __( 'Enable Hide/Show Button', 'ad-fuz' ),
'hint' => __( 'Show a button so visitors can hide or reveal the bar.', 'ad-fuz' ),
'type' => 'toggle',
'default' => '1',
'sanitize' => fn( $v ) => $v ? 1 : 0,
),
'toggle_hide_text' => array(
'label' => __( 'Hide Button Text', 'ad-fuz' ),
'hint' => __( 'Text on the button that hides the bar.', 'ad-fuz' ),
'type' => 'text',
'default' => 'Hide',
'sanitize' => fn( $v ) => sanitize_text_field( $v ) ?: 'Hide',
),
'toggle_show_text' => array(
'label' => __( 'Show Tab Text', 'ad-fuz' ),
'hint' => __( 'Text on the peek tab that brings the bar back.', 'ad-fuz' ),
'type' => 'text',
'default' => 'Show Ad',
'sanitize' => fn( $v ) => sanitize_text_field( $v ) ?: 'Show Ad',
),
'toggle_align' => array(
'label' => __( 'Button Alignment', 'ad-fuz' ),
'hint' => __(
'Where along the bar the hide/show button sits. For horizontal bars (top/bottom) this is left/center/right. For vertical bars (left/right) this is top/center/bottom.',
'ad-fuz'
),
'type' => 'select',
'default' => 'flex-end',
'options' => array(
'flex-start' => __( 'Start', 'ad-fuz' ),
'center' => __( 'Center', 'ad-fuz' ),
'flex-end' => __( 'End', 'ad-fuz' ),
),
'sanitize' => fn( $v ) => in_array( $v, array( 'flex-start', 'center', 'flex-end' ), true ) ? $v : 'flex-end',
),
'toggle_side' => array(
'label' => __( 'Button Side', 'ad-fuz' ),
'hint' => __(
'Which side of the bar the button appears on "Inner" places it adjacent to the ad content (always visible) "Outer" places it on the screen-edge side — note this pushes the button partially off-screen on bottom and right bars.',
'ad-fuz'
),
'type' => 'select',
'default' => 'inner',
'options' => array(
'inner' => __( 'Inner (content side)', 'ad-fuz' ),
'outer' => __( 'Outer (screen-edge side)', 'ad-fuz' ),
),
'sanitize' => fn( $v ) => in_array( $v, array( 'inner', 'outer' ), true ) ? $v : 'inner',
),
),
),
'global' => array(
'name' => 'Global',
'description' => 'Ad that will be placed in the Global spaces.',
'status' => 'active',
'placement_type' => 'positional',
'max_spaces' => null,
),
);
$ad_formats = apply_filters( 'adfuz/ads/ad_format/formats', $ad_formats );
if ( $ad_format_id ) {
return $ad_formats[ $ad_format_id ]['name'] ?? '';
}
return array_filter(
$ad_formats,
function ( $format ) {
return ( 'active' === $format['status'] );
}
);
}
public static function active_positional_ad_format() {
return array_filter(
self::ad_format(),
function ( $format ) {
return ( 'positional' === $format['placement_type'] );
}
);
}
public static function active_global_ad_format() {
return array_filter(
self::ad_format(),
function ( $format ) {
return ( 'global' === $format['placement_type'] );
}
);
}
public static function is_global_format( $ad_format_id ): bool {
$format = self::ad_format( $ad_format_id );
return ( $format['placement_type'] ?? 'positional' ) === 'global';
}
// Global formats are never shown in Ad Space listings
public static function get_positional_formats(): array {
return array_filter( self::ad_format(), fn( $f ) => $f['placement_type'] === 'positional' );
}
public static function get_global_formats(): array {
return array_filter( self::ad_format(), fn( $f ) => $f['placement_type'] === 'global' );
}
/**
* Output an icon (default: “info” Dashicon) that shows a tooltip.
*
* @param string $tooltip Tooltip text or HTML. Required.
* @param array|string $args Optional settings **or** a shortcut label string.
* If you pass a string here it becomes the visible label.
* For array options see below.
*
* Array options (all optional):
* - label (string) Visible text next to the icon. Default '' (icon-only).
* - icon (string) SVG filename in /assets/icons/ (no “.svg”) **or** raw HTML.
* Default uses Dashicon info.
* - href (string) If set: output . Otherwise