Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
forbidals
/
wp-content
/
plugins
/
pixel-caffeine
/
includes
/
admin
:
class-aepc-admin-ca.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * CRUD class for custom audience record * * @class AEPC_Admin_CA */ class AEPC_Admin_CA { /** @var array */ protected $_data = array( 'ID' => 0, 'fb_id' => 0, 'date' => '', 'date_gmt' => '', 'modified_date' => '', 'modified_date_gmt' => '', 'name' => '', 'description' => '', 'prefill' => true, 'retention' => 14, 'rule' => array(), 'approximate_count' => -1 ); /** @var array Save here if some error occurred per each field */ protected $errors = array(); /** @var bool Flag indicates if CA exists or not */ protected $exists = false; /** @var array Save the available translations to go speedy */ private static $translations = array(); /** * AEPC_Admin_CA constructor. * * Initialize the instance in base of ID. If ID is zero, it preparse the instance for a new CA to save * * @param int $id */ public function __construct( $id = 0 ) { if ( ! empty( $id ) ) { $this->populate( $id ); } } /** * Populate the data from DB * * @param $id */ public function populate( $id ) { if ( empty( $id ) || ! ( $ca_object = $this->read( $id ) ) ) { return; } $this->_data = $ca_object; $this->exists = true; } /** * Populate the data from DB by getting the record by Facebook ID, instead of record ID * * @param $fb_id */ public function populate_by_fb_id( $fb_id ) { if ( empty( $fb_id ) ) { return; } global $wpdb; if ( $ca = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}aepc_custom_audiences WHERE fb_id = %d", absint( $fb_id ) ), ARRAY_A ) ) { $this->_data = array_map( 'maybe_unserialize', $ca ); $this->exists = true; } } /** * Retrieve the record from DB * * @param $id * * @return array|null|object|void */ public function read( $id ) { global $wpdb; $ca = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}aepc_custom_audiences WHERE ID = %d", $id ), ARRAY_A ); return is_array( $ca ) ? array_map( 'maybe_unserialize', $ca ) : $ca; } /** * Create the record in DB * * @param array $args * * @return bool|int */ public function create( $args = array() ) { $args = array_intersect_key( $args, $this->_data ); $data = wp_parse_args( $args, $this->_data ); if ( $this->exists() ) { return false; } // Fields validation $data = $this->validate_fields( $data ); // Save in Facebook Ad account if ( ! AEPC_Admin::$api->is_debug() ) { $res = AEPC_Admin::$api->create_audience( $data ); // Add Facebook ID in arguments $data['fb_id'] = isset( $res->id ) ? $res->id : 0; } // Sanitize values for database $this->_data = $data; foreach ( $data as $key => &$val ) { if ( is_array( $val ) ) { $val = serialize( $val ); } } // Save the values global $wpdb; // Add datatime $data['date'] = $data['modified_date']; $data['date_gmt'] = $data['modified_date_gmt']; $wpdb->insert( $wpdb->prefix . 'aepc_custom_audiences', $data ); $this->set_id( $wpdb->insert_id ); $this->exists = true; return $this->get_id(); } /** * Update a record in DB. Must be defined an ID, to select what record you have to edit * * @param array $args * * @return bool|int */ public function update( $args = array() ) { if ( ! $this->exists() ) { return false; } $original_values = $this->_data; $args = array_intersect_key( $args, $this->_data ); $to_update = wp_parse_args( $args, $this->_data ); if ( empty( $this->_data['ID'] ) || ! ( $ca_object = $this->read( $this->_data['ID'] ) ) ) { return false; } // Fields validation $to_update = $this->validate_fields( $to_update ); $this->_data = $to_update; // Save in Facebook Ad account if ( ! AEPC_Admin::$api->is_debug() ) { AEPC_Admin::$api->update_audience( $this->get_facebook_id(), $to_update ); } // Sanitize values for database foreach ( $to_update as $key => &$val ) { if ( is_array( $val ) ) { $val = serialize( $val ); } if ( $val === $original_values[ $key ] ) { unset( $val ); } } // Do not update if all values are unchanged if ( empty( $to_update ) ) { return false; } // Save the values global $wpdb; $wpdb->update( $wpdb->prefix . 'aepc_custom_audiences', $to_update, array( 'ID' => $this->get_id() ) ); return true; } /** * Refresh the size of audience, getting it from Facebook API */ public function refresh_size() { $ca = AEPC_Admin::$api->get_audience( $this->get_facebook_id(), 'approximate_count' ); $this->update( array( 'approximate_count' => intval( $ca->approximate_count ) ) ); } /** * Refresh the data audience, getting it from Facebook API */ public function refresh_facebook_data() { $ca = AEPC_Admin::$api->get_audience( $this->get_facebook_id() ); $this->update( array( 'name' => $ca->name, 'description' => $ca->description, 'approximate_count' => intval( $ca->approximate_count ) ) ); } /** * Fields validation, useful for create and update method * * @throws Exception */ protected function validate_fields( $args = array() ) { $this->reset_errors(); $args = wp_parse_args( $args, $this->_data ); if ( empty( $args['name'] ) ) { AEPC_Admin_Notices::add_notice( 'error', 'ca_name', __( 'The name for the cluster is required.', 'pixel-caffeine' ) ); } if ( empty( $args['rule'] ) ) { AEPC_Admin_Notices::add_notice( 'error', 'ca_include_url', __( 'You have to define one of included or excluded URL.', 'pixel-caffeine' ) ); AEPC_Admin_Notices::add_notice( 'error', 'ca_exclude_url', __( 'You have to define one of included or excluded URL.', 'pixel-caffeine' ) ); AEPC_Admin_Notices::add_notice( 'error', 'ca_rule', __( 'A custom audience from a website must contain at least one audience rule.', 'pixel-caffeine' ) ); } if ( empty( $args['retention'] ) ) { AEPC_Admin_Notices::add_notice( 'error', 'ca_retention', __( 'You have to define the number of days to keep the user in this cluster.', 'pixel-caffeine' ) ); } $args['retention'] = intval( $args['retention'] ); $args['modified_date'] = current_time( 'mysql', false ); $args['modified_date_gmt'] = current_time( 'mysql', true ); $args['approximate_count'] = intval( $args['approximate_count'] ); if ( $args['retention'] < 1 || $args['retention'] > 180 ) { AEPC_Admin_Notices::add_notice( 'error', 'ca_retention', __( 'The retention value must be beetwen 1 and 180 days value.', 'pixel-caffeine' ) ); } // Remove the prefill field, because it's useful only for facebook request and it's useless for future unset( $args['prefill'] ); // Throw exception if error if ( $this->have_errors() ) { throw new Exception( __( '<strong>Cannot save custom audience</strong> Please, check fields errors below.', 'pixel-caffeine' ) ); } return $args; } /** * Update a record in DB. Must be defined an ID, to select what record you have to edit * * @return bool|int */ public function delete() { if ( ! $this->exists() ) { return false; } // Save in Facebook Ad account if ( ! AEPC_Admin::$api->is_debug() ) { AEPC_Admin::$api->delete_audience( $this->get_facebook_id() ); } // Save the values global $wpdb; $wpdb->delete( $wpdb->prefix . 'aepc_custom_audiences', array( 'ID' => $this->get_id() ) ); $this->exists = false; return true; } /** * Create an identical CA in a new record with a new ID * * @param bool|string $name * * @return AEPC_Admin_CA */ public function duplicate( $name = false ) { $new = clone $this; $new->set_id( 0 ); $new->exists = false; // Change name if defined if ( false !== $name ) { $new->set_name( $name ); } $new->create(); return $new; } /** * Check if the CA exists */ public function exists() { return (bool) $this->exists; } /** * Get the ID of record of this instance * * @return int */ public function get_id() { return absint( $this->_data['ID'] ); } /** * Set the ID of record of this instance and also populate data by ID * * @param int $id * * @return int */ public function set_id( $id ) { $this->_data['ID'] = $id; $this->populate( $id ); } /** * Get the Facebook ID for this CA * * @return string */ public function get_facebook_id() { return $this->_data['fb_id']; } /** * Set the Facebook ID for this CA * * @param string $fb_id * * @return string */ public function set_facebook_id( $fb_id ) { return $this->_data['fb_id'] = $fb_id; } /** * Get the date of record of this instance * * @param bool $gmt * * @return string */ public function get_date( $gmt = false ) { return $this->_data[ 'date' . ( $gmt ? '_gmt' : '' ) ]; } /** * Set the date of record of this instance * * @param string $date * * @return string */ public function set_date( $date ) { $this->_data['date'] = $date; $this->_data['date_gmt'] = gmdate( 'Y-m-d H:i:s', ( strtotime( $date ) - ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) ); } /** * Get the time for print * * @param string $what You can return a specific date with a specific format - 't_time' for only time - 'h_time' for human date * * @return string */ public function get_human_date( $what = '' ) { $t_time = mysql2date( get_option( 'date_format' ) . ' - ' . get_option( 'time_format' ), $this->get_date(), true ); $time = mysql2date( 'G', $this->get_date( true ) ); $time_diff = time() - $time; if ( $time_diff < MINUTE_IN_SECONDS ) { $h_time = __( 'Now', 'pixel-caffeine' ); } else { $h_time = sprintf( __( '%s ago', 'pixel-caffeine' ), human_time_diff( $time ) ); } if ( ! empty( $what ) && isset( ${$what} ) ) { return ${$what}; } return array( 't_time' => $t_time, 'h_time' => $h_time, ); } /** * Print out the human date * * @param string $what You can return a specific date with a specific format - 't_time' for only time - 'h_time' for human date */ public function human_date( $what = '' ) { echo $this->get_human_date( $what ); } /** * Get the modified_date of record of this instance * * @param bool $gmt * * @return string */ public function get_modified_date( $gmt = false ) { return $this->_data[ 'modified_date' . ( $gmt ? '_gmt' : '' ) ]; } /** * Set the modified_date of record of this instance * * @param string $modified_date * * @return string */ public function set_modified_date( $modified_date ) { $this->_data['modified_date'] = $modified_date; $this->_data['modified_date_gmt'] = gmdate( 'Y-m-d H:i:s', ( strtotime( $modified_date ) - ( get_option( 'gmt_offset' ) * HOUR_IN_SECONDS ) ) ); } /** * Get the name of record of this instance * * @return string */ public function get_name() { return $this->_data['name']; } /** * Set the name of record of this instance * * @param string $name * * @return string */ public function set_name( $name ) { $this->_data['name'] = $name; } /** * Get the description of record of this instance * * @return string */ public function get_description() { return $this->_data['description']; } /** * Set the ID of record of this instance * * @param string $description * * @return string */ public function set_description( $description ) { $this->_data['description'] = $description; } /** * Get if the custom audience must include website traffic recorded prior to the audience creation. * * @return bool */ public function get_prefill() { return (bool) $this->_data['prefill']; } /** * Set if the custom audience must include website traffic recorded prior to the audience creation. * * @param bool $prefill * * @return bool */ public function set_prefill( $prefill ) { $this->_data['prefill'] = $prefill; } /** * Get number of days to keep the user in this cluster. You can use any value between 1 and 180 days. * Defaults to 14 days if not specified. * * @return int */ public function get_retention() { return intval( $this->_data['retention'] ); } /** * Set number of days to keep the user in this cluster. You can use any value between 1 and 180 days. * * @param int $retention * * @return int */ public function set_retention( $retention ) { $this->_data['retention'] = $retention; } /** * Get Audience rules to be applied on the referrer URL. * * @param string $what You can have a specific rule, as "include_url" or "exclude_url" * * @return array */ public function get_rule( $what = '' ) { $rules = maybe_unserialize( $this->_data['rule'] ); if ( 'include_url' == $what ) { foreach ( $rules as $rule ) { if ( 'include' == $rule['main_condition'] && 'url' === $rule['event_type'] && isset( $rule['conditions'][0]['value'] ) ) { return $rule['conditions'][0]['value']; } } } elseif ( 'exclude_url' == $what ) { foreach ( $rules as $rule ) { if ( 'exclude' == $rule['main_condition'] && 'url' === $rule['event_type'] && isset( $rule['conditions'][0]['value'] ) ) { return ! empty( $rule['conditions'][0]['value'] ) ? $rule['conditions'][0]['value'] : ''; } } } else { return $rules; } return array(); } /** * Get the condition used for the URL field * * @param string $what You can have a specific rule, as "include_url" or "exclude_url" * * @return array */ public function get_url_condition( $what = '' ) { $rules = maybe_unserialize( $this->_data['rule'] ); if ( 'include_url' == $what ) { foreach ( $rules as $rule ) { if ( 'include' == $rule['main_condition'] && 'url' === $rule['event_type'] && isset( $rule['conditions'][0]['operator'] ) ) { return $rule['conditions'][0]['operator']; } } } elseif ( 'exclude_url' == $what ) { foreach ( $rules as $rule ) { if ( 'exclude' == $rule['main_condition'] && 'url' === $rule['event_type'] && isset( $rule['conditions'][0]['operator'] ) ) { return ! empty( $rule['conditions'][0]['operator'] ) ? $rule['conditions'][0]['operator'] : ''; } } } else { return $rules; } return array(); } /** * Get Audience rules to be applied on the referrer URL. * * @param array $rules * * @return array */ public function set_rule( array $rules ) { $this->_data['rule'] = $rules; } /** * Get the rule filters, excluding URL filter * * @param string $condition Could be 'include' or 'exclude' to check specifically for what rule we want to get * * @return array */ public function get_filters( $condition = '' ) { $filters = $this->get_rule(); // Exclude URL from filters foreach ( $filters as $k => $f ) { if ( 'url' === $f['event_type'] || ! empty( $condition ) && ( 'include' == $condition && 'exclude' == $f['main_condition'] || 'exclude' == $condition && 'include' == $f['main_condition'] ) ) { unset( $filters[ $k ] ); } } return array_values( $filters ); } /** * Check if there are some filters in CA * * @param string $condition Could be 'include' or 'exclude' to check specifically for what rule we want to check * * @return bool */ public function has_filters( $condition = '' ) { $filters = $this->get_filters(); // Check for specific condition if ( ! empty( $condition ) ) { foreach ( $filters as $filter ) { if ( 'include' === $condition && 'include' == $filter['main_condition'] || 'exclude' === $condition && 'exclude' == $filter['main_condition'] ) { return true; } } } else { return ! empty( $filters ); } return false; } /** * Get the size of audience * * @return int */ public function get_size() { return intval( $this->_data['approximate_count'] ); } /** * Translate the configuration array of a filter into a readable statement to print out on screen * * @param $rule * @param string $highlight_before * @param string $highlight_after * * @return string|void */ public function get_human_filter( $rule, $highlight_before = '[', $highlight_after = ']' ) { // Standard statements for the filter rows, they may be changed in some condition $translate_words = array( // Specific cases 'attributes' => array( 'login_status' => array( 'eq' => _x( 'is %2$s', '%2$s is the value', 'pixel-caffeine' ), 'neq' => _x( 'is not %2$s', '%2$s is the value', 'pixel-caffeine' ), ), 'referrer' => array( 'i_contains' => _x( 'come from %2$s', '%2$s is the value', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t come from %2$s', '%2$s is the value', 'pixel-caffeine' ), ), 'device_type' => array( 'i_contains' => _x( 'use %2$s', '%2$s is the value', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t use %2$s', '%2$s is the value', 'pixel-caffeine' ), 'eq' => _x( 'use %2$s', '%2$s is the value', 'pixel-caffeine' ), 'neq' => _x( 'don\'t use %2$s', '%2$s is the value', 'pixel-caffeine' ), ), ), 'blog' => array( 'categories' => array( 'i_contains' => _x( 'read posts from %2$s %1$s', '%1$s is the taxonomy and %2$s is the term of that taxonomy', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t read posts from %2$s %1$s', '%1$s is the taxonomy and %2$s is the term of that taxonomy', 'pixel-caffeine' ), ), 'tax_post_tag' => array( 'i_contains' => _x( 'read posts from %2$s %1$s', '%1$s is the taxonomy and %2$s is the term of that taxonomy', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t read posts from %2$s %1$s', '%1$s is the taxonomy and %2$s is the term of that taxonomy', 'pixel-caffeine' ), ), 'posts' => array( 'i_contains' => _x( 'read %2$s from %1$s', '%1$s is the post type or blog and %2$s should be "the post(s) <post title>" or "any post" if all', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t read %2$s from %1$s', '%1$s is the post type or blog and %2$s should be "the post(s) <post title>" or "any post" if all', 'pixel-caffeine' ), ), 'pages' => array( 'i_contains' => _x( 'visit %2$s %1$s', '%1$s is "page" or "pages" and %2$s is the page title', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t visit %2$s %1$s', '%1$s is "page" or "pages" and %2$s is the page title', 'pixel-caffeine' ), ), 'custom_fields' => array( 'i_contains' => _x( 'read a post contains %1$s %2$s', '%1$s is the custom field key and %2$s is the value. Complete statement: "read a post contains [field_key] custom field with [value] and [value2] as value"', 'pixel-caffeine' ), 'i_not_contains' => _x( 'don\'t read a post contains %1$s %2$s', '%1$s is the custom field key and %2$s is the value. Complete statement: "don\'t read a post contains [field_key] custom field with [value] and [value2] as value"', 'pixel-caffeine' ), ) ), 'ecommerce' => array( 'ViewContent' => array( 'generic' => __( 'visit a product page', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'visit %s product page', '%s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'visit %s product pages', '%s are the product titles', 'pixel-caffeine' ), ) ), 'Search' => array( 'generic' => _x( 'search', 'it is followed by "something" or a specific string searched', 'pixel-caffeine' ) ), 'AddToCart' => array( 'generic' => __( 'add to cart a product', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'add to cart %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'add to cart %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), 'AddToWishlist' => array( 'generic' => __( 'add to wishlist a product', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'add to wishlist %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'add to wishlist %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), 'InitiateCheckout' => array( 'generic' => __( 'enter the checkout flow', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'enter the checkout flow containing %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'enter the checkout flow containing %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), 'AddPaymentInfo' => array( 'generic' => __( 'add payment information in the checkout flow', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'add payment information in the checkout flow containing %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'add payment information in the checkout flow containing %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), 'Purchase' => array( 'generic' => __( 'make a purchase', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'purchase %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'purchase %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), 'Lead' => array( 'generic' => __( 'sign up for something', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'sign up for %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'sign up for %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), 'CompleteRegistration' => array( 'generic' => __( 'complete registration for a service', 'pixel-caffeine' ), 'specific' => array( 'singular' => _x( 'complete registration for %2$s product', '%2$s is the product title', 'pixel-caffeine' ), 'plural' => _x( 'complete registration for %2$s products', '%2$s are the product titles', 'pixel-caffeine' ), ) ), ), // Standard statements 'i_contains' => _x( '%1$s contains %2$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'i_not_contains' => _x( '%1$s not contains %2$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'eq' => _x( 'have set %2$s as %1$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'neq' => _x( 'have not set %2$s as %1$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'gte' => _x( '%1$s greater than or equal to %2$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'gt' => _x( '%1$s greater than %2$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'lte' => _x( '%1$s lower than or equal to %2$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), 'lt' => _x( '%1$s lower than %2$s', '%1$s is the parameter and %2$s is the value', 'pixel-caffeine' ), ); // Don't add any statement for URL filter if ( 'url' == $rule['event_type'] && 'url' == $rule['event'] ) { return ''; } $conditions = array(); $values_count = 0; $prepend = ''; // Force to add conditions key when it doesn't exist if ( ! isset( $rule['conditions'] ) ) { $rule['conditions'] = array(); } foreach ( $rule['conditions'] as $k => $condition ) { $statement = $parameter = $value = ''; // Remove condition if it's not allowed empty key and empty value if ( in_array( $rule['event_type'], array( 'attributes', 'blog' ) ) && ( isset( $condition['key'] ) && empty( $condition['key'] ) || empty( $condition['value'] ) ) ) { unset( $rule['conditions'][$k] ); continue; } // Define the value and parameters in specific cases if ( ! empty( $condition['value'] ) ) { $condition['value'] = array_map( 'trim', explode( ',', $condition['value'] ) ); // Save the count of values useful for parameter, to choose between singular and plural $values_count = count( $condition['value'] ); // Use this to set some text after and before the value, by replacing the value of variable with a localized string and %s for the value $value_wrapper = '%s'; // Sanitize all values foreach ( $condition['value'] as &$v ) { // Get language english name if ( 'attributes' == $rule['event_type'] && 'language' == $rule['event'] ) { if ( 'en-US' == $v ) { $v = __( 'English (American)', 'pixel-caffeine' ); } else { if ( empty( self::$translations ) ) { require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); self::$translations = wp_get_available_translations(); } foreach ( self::$translations as $translation ) { if ( $v == str_replace( '_', '-', $translation['language'] ) ) { $v = $translation['english_name']; } } } } // Get label of taxonomy elseif ( 'blog' == $rule['event_type'] && in_array( $rule['event'], array( 'categories', 'tax_post_tag' ) ) ) { if ( '[[any]]' === $v ) { $v = _x( 'any', 'Sentence like: "read posts from any category"', 'pixel-caffeine' ); } elseif ( $term = get_term_by( 'slug', $v, str_replace( 'tax_', '', ( ! empty( $condition['key'] ) ? $condition['key'] : $rule['event'] ) ) ) ) { $v = $term->name; } // Set now parameter if ( ! empty( $condition['key'] ) && 'tax_category' == $condition['key'] ) { $parameter = _n( __( 'category', 'pixel-caffeine' ), __( 'categories', 'pixel-caffeine' ), $values_count ); } elseif ( 'tax_post_tag' == $rule['event'] && 'tax_post_tag' == $condition['key'] ) { $parameter = _n( __( 'tag', 'pixel-caffeine' ), __( 'tags', 'pixel-caffeine' ), $values_count ); } elseif ( function_exists( 'WC' ) && 'tax_post_tag' == $rule['event'] && 'tax_product_tag' == $condition['key'] ) { $parameter = _n( __( 'product tag', 'pixel-caffeine' ), __( 'product tags', 'pixel-caffeine' ), $values_count ); } else { if ( '[[any]]' === $v ) { $v = __( 'any term', 'pixel-caffeine' ); } if ( $taxonomy = get_taxonomy( str_replace( 'tax_', '', $condition['key'] ) ) ) { $label = $taxonomy->label; } else { $label = str_replace( 'tax_', '', $condition['key'] ); } $parameter = sprintf( __( 'of %s custom taxonomy', 'pixel-caffeine' ), $highlight_before . $label . $highlight_after ); } } // Get post title elseif ( 'blog' == $rule['event_type'] && 'posts' == $rule['event'] ) { if ( '[[any]]' == $v ) { $v = __( 'any post', 'pixel-caffeine' ); } else { $value_wrapper = _n( 'the post %s', 'the posts %s', $values_count, 'pixel-caffeine' ); if ( $post_title = get_the_title( $v ) ) { $v = $post_title; } } // Set now parameter if ( 'post' == $condition['key'] ) { $parameter = 'blog'; } else { $key = _x( '%s post type', 'The complete statement is "read the posts [Post Title 1] and [Post Title 2] from [Post Type Name] post type"', 'pixel-caffeine' ); $post_type = get_post_type_object( $condition['key'] ); if ( $post_type ) { $post_type_labels = get_post_type_labels( $post_type ); $condition['key'] = $post_type_labels->singular_name; } $parameter = sprintf( $key, $highlight_before . ucfirst( $condition['key'] ) . $highlight_after ); } } // Get page title elseif ( 'blog' == $rule['event_type'] && 'pages' == $rule['event'] ) { if ( '[[any]]' == $v ) { $v = __( 'any', 'pixel-caffeine' ); } elseif ( ! in_array( $v, array( 'home', 'blog' ) ) ) { $v = get_the_title( $v ); } // Set now parameter $parameter = _n( __( 'page', 'pixel-caffeine' ), __( 'pages', 'pixel-caffeine' ), $values_count ); } // Exception for custom fields elseif ( 'blog' == $rule['event_type'] && 'custom_fields' == $rule['event'] ) { $value_wrapper = _n( 'with %s value', 'with %s values', $values_count, 'pixel-caffeine' ); if ( '[[any]]' == $v ) { $v = __( 'any', 'pixel-caffeine' ); } // Set now parameter if ( '[[any]]' == $condition['key'] ) { $parameter = __( 'the custom fields defined on \'Track Custom Fields Based Events\' option on General Settings tab', 'pixel-caffeine' ); } } // Exception search event elseif ( 'ecommerce' == $rule['event_type'] && 'Search' == $rule['event'] ) { if ( '[[any]]' == $v ) { $v = __( 'something', 'pixel-caffeine' ); } $statement = '%2$s'; } // Exception search event elseif ( 'ecommerce' == $rule['event_type'] ) { if ( '[[any]]' == $v ) { $v = __( 'any', 'pixel-caffeine' ); } // Replace IDs with product title, if a store plugin installed if ( 'content_ids' == $condition['key'] ) { foreach ( AEPC_Addons_Support::get_detected_addons() as $addon ) { if ( $addon->is_product_of_this_addon( intval( $v ) ) ) { $v = $addon->get_product_name( intval( $v ) ); } } } } // Translate underscores into spaces if ( empty( $condition['key'] ) || ! in_array( $condition['key'], array( 'content_type' ) ) ) { $v = str_replace( '_', ' ', $v ); } $v = ! empty( $v ) ? $highlight_before . $v . $highlight_after : ''; } // Format array list if ( 1 == $values_count ) { $value = $condition['value'][0]; } else { $last_condition = array_pop( $condition['value'] ); $value = implode( ', ', $condition['value'] ) . ' ' . __( 'or', 'pixel-caffeine' ) . ' ' . $last_condition; } // Wrap the value list with some text defined in some cases $value = sprintf( $value_wrapper, $value ); } // Define the parameter, for cases not covered above if ( empty( $parameter ) ) { if ( 'attributes' == $rule['event_type'] && 'language' == $rule['event'] ) { $parameter = __( 'browser language', 'pixel-caffeine' ); } elseif ( 'blog' == $rule['event_type'] && 'custom_fields' == $rule['event'] && '[[any]]' != $condition['key'] ) { $parameter = sprintf( __( '%s custom field', 'pixel-caffeine' ), $highlight_before . $condition['key'] . $highlight_after ); } elseif ( 'ecommerce' == $rule['event_type'] ) { $parameter = sprintf( __( '%s parameter', 'pixel-caffeine' ), $highlight_before . $condition['key'] . $highlight_after ); } elseif ( ! empty( $condition['key'] ) ) { $parameter = $condition['key']; } } // Set by default the statement to use for this row, it could be changed in some cases above if ( empty( $statement ) ) { if ( isset( $translate_words[ $rule['event_type'] ][ $rule['event'] ][ $condition['operator'] ] ) ) { $statement = ' ' . $translate_words[ $rule['event_type'] ][ $rule['event'] ][ $condition['operator'] ]; } elseif ( isset( $condition['key'] ) && 'content_ids' == $condition['key'] && isset( $translate_words[ $rule['event_type'] ][ $rule['event'] ]['specific'] ) ) { $statement = $translate_words[ $rule['event_type'] ][ $rule['event'] ]['specific']; if ( is_array( $statement ) ) { $statement = $statement[ $values_count <= 1 ? 'singular' : 'plural' ]; } $statement = ' ' . $statement; } else { $statement = ' ' . $translate_words[ $condition['operator'] ]; } } if ( empty( $value ) ) { $value = __( 'nothing', 'pixel-caffeine' ); } // Decide what statement use if ( ! empty( $condition['key'] ) && 'content_ids' == $condition['key'] ) { $prepend = sprintf( trim( $statement ), $parameter, $value ) . ' '; } else { $conditions[] = sprintf( trim( $statement ), $parameter, $value ); } } // Set some statement to prepend to above generated if ( empty( $prepend ) && isset( $translate_words[ $rule['event_type'] ][ $rule['event'] ]['generic'] ) ) { $prepend = $translate_words[ $rule['event_type'] ][ $rule['event'] ]['generic'] . ' '; } elseif ( 'events' == $rule['event_type'] ) { $prepend = sprintf('is tracked with the event [%s]', $rule['event']) . ' '; } // Add conditions if any if ( ! empty( $prepend ) && ! empty( $conditions ) && ! in_array( $rule['event'], array( 'Search' ) ) ) { $prepend .= __( 'with', 'pixel-caffeine' ) . ' '; } // Save final text if ( empty( $conditions ) ) { $final = ''; } elseif ( 1 == count( $conditions ) ) { $final = $conditions[0]; } else { $last_condition = array_pop( $conditions ); $final = implode( ', ', $conditions ) . ' ' . __( 'and', 'pixel-caffeine' ) . ' ' . $last_condition; } // Save final statement return trim( $prepend . $final ); } /** * Get a list of all rule formatted for human reading to print out on frontend * * @param string $highlight_before What put before the highlighted word * @param string $highlight_after What put after the highlighted word * * @return array */ public function get_human_rule_list( $highlight_before = '[', $highlight_after = ']' ) { $filters = $this->get_rule(); // Change each condition into text readable foreach ( $filters as $filter_id => &$rule ) { // Don't add any statement for URL filter if ( 'url' == $rule['event_type'] && 'url' == $rule['event'] ) { unset( $filters[ $filter_id ] ); continue; } // Save final statement $rule = $this->get_human_filter( $rule, $highlight_before, $highlight_after ); } return array_filter( $filters ); } /** * Set the size of audience * * @param int $size * * @return int */ public function set_size( $size ) { return $this->_data['approximate_count'] = intval( $size ); } /** * Add new filter to rules already existing with AND condition * * @param array $rule */ public function add_filter( array $rule ) { // Remove conditions with emptu value and key foreach ( $rule['conditions'] as $k => $condition ) { if ( isset( $condition['key'] ) && empty( $condition['key'] ) || ! isset( $condition['key'] ) && empty( $condition['value'] ) ) { unset( $rule['conditions'][ $k ] ); } } $this->set_rule( array_merge( $this->get_rule(), array( $rule ) ) ); } /** * Get error message if any * * @param $field * * @return bool|mixed */ public function get_error( $field ) { return AEPC_Admin_Notices::get_notices( 'error', 'ca_' . $field ); } /** * Return if the CA have some errors */ public function have_errors() { return AEPC_Admin_Notices::has_notice( 'error' ); } /** * Get all error messages * * @return array */ public function get_errors() { return AEPC_Admin_Notices::get_notices( 'error' ); } /** * Delete an error for a field * * @param $field */ public function remove_error( $field ) { AEPC_Admin_Notices::remove_notices( 'error', 'ca_' . $field ); if ( 'rule' == $field ) { AEPC_Admin_Notices::remove_notices( 'error', 'ca_include_url' ); AEPC_Admin_Notices::remove_notices( 'error', 'ca_exclude_url' ); } } /** * Reset all errors */ public function reset_errors() { AEPC_Admin_Notices::remove_notices( 'error' ); } }