first commit

This commit is contained in:
2024-11-10 21:08:49 +01:00
commit 0d932ce5ee
14455 changed files with 2567501 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class CustomEventFactory {
public static function create( $args ) {
// create event post object
$post_id = wp_insert_post( array(
'post_title' => empty( $args['title'] ) ? 'Untitled' : sanitize_text_field( $args['title'] ),
'post_type' => 'pys_event',
'post_status' => 'publish',
'ping_status' => 'closed',
'comment_status' => 'closed',
), true );
if ( is_wp_error( $post_id ) ) {
return false;
}
$event = new CustomEvent( $post_id );
$event->update( $args );
return $event;
}
/**
* @param string $state Event state. Can be 'any', 'active' or 'paused'
* @param null $post_id
*
* @return array
*/
public static function get( $state = 'any', $post_id = null ) {
$limit = isset( $post_id ) ? 1 : -1;
$args = array(
'post_type' => 'pys_event',
'numberposts' => $limit,
'meta_query' => array(
'relation' => 'AND'
)
);
if( isset( $post_id ) ) {
$args['include'] = (int) $post_id;
}
if ( $state !== 'any' ) {
$args['meta_query'][] = array(
'key' => '_pys_event_state',
'value' => $state
);
}
$results = array();
foreach ( get_posts( $args ) as $post ) {
$customEvent = new CustomEvent( $post->ID );
if ( $customEvent->getTriggerType() == 'page_visit' ) {
$results[ $post->ID ] = $customEvent;
}
}
return $results;
}
/**
* @param $post_id
*
* @return CustomEvent
*/
public static function getById( $post_id ) {
$results = self::get( 'any', $post_id );
if ( isset( $results[ $post_id ] ) ) {
return $results[ $post_id ];
} else {
return new CustomEvent();
}
}
public static function remove( $post_id ) {
wp_delete_post( $post_id, true );
}
public static function makeClone( $post_id ) {
if ( $event = self::getById( $post_id ) ) {
$args = array(
'title' => $event->getTitle() . ' (duplicate)',
);
// create new event
$new_event = self::create( $args );
if ( ! $new_event ) {
return;
}
// copy meta from original event
foreach ( get_post_meta( $event->getPostId() ) as $meta_key => $meta_values ) {
foreach ( $meta_values as $meta_value ) {
update_post_meta( $new_event->getPostId(), $meta_key, maybe_unserialize( $meta_value ) );
}
}
// disable cloned event
$new_event->disable();
}
}
}

View File

@@ -0,0 +1,737 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @property int post_id
* @property string title
* @property bool enabled
*
* @property int delay
* @property array triggers
* @property string trigger_type
*
* @property bool facebook_enabled
* @property string facebook_event_type
* @property string facebook_custom_event_type
* @property bool facebook_params_enabled
* @property array facebook_params
* @property array facebook_custom_params
*
* @property bool pinterest_enabled
* @property string pinterest_event_type
* @property string pinterest_custom_event_type
* @property bool pinterest_params_enabled
* @property array pinterest_custom_params
* @property array ga_custom_params
* @property array ga_params
*
* @property bool ga_enabled
* @property string ga_event_action
* @property string ga_custom_event_action
* @property string ga_event_category
* @property string ga_event_label
* @property string ga_event_value
* @property bool ga_non_interactive
*
* @property bool bing_enabled
* @property string bing_event_action
* @property string bing_event_category
* @property string bing_event_label
* @property string bing_event_value
*/
class CustomEvent {
private $post_id;
private $title = 'Untitled';
private $enabled = true;
public $GAEvents = array(
"" => array("CustomEvent"=>array()),
"All Properties" => array(
"earn_virtual_currency" => array("virtual_currency_name","value"),
"join_group" => array("group_id"),
"login" => array("method"),
"purchase" => array("transaction_id",'value','currency','tax','shipping','items','coupon'),
"refund" => array("transaction_id",'value','currency','tax','shipping','items'),
"search" => array("search_term"),
"select_content" => array("content_type",'item_id'),
"share" => array("content_type",'item_id'),
"sign_up" => array("method"),
"spend_virtual_currency" => array("item_name",'virtual_currency_name','value'),
"tutorial_begin" => array(),
"tutorial_complete" => array(),
),
"Retail/Ecommerce" => array(
'add_payment_info' => array('coupon','currency','items','payment_type','value'),
'add_shipping_info' => array('coupon','currency','items','shipping_tier','value'),
'add_to_cart' => array('currency', 'items', 'value'),
'add_to_wishlist' => array('currency', 'items', 'value'),
'begin_checkout' => array('coupon','currency', 'items', 'value'),
'generate_lead' => array('value', 'currency'),
'purchase' => array('affiliation', 'coupon', 'currency', 'items', 'transaction_id', 'shipping', 'tax', 'value'),
'refund' => array('affiliation', 'coupon', 'currency', 'items', 'transaction_id', 'shipping', 'tax', 'value'),
'remove_from_cart' => array('currency', 'items', 'value'),
'select_item' => array('items', 'item_list_name', 'item_list_id'),
'select_promotion' => array('items', 'promotion_id', 'promotion_name', 'creative_name', 'creative_slot', 'location_id'),
'view_cart' => array('currency', 'items', 'value'),
'view_item' => array('currency', 'items', 'value'),
'view_item_list' => array('items', 'item_list_name', 'item_list_id'),
'view_promotion' => array('items', 'promotion_id', 'promotion_name', 'creative_name', 'creative_slot', 'location_id')
),
"Jobs, Education, Local Deals, Real Estate" => array(
'add_payment_info' => array("coupon", 'currency', 'items', 'payment_type', 'value'),
'add_shipping_info' => array('coupon', 'currency', 'items', 'shipping_tier', 'value'),
'add_to_cart' => array('currency', 'items', 'value'),
'add_to_wishlist' => array('currency', 'items', 'value'),
'begin_checkout' => array('coupon','currency', 'items', 'value'),
'purchase' => array('affiliation', 'coupon', 'currency', 'items', 'transaction_id', 'shipping', 'tax', 'value'),
'refund' => array('affiliation', 'coupon', 'currency', 'items', 'transaction_id', 'shipping', 'tax', 'value'),
'remove_from_cart' => array('currency', 'items', 'value'),
'select_item' => array('items', 'item_list_name', 'item_list_id'),
'select_promotion' => array('items', 'promotion_id', 'promotion_name', 'creative_name', 'creative_slot', 'location_id'),
'view_cart' => array('currency', 'items', 'value'),
'view_item' => array('currency', 'items', 'value'),
'view_item_list' => array('items', 'item_list_name', 'item_list_id'),
'view_promotion' => array('items', 'promotion_id', 'promotion_name', 'creative_name', 'creative_slot', 'location_id')
),
"Travel (Hotel/Air)" => array(
'add_payment_info' => array("coupon", 'currency', 'items', 'payment_type', 'value'),
'add_shipping_info' => array('coupon', 'currency', 'items', 'shipping_tier', 'value'),
'add_to_cart' => array('currency', 'items', 'value'),
'add_to_wishlist' => array('currency', 'items', 'value'),
'begin_checkout' => array('coupon','currency', 'items', 'value'),
'generate_lead' => array('value', 'currency'),
'purchase' => array('affiliation', 'coupon', 'currency', 'items', 'transaction_id', 'shipping', 'tax', 'value'),
'refund' => array('affiliation', 'coupon', 'currency', 'items', 'transaction_id', 'shipping', 'tax', 'value'),
'remove_from_cart' => array('currency', 'items', 'value'),
'select_item' => array('items', 'item_list_name', 'item_list_id'),
'select_promotion' => array('items', 'promotion_id', 'promotion_name', 'creative_name', 'creative_slot', 'location_id'),
'view_cart' => array('currency', 'items', 'value'),
'view_item' => array('currency', 'items', 'value'),
'view_item_list' => array('items', 'item_list_name', 'item_list_id'),
'view_promotion' => array('items', 'promotion_id', 'promotion_name', 'creative_name', 'creative_slot', 'location_id')
),
"Games" => array(
'earn_virtual_currency' => array('virtual_currency_name', 'value'),
'join_group' => array('group_id'),
'level_end' => array('level_name', 'success'),
'level_start' => array('level_name'),
'level_up' => array('character', 'level'),
'post_score' => array('level', 'character', 'score'),
'select_content' => array('content_type', 'item_id'),
'spend_virtual_currency' => array('item_name', 'virtual_currency_name', 'value'),
'tutorial_begin' => array(),
'tutorial_complete' => array(),
'unlock_achievement' => array('achievement_id'),
)
);
private $data = array(
'delay' => null,
'trigger_type' => 'page_visit',
'triggers' => array(),
'facebook_enabled' => false,
'facebook_event_type' => 'ViewContent',
'facebook_custom_event_type' => null,
'facebook_params_enabled' => false,
'facebook_params' => array(),
'facebook_custom_params' => array(),
'pinterest_enabled' => false,
'pinterest_event_type' => 'ViewContent',
'pinterest_custom_event_type' => null,
'pinterest_params_enabled' => false,
'pinterest_custom_params' => array(),
'ga_enabled' => false,
'ga_event_action' => '_custom',
'ga_custom_event_action' => null,
'ga_event_category' => null,
'ga_event_label' => null,
'ga_event_value' => null,
'ga_non_interactive' => true,
//ver 4
'ga_params' => array(),
'ga_custom_params' => array(),
'ga_custom_params_enabled' => false,
'bing_enabled' => false,
'bing_event_action' => null,
'bing_event_category' => null,
'bing_event_label' => null,
'bing_event_value' => null,
);
public function __construct( $post_id = null ) {
$this->initialize( $post_id );
}
public function __get( $key ) {
if ( $key == 'post_id' ) {
return $this->post_id;
}
if ( $key == 'title' ) {
return $this->title;
}
if ( $key == 'enabled' ) {
return $this->enabled;
}
if ( isset( $this->data[ $key ] ) ) {
return $this->data[ $key ];
} else {
return null;
}
}
private function initialize( $post_id ) {
if ( $post_id ) {
$this->post_id = $post_id;
$this->title = get_the_title( $post_id );
$data = get_post_meta( $post_id, '_pys_event_data', true );
$this->data = is_array( $data ) ? $data : array();
$state = get_post_meta( $post_id, '_pys_event_state', true );
$this->enabled = $state == 'active' ? true : false;
if(count(GA()->getPixelIDs()) == 0) {
$this->data['ga_enabled'] = false;
$this->clearGa();
}
}
}
public function update( $args = null ) {
if ( ! is_array( $args ) ) {
$args = $this->data;
}
/**
* GENERAL
*/
// title
wp_update_post( array(
'ID' => $this->post_id,
'post_title' => empty( $args['title'] ) ? $this->title : sanitize_text_field( $args['title'] )
) );
// state
$state = isset( $args['enabled'] ) && $args['enabled'] ? 'active' : 'paused';
$this->enabled = $state == 'active' ? true : false;
update_post_meta( $this->post_id, '_pys_event_state', $state );
// trigger type
$this->data['trigger_type'] = 'page_visit';
// delay
$this->data['delay'] = isset( $args['delay'] ) && $args['delay'] ? (int) $args['delay'] : null;
/**
* TRIGGERS
*/
// reset old triggers
$this->data['triggers'] = array();
// page visit triggers
if ( $this->trigger_type == 'page_visit' && isset( $args['page_visit_triggers'] )
&& is_array( $args['page_visit_triggers'] ) ) {
foreach ( $args['page_visit_triggers'] as $trigger ) {
if ( ! empty( $trigger['value'] ) ) {
$this->data['triggers'][] = array(
'rule' => $trigger['rule'] == 'contains' ? 'contains' : 'match',
'value' => $trigger['value'],
);
}
}
}
// reset old url filters
$this->data['url_filters'] = array();
/**
* FACEBOOK
*/
$facebook_event_types = array(
'ViewContent',
'AddToCart',
'AddToWishlist',
'InitiateCheckout',
'AddPaymentInfo',
'Purchase',
'Lead',
'CompleteRegistration',
'Subscribe',
'CustomizeProduct',
'FindLocation',
'StartTrial',
'SubmitApplication',
'Schedule',
'Contact',
'Donate',
'CustomEvent'
);
// enabled
$this->data['facebook_enabled'] = isset( $args['facebook_enabled'] ) && $args['facebook_enabled'] ? true : false;
// event type
$this->data['facebook_event_type'] = isset( $args['facebook_event_type'] ) && in_array( $args['facebook_event_type'], $facebook_event_types )
? sanitize_text_field( $args['facebook_event_type'] )
: 'ViewContent';
// custom event type
$this->data['facebook_custom_event_type'] = $this->facebook_event_type == 'CustomEvent' && ! empty( $args['facebook_custom_event_type'] )
? sanitizeKey( $args['facebook_custom_event_type'] )
: null;
// params enabled
$this->data['facebook_params_enabled'] = isset( $args['facebook_params_enabled'] ) && $args['facebook_params_enabled'] ? true : false;
// params
if ( $this->facebook_params_enabled && isset( $args['facebook_params'] ) && $this->facebook_event_type !== 'CustomEvent' ) {
$this->data['facebook_params'] = array(
'value' => ! empty( $args['facebook_params']['value'] ) ? sanitize_text_field( $args['facebook_params']['value'] ) : null,
'currency' => ! empty( $args['facebook_params']['currency'] ) ? sanitize_text_field( $args['facebook_params']['currency'] ) : null,
'content_name' => ! empty( $args['facebook_params']['content_name'] ) ? sanitize_text_field( $args['facebook_params']['content_name'] ) : null,
'content_ids' => ! empty( $args['facebook_params']['content_ids'] ) ? sanitize_text_field( $args['facebook_params']['content_ids'] ) : null,
'content_type' => ! empty( $args['facebook_params']['content_type'] ) ? sanitize_text_field( $args['facebook_params']['content_type'] ) : null,
'content_category' => ! empty( $args['facebook_params']['content_category'] ) ? sanitize_text_field( $args['facebook_params']['content_category'] ) : null,
'num_items' => ! empty( $args['facebook_params']['num_items'] ) ? (int) $args['facebook_params']['num_items'] : null,
'order_id' => ! empty( $args['facebook_params']['order_id'] ) ? sanitize_text_field( $args['facebook_params']['order_id'] ) : null,
'search_string' => ! empty( $args['facebook_params']['search_string'] ) ? sanitize_text_field( $args['facebook_params']['search_string'] ) : null,
'status' => ! empty( $args['facebook_params']['status'] ) ? sanitize_text_field( $args['facebook_params']['status'] ) : null,
'predicted_ltv' => ! empty( $args['facebook_params']['predicted_ltv'] ) ? sanitize_text_field( $args['facebook_params']['predicted_ltv'] ) : null,
);
// custom currency
if ( $this->data['facebook_params']['currency'] == 'custom' && ! empty( $args['facebook_params']['custom_currency'] )) {
$this->data['facebook_params']['custom_currency'] = sanitize_text_field( $args['facebook_params']['custom_currency'] );
} else {
$this->data['facebook_params']['custom_currency'] = null;
}
} else {
$this->data['facebook_params'] = array(
'value' => null,
'currency' => null,
'custom_currency' => null,
'content_name' => null,
'content_ids' => null,
'content_type' => null,
'content_category' => null,
'num_items' => null,
'order_id' => null,
'search_string' => null,
'status' => null,
'predicted_ltv' => null,
);
}
// reset old custom params
$this->data['facebook_custom_params'] = array();
// custom params
if ( $this->facebook_params_enabled && isset( $args['facebook_custom_params'] ) ) {
foreach ( $args['facebook_custom_params'] as $custom_param ) {
if ( ! empty( $custom_param['name'] ) && ! empty( $custom_param['value'] ) ) {
$this->data['facebook_custom_params'][] = array(
'name' => sanitize_text_field( $custom_param['name'] ),
'value' => sanitize_text_field( $custom_param['value'] ),
);
}
}
}
/**
* PINTEREST
*/
$pinterest_event_types = array(
'pagevisit',
'viewcategory',
'search',
'addtocart',
'checkout',
'watchvideo',
'signup',
'lead',
'custom',
'CustomEvent',
);
// enabled
$this->data['pinterest_enabled'] = isset( $args['pinterest_enabled'] ) && $args['pinterest_enabled'] ? true
: false;
// event type
$this->data['pinterest_event_type'] = isset( $args['pinterest_event_type'] ) && in_array( $args['pinterest_event_type'],
$pinterest_event_types )
? sanitize_text_field( $args['pinterest_event_type'] )
: 'pagevisit';
// custom event type
$this->data['pinterest_custom_event_type'] = $this->pinterest_event_type == 'CustomEvent' && ! empty( $args['pinterest_custom_event_type'] )
? sanitizeKey( $args['pinterest_custom_event_type'] )
: null;
// params enabled
$this->data['pinterest_params_enabled'] = isset( $args['pinterest_params_enabled'] ) && $args['pinterest_params_enabled']
? true : false;
// reset old custom params
$this->data['pinterest_custom_params'] = array();
// custom params
if ( $this->pinterest_params_enabled && isset( $args['pinterest_custom_params'] ) ) {
foreach ( $args['pinterest_custom_params'] as $custom_param ) {
if ( ! empty( $custom_param['name'] ) && ! empty( $custom_param['value'] ) ) {
$this->data['pinterest_custom_params'][] = array(
'name' => sanitize_text_field( $custom_param['name'] ),
'value' => sanitize_text_field( $custom_param['value'] ),
);
}
}
}
/**
* GOOGLE ANALYTICS
*/
$this->updateGA($args);
/**
* BING
*/
$this->data['bing_enabled'] = isset($args['bing_enabled']) && $args['bing_enabled'] ? true : false;
$this->data['bing_event_action'] = !empty($args['bing_event_action']) ? sanitize_text_field($args['bing_event_action']) : null;
$this->data['bing_event_category'] = !empty($args['bing_event_category']) ? sanitize_text_field($args['bing_event_category']) : null;
$this->data['bing_event_label'] = !empty($args['bing_event_label']) ? sanitize_text_field($args['bing_event_label']) : null;
$this->data['bing_event_value'] = !empty($args['bing_event_value']) ? sanitize_text_field($args['bing_event_value']) : null;
update_post_meta( $this->post_id, '_pys_event_data', $this->data );
}
public function enable() {
$this->enabled = true;
update_post_meta( $this->post_id, '_pys_event_state', 'active' );
}
public function disable() {
$this->enabled = false;
update_post_meta( $this->post_id, '_pys_event_state', 'paused' );
}
/**
* @return int
*/
public function getPostId() {
return $this->post_id;
}
/**
* @return string
*/
public function getTitle() {
return $this->title;
}
public function isEnabled() {
return $this->enabled;
}
public function getTriggerType() {
return $this->trigger_type;
}
public function getDelay() {
return $this->delay;
}
/**
* @return array
*/
public function getPageVisitTriggers() {
return $this->trigger_type == 'page_visit' ? $this->triggers : array();
}
public function isFacebookEnabled() {
return (bool) $this->facebook_enabled;
}
public function getFacebookEventType() {
return $this->facebook_event_type == 'CustomEvent' ? $this->facebook_custom_event_type : $this->facebook_event_type;
}
public function isFacebookParamsEnabled() {
return (bool) $this->facebook_params_enabled;
}
public function getFacebookParam( $key ) {
return isset( $this->facebook_params[ $key ] ) ? $this->facebook_params[ $key ] : null;
}
public function getFacebookParams() {
return $this->facebook_params_enabled ? $this->facebook_params : array();
}
public function getFacebookCustomParams() {
return $this->facebook_params_enabled ? $this->facebook_custom_params : array();
}
public function isPinterestEnabled() {
return (bool) $this->pinterest_enabled;
}
public function getPinterestEventType() {
return $this->pinterest_event_type == 'CustomEvent'
? $this->pinterest_custom_event_type
: $this->pinterest_event_type;
}
public function isPinterestParamsEnabled() {
return (bool) $this->pinterest_params_enabled;
}
public function getPinterestCustomParams() {
return $this->pinterest_params_enabled ? $this->pinterest_custom_params : array();
}
public function isGoogleAnalyticsEnabled() {
return (bool) $this->ga_enabled;
}
public function getGoogleAnalyticsAction() {
return $this->ga_event_action == '_custom' ||
$this->ga_event_action == 'CustomEvent' ? $this->ga_custom_event_action : $this->ga_event_action;
}
public function isBingEnabled() {
return (bool) $this->bing_enabled;
}
public function isGaV4() {
$all = GA()->getPixelIDs();
if(count($all) == 0) {
return false;
}
return strpos($all[0], 'G') === 0;
}
private function clearGa() {
$this->data['ga_params'] = array();
$this->data['ga_custom_params'] = array();
$this->data['ga_event_action'] = 'CustomEvent';
$this->data['ga_custom_event_action']=null;
$this->data['ga_non_interactive'] = false;
// old
$this->data['ga_event_category'] = null;
$this->data['ga_event_label'] = null;
$this->data['ga_event_value'] = null;
}
private function updateGA( $args) {
$all = GA()->getPixelIDs();
$this->data['ga_enabled'] = count($all) > 0
&& isset( $args['ga_enabled'] )
&& $args['ga_enabled'];
if(!$this->data['ga_enabled']) {
$this->clearGa();
} else {
if($this->isGaV4()) {
$this->data['ga_event_action'] = isset( $args['ga_event_action'] )
? sanitize_text_field( $args['ga_event_action'] )
: 'view_item';
$this->data['ga_custom_event_action'] = $this->ga_event_action == '_custom' || $this->ga_event_action == 'CustomEvent' && !empty( $args['ga_custom_event_action'] )
? sanitizeKey( $args['ga_custom_event_action'] )
: null;
$this->data['ga_params'] = array();
foreach ($this->GAEvents as $group) {
foreach ($group as $name => $fields) {
if($name == $this->data['ga_event_action']) {
foreach ($fields as $field) {
$this->data['ga_params'][$field] = isset($args['ga_params'][$field]) ? $args['ga_params'][$field] : "";
}
break;
}
}
}
if ( isset( $args['ga_params'] ) ) {
foreach ($args['ga_params'] as $key => $val) {
$this->data['ga_params'][$key] = sanitize_text_field( $val );
}
}
// reset old custom params
$this->data['ga_custom_params'] = array();
// custom params
if ( isset( $args['ga_custom_params'] ) ) {
foreach ( $args['ga_custom_params'] as $custom_param ) {
if ( ! empty( $custom_param['name'] ) && ! empty( $custom_param['value'] ) ) {
$this->data['ga_custom_params'][] = array(
'name' => sanitize_text_field( $custom_param['name'] ),
'value' => sanitize_text_field( $custom_param['value'] ),
);
}
}
}
$this->data['ga_non_interactive'] = isset( $args['ga_non_interactive'] ) && $args['ga_non_interactive'] ? true : false;
} else {
$ga_event_actions = array(
'_custom',
'add_payment_info',
'add_to_cart',
'add_to_wishlist',
'begin_checkout',
'checkout_progress',
'generate_lead',
'login',
'purchase',
'refund',
'remove_from_cart',
'search',
'select_content',
'set_checkout_option',
'share',
'sign_up',
'view_item',
'view_item_list',
'view_promotion',
'view_search_results',
);
// event action
$this->data['ga_event_action'] = isset( $args['ga_event_action'] ) && in_array( $args['ga_event_action'], $ga_event_actions )
? sanitize_text_field( $args['ga_event_action'] )
: 'view_item';
// custom event type
$this->data['ga_custom_event_action'] = $this->ga_event_action == '_custom' && !empty( $args['ga_custom_event_action'] )
? sanitizeKey( $args['ga_custom_event_action'] )
: null;
$this->data['ga_event_category'] = ! empty( $args['ga_event_category'] ) ? sanitize_text_field( $args['ga_event_category'] ) : null;
$this->data['ga_event_label'] = ! empty( $args['ga_event_label'] ) ? sanitize_text_field( $args['ga_event_label'] ) : null;
$this->data['ga_event_value'] = ! empty( $args['ga_event_value'] ) ? sanitize_text_field( $args['ga_event_value'] ) : null;
$this->data['ga_non_interactive'] = isset( $args['ga_non_interactive'] ) && $args['ga_non_interactive'] ? true : false;
}
}
}
public function getGACustomParams() {
if($this->isGaV4()) {
if(is_array($this->ga_custom_params)) {
return $this->ga_custom_params;
}
return [];
}
$custom = array();
if($this->ga_event_category) {
$custom[] = array('name'=>"event_category",'value' => $this->ga_event_category);
}
if($this->ga_event_value){
$custom[] = array('name'=>"value",'value' => $this->ga_event_value);
}
if($this->ga_event_label){
$custom[] = array('name'=>"event_label",'value' => $this->ga_event_label);
}
return $custom;
}
public function getGaParams() {
if($this->isGaV4())
if(is_array($this->ga_params)) {
return $this->ga_params;
} else {
return [];
}
$list = array();
foreach ($this->GAEvents as $group) {
foreach ($group as $name => $fields) {
if($name == $this->data['ga_event_action']) {
foreach ($fields as $field) {
$list[$field] = "";
}
}
}
}
return $list;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace PixelYourSite;
final class EventIdGenerator {
public static function guidv4() {
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
}

View File

@@ -0,0 +1,238 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class AjaxHookEventManager {
public static $DIV_ID_FOR_AJAX_EVENTS = "pys_ajax_events";
private static $_instance;
static function addPendingEvent($name,$event) {
$events = WC()->session->get( 'pys_events', array() );
$events[$name] = $event;
WC()->session->set( 'pys_events', $events );
}
/**
* @param $name
* @param $slug
* @return mixed|null
*/
static function getPendingEvent($name,$unset) {
if ( function_exists( 'WC' ) ) {
if(!WC()->session) return null;
$session_data = WC()->session->get_session_data();
$events = isset( $session_data['pys_events'] ) ? WC()->session->get( 'pys_events', array() ) : array();
PYS()->getLog()->debug('events hook called', $events);
if (isset($events[$name])) {
$event = $events[$name];
if ($unset) {
unset($events[$name]);
WC()->session->set('pys_events', $events);
}
return $event;
}
return null;
}
return null;
}
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
}
public function addHooks() {
if(EventsWoo()->isEnabled()) {
// use for fb server only because ajax request cause bugs in woo
if ( PYS()->getOption('woo_add_to_cart_on_button_click')
&& isEventEnabled('woo_add_to_cart_enabled')
)
{
add_action( 'woocommerce_after_add_to_cart_button', 'PixelYourSite\EventsManager::setupWooSingleProductData' );
if(PYS()->getOption('woo_add_to_cart_catch_method') == "add_cart_hook") {
add_action( 'wp_footer', array( __CLASS__, 'addDivForAjaxPixelEvent') );
add_action( 'woocommerce_add_to_cart',array(__CLASS__, 'trackWooAddToCartEvent'),40, 6);
if (wp_doing_ajax()) {
add_filter('woocommerce_add_to_cart_fragments', array(__CLASS__, 'addPixelCodeToAddToCartFragment'));
} else {
add_action("wp_footer",array(__CLASS__, 'printEvent'));
}
} else {
add_action( 'woocommerce_after_add_to_cart_button', 'PixelYourSite\EventsManager::setupWooSingleProductData' );
}
}
}
}
static function trackWooAddToCartEvent($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
if(isset($cart_item_data['woosb_parent_id'])) return; // fix for WPC Product Bundles for WooCommerce (Premium) product
$is_ajax_request = wp_doing_ajax();
if( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'yith_wacp_add_item_cart') {
$is_ajax_request = true;
}
$standardParams = getStandardParams();
PYS()->getLog()->debug('trackWooAddToCartEvent is_ajax_request '.$is_ajax_request);
$dataList = [];
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
if( !empty($variation_id)
&& $variation_id > 0
&& ( !$pixel->getOption( 'woo_variable_as_simple' )
|| ( $pixel->getSlug() == "facebook"
&& !Facebook\Helpers\isDefaultWooContentIdLogic()
)
)
) {
$_product_id = $variation_id;
} else {
$_product_id = $product_id;
}
$event = new SingleEvent('woo_add_to_cart_on_button_click',EventTypes::$STATIC,'woo');
$event->args = ['productId' => $_product_id,'quantity' => $quantity];
$events = $pixel->generateEvents( $event );
if ( count($events) == 0 ) {
continue; // event is disabled or not supported for the pixel
}
$event = $events[0];
// add standard params
$event->addParams($standardParams);
// prepare event data
$eventData = $event->getData();
$eventData = EventsManager::filterEventParams($eventData,"woo");
$dataList[$pixel->getSlug()] = $eventData;
if($pixel->getSlug() == "facebook" && Facebook()->isServerApiEnabled()) {
if($is_ajax_request) {
FacebookServer()->sendEventsNow([$event]);
} else {
FacebookServer()->sendEventsAsync([$event]);
}
}
}
AjaxHookEventManager::addPendingEvent("woo_add_to_cart_on_button_click",$dataList);
}
public static function printEvent() {
$pixelsEventData = self::getPendingEvent("woo_add_to_cart_on_button_click",true);
if( !is_null($pixelsEventData) ) {
PYS()->getLog()->debug('trackWooAddToCartEvent printEvent is footer');
echo "<div id='pys_late_event' style='display:none' dir='".json_encode($pixelsEventData,JSON_HEX_APOS)."'></div>";
}
}
public static function addDivForAjaxPixelEvent(){
echo self::getDivForAjaxPixelEvent();
?>
<script>
var node = document.getElementsByClassName('woocommerce-message')[0];
if(node && document.getElementById('pys_late_event')) {
var messageText = node.textContent.trim();
if(!messageText) {
node.style.display = 'none';
}
}
</script>
<?php
}
public static function getDivForAjaxPixelEvent($content = ''){
return "<div id='".self::$DIV_ID_FOR_AJAX_EVENTS."'>" . $content . "</div>";
}
public static function addPixelCodeToAddToCarMessage($message, $products, $show_qty) {
$pixelsEventData = self::getPendingEvent("woo_add_to_cart_on_button_click",true);
if( !is_null($pixelsEventData) ){
$message .= "<div id='pys_late_event' dir='".json_encode($pixelsEventData,JSON_HEX_APOS)."'></div>";
}
return $message;
}
public static function addPixelCodeToAddToCartFragment($fragments) {
$pixelsEventData = self::getPendingEvent("woo_add_to_cart_on_button_click",true);
if( !is_null($pixelsEventData) ){
PYS()->getLog()->debug('addPixelCodeToAddToCartFragment send data with fragment');
$pixel_code = self::generatePixelCode($pixelsEventData);
$fragments['#'.self::$DIV_ID_FOR_AJAX_EVENTS] =
self::getDivForAjaxPixelEvent($pixel_code);
}
return $fragments;
}
public static function generatePixelCode($pixelsEventData){
ob_start();
//$cartHashKey = apply_filters( 'woocommerce_cart_hash_key', 'wc_cart_hash_' . md5( get_current_blog_id() . '_' . get_site_url( get_current_blog_id(), '/' ) . get_template() ) );
?>
<script>
function pys_getCookie(name) {
var v = document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
return v ? v[2] : null;
}
function pys_setCookie(name, value, days) {
var d = new Date;
d.setTime(d.getTime() + 24*60*60*1000*days);
document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
}
var name = 'pysAddToCartFragmentId';
var cartHash = "<?=WC()->cart->get_cart_hash()?>";
if(pys_getCookie(name) != cartHash) { // prevent re send event if user update page
<?php foreach ($pixelsEventData as $slug => $eventData) : ?>
var pixel = getPixelBySlag('<?=$slug?>');
var event = <?=json_encode($eventData)?>;
pixel.fireEvent(event.name, event);
<?php endforeach; ?>
pys_setCookie(name,cartHash,90)
}
</script>
<?php
$code = ob_get_clean();
return $code;
}
}

View File

@@ -0,0 +1,538 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class EventsManager {
public $facebookServerEvents = array();
public $doingAMP = false;
private $standardParams = array();
private $staticEvents = array();
private $dynamicEvents = array();
private $triggerEvents = array();
private $triggerEventTypes = array();
public function __construct() {
add_action( 'wp_enqueue_scripts', array( $this, 'enqueueScripts' ),10 );
add_action( 'wp_enqueue_scripts', array( $this, 'setupEventsParams' ),14 );
add_action( 'wp_enqueue_scripts', array( $this, 'outputData' ),15 );
add_action( 'wp_footer', array( $this, 'outputNoScriptData' ), 10 );
}
public function enqueueScripts() {
wp_register_script( 'jquery-bind-first', PYS_FREE_URL . '/dist/scripts/jquery.bind-first-0.2.3.min.js', array( 'jquery' ) );
wp_enqueue_script( 'jquery-bind-first' );
wp_register_script( 'js-cookie-pys', PYS_FREE_URL . '/dist/scripts/js.cookie-2.1.3.min.js', array(), '2.1.3' );
wp_enqueue_script( 'js-cookie-pys' );
if ( PYS()->getOption( 'compress_front_js' )){
wp_enqueue_script( 'pys', PYS_FREE_URL . '/dist/scripts/public.bundle.js',
array( 'jquery','js-cookie-pys', 'jquery-bind-first' ), PYS_FREE_VERSION );
}
else
{
wp_enqueue_script( 'pys', PYS_FREE_URL . '/dist/scripts/public.js',
array( 'jquery','js-cookie-pys', 'jquery-bind-first' ), PYS_FREE_VERSION );
}
}
public function outputData() {
$data = array(
'staticEvents' => $this->staticEvents,
'dynamicEvents' => $this->dynamicEvents,
'triggerEvents' => $this->triggerEvents,
'triggerEventTypes' => $this->triggerEventTypes,
);
// collect options for configured pixel
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
/** @var Pixel|Settings $pixel */
if ( $pixel->configured() ) {
$data[ $pixel->getSlug() ] = $pixel->getPixelOptions();
}
}
$options = array(
'debug' => PYS()->getOption( 'debug_enabled' ),
'siteUrl' => site_url(),
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
'ajax_event' => wp_create_nonce('ajax-event-nonce'),
'enable_remove_download_url_param' => PYS()->getOption( 'enable_remove_download_url_param' ),
'cookie_duration' => PYS()->getOption( 'cookie_duration' ),
'last_visit_duration' => PYS()->getOption('last_visit_duration'),
'enable_success_send_form' => PYS()->getOption( 'enable_success_send_form' ),
);
$options['gdpr'] = array(
'ajax_enabled' => PYS()->getOption( 'gdpr_ajax_enabled' ),
'all_disabled_by_api' => apply_filters( 'pys_disable_by_gdpr', false ),
'facebook_disabled_by_api' => apply_filters( 'pys_disable_facebook_by_gdpr', false ),
'analytics_disabled_by_api' => apply_filters( 'pys_disable_analytics_by_gdpr', false ),
'google_ads_disabled_by_api' => apply_filters( 'pys_disable_google_ads_by_gdpr', false ),
'pinterest_disabled_by_api' => apply_filters( 'pys_disable_pinterest_by_gdpr', false ),
'bing_disabled_by_api' => apply_filters( 'pys_disable_bing_by_gdpr', false ),
'facebook_prior_consent_enabled' => PYS()->getOption( 'gdpr_facebook_prior_consent_enabled' ),
'analytics_prior_consent_enabled' => PYS()->getOption( 'gdpr_analytics_prior_consent_enabled' ),
'google_ads_prior_consent_enabled' => PYS()->getOption( 'gdpr_google_ads_prior_consent_enabled' ),
'pinterest_prior_consent_enabled' => PYS()->getOption( 'gdpr_pinterest_prior_consent_enabled' ),
'bing_prior_consent_enabled' => PYS()->getOption( 'gdpr_bing_prior_consent_enabled' ),
'cookiebot_integration_enabled' => isCookiebotPluginActivated() && PYS()->getOption( 'gdpr_cookiebot_integration_enabled' ),
'cookiebot_facebook_consent_category' => PYS()->getOption( 'gdpr_cookiebot_facebook_consent_category' ),
'cookiebot_analytics_consent_category' => PYS()->getOption( 'gdpr_cookiebot_analytics_consent_category' ),
'cookiebot_google_ads_consent_category' => PYS()->getOption( 'gdpr_cookiebot_google_ads_consent_category' ),
'cookiebot_pinterest_consent_category' => PYS()->getOption( 'gdpr_cookiebot_pinterest_consent_category' ),
'cookiebot_bing_consent_category' => PYS()->getOption( 'gdpr_cookiebot_bing_consent_category' ),
'consent_magic_integration_enabled' => isConsentMagicPluginActivated() && PYS()->getOption( 'consent_magic_integration_enabled' ),
'real_cookie_banner_integration_enabled' => isRealCookieBannerPluginActivated() && PYS()->getOption( 'gdpr_real_cookie_banner_integration_enabled' ),
'cookie_notice_integration_enabled' => isCookieNoticePluginActivated() && PYS()->getOption( 'gdpr_cookie_notice_integration_enabled' ),
'cookie_law_info_integration_enabled' => isCookieLawInfoPluginActivated() && PYS()->getOption( 'gdpr_cookie_law_info_integration_enabled' ),
);
/**
* @var EventsFactory[] $eventsFactory
*/
$eventsFactory = apply_filters("pys_event_factory",[]);
foreach ($eventsFactory as $factory) {
$opt = $factory->getOptions();
if(!empty($opt)) {
$options[$factory::getSlug()] = $factory->getOptions();
}
}
$data = array_merge( $data, $options );
wp_localize_script( 'pys', 'pysOptions', $data );
}
public function outputNoScriptData() {
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
/** @var Pixel|Settings $pixel */
$pixel->outputNoScriptEvents();
}
}
public function setupEventsParams() {
$this->standardParams = getStandardParams();
$this->facebookServerEvents = array();
// initial event
$initEvent = new SingleEvent('init_event',EventTypes::$STATIC,'');
if(get_post_type() == "post") {
global $post;
$catIds = wp_get_object_terms( $post->ID, 'category', array( 'fields' => 'names' ) );
$initEvent->addParams([
'post_category' => implode(", ",$catIds)
]);
}
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
$events = $pixel->generateEvents( $initEvent );
foreach ($events as $event) {
$event->addParams($this->standardParams);
$this->addStaticEvent( $event,$pixel,"" );
}
}
/**
* @var EventsFactory[] $eventsFactory
**/
$eventsFactory = apply_filters("pys_event_factory",[]);
foreach ($eventsFactory as $factory) {
if(!$factory->isEnabled()) continue;
$events = $factory->generateEvents();
$this->addEvents($events,$factory->getSlug());
}
if(EventsEdd()->isEnabled()) {
// AddToCart on button
if ( isEventEnabled( 'edd_add_to_cart_enabled') && PYS()->getOption( 'edd_add_to_cart_on_button_click' ) ) {
add_action( 'edd_purchase_link_end', array( $this, 'setupEddSingleDownloadData' ) );
}
}
if(EventsWoo()->isEnabled()){
// AddToCart on button and Affiliate
if ( PYS()->getOption('woo_add_to_cart_catch_method') == "add_cart_js"
&& isEventEnabled( 'woo_add_to_cart_enabled')
&& PYS()->getOption( 'woo_add_to_cart_on_button_click' )
) {
add_action( 'woocommerce_after_shop_loop_item', array( $this, 'setupWooLoopProductData' ) );
add_action( 'woocommerce_after_add_to_cart_button', 'PixelYourSite\EventsManager::setupWooSingleProductData' );
add_filter( 'woocommerce_blocks_product_grid_item_html', array( $this, 'setupWooBlocksProductData' ), 10, 3 );
add_filter('jet-woo-builder/elementor-views/frontend/archive-item-content', array( $this, 'setupWooBlocksProductData' ),10, 3);
}
}
if(count($this->facebookServerEvents)>0 && Facebook()->enabled()) {
FacebookServer()->sendEventsAsync($this->facebookServerEvents);
}
// remove new user mark
if($user_id = get_current_user_id()) {
if ( get_user_meta( $user_id, 'pys_complete_registration', true ) ) {
delete_user_meta( $user_id, 'pys_complete_registration' );
}
}
}
public function getStaticEvents( $context ) {
return isset( $this->staticEvents[ $context ] ) ? $this->staticEvents[ $context ] : array();
}
function addEvents($pixelEvents,$slug) {
foreach ($pixelEvents as $pixelSlug => $events) {
$pixel = PYS()->getRegisteredPixels()[$pixelSlug];
foreach ($events as $event) {
// add standard params
$event->addParams($this->standardParams);
//save different types of events
if($event->getType() == EventTypes::$STATIC) {
$this->addStaticEvent( $event,$pixel,$slug );
} elseif($event->getType() == EventTypes::$TRIGGER) {
$this->addTriggerEvent($event,$pixel,$slug);
} else {
$this->addDynamicEvent($event,$pixel,$slug);
}
}
}
}
function addDynamicEvent($event,$pixel,$slug) {
$eventData = $event->getData();
$eventData = $this::filterEventParams($eventData,$slug);
if($event->getId() == 'edd_remove_from_cart' || $event->getId() == 'woo_remove_from_cart') {
$this->dynamicEvents[ $event->getId() ][ $event->args['key'] ][ $pixel->getSlug() ] = $eventData;
} else {
$this->dynamicEvents[ $event->getId() ][ $pixel->getSlug() ] = $eventData;
}
}
function addTriggerEvent($event,$pixel,$slug) {
$eventData = $event->getData();
$eventData = $this->filterEventParams($eventData,$slug);
//save static event data
if($event->getId() == "custom_event") {
$eventId = $event->args->getPostId();
} else {
$eventId = $event->getId();
}
$this->triggerEvents[ $eventId ][ $pixel->getSlug() ] = $eventData;
$this->triggerEventTypes[ $eventData['trigger_type'] ][ $eventId ] = $eventData['trigger_value'];
}
/**
* Create stack event, they fire when page loaded
* @param Event $event
*/
function addStaticEvent($event,$pixel,$slug) {
$eventData = $event->getData();
$eventData = $this::filterEventParams($eventData,$slug);
// send only for FB Server events
if($pixel->getSlug() == "facebook" &&
($event->getId() == "woo_complete_registration") &&
Facebook()->isServerApiEnabled() &&
Facebook()->getOption("woo_complete_registration_send_from_server") &&
!$this->isGdprPluginEnabled() )
{
if($eventData['delay'] == 0) {
$this->facebookServerEvents[] = $event;
}
return;
}
//save static event data
$this->staticEvents[ $pixel->getSlug() ][ $event->getId() ][] = $eventData;
// fire fb server api event
if($pixel->getSlug() == "facebook") {
if( $eventData['delay'] == 0 && !Facebook()->getOption( "server_event_use_ajax" )) {
$this->facebookServerEvents[] = $event;
}
}
}
static function filterEventParams($data,$slug)
{
if(!PYS()->getOption('enable_content_name_param')) {
unset($data['params']['content_name']);
}
if(!PYS()->getOption('enable_page_title_param')) {
unset($data['params']['page_title']);
}
if(!PYS()->getOption('enable_post_category_param')) {
unset($data['params']['post_category']);
}
if($slug == EventsWoo::getSlug()) {
if(!PYS()->getOption("enable_woo_category_name_param")) {
unset($data['params']['category_name']);
}
if(!PYS()->getOption("enable_woo_num_items_param")) {
unset($data['params']['num_items']);
}
if(!PYS()->getOption("enable_woo_tags_param")) {
unset($data['params']['tags']);
}
}
if($slug == EventsEdd::getSlug()) {
if(!PYS()->getOption("enable_edd_category_name_param")) {
unset($data['params']['category_name']);
}
if(!PYS()->getOption("enable_edd_num_items_param")) {
unset($data['params']['num_items']);
}
if(!PYS()->getOption("enable_edd_tags_param")) {
unset($data['params']['tags']);
}
}
return $data;
}
function isGdprPluginEnabled() {
return apply_filters( 'pys_disable_by_gdpr', false ) ||
apply_filters( 'pys_disable_facebook_by_gdpr', false ) ||
isCookiebotPluginActivated() && PYS()->getOption( 'gdpr_cookiebot_integration_enabled' ) ||
isConsentMagicPluginActivated() && PYS()->getOption( 'consent_magic_integration_enabled' ) ||
isRealCookieBannerPluginActivated() && PYS()->getOption( 'gdpr_real_cookie_banner_integration_enabled' ) ||
isCookieNoticePluginActivated() && PYS()->getOption( 'gdpr_cookie_notice_integration_enabled' ) ||
isCookieLawInfoPluginActivated() && PYS()->getOption( 'gdpr_cookie_law_info_integration_enabled' );
}
public function setupWooLoopProductData()
{
global $product;
$this->setupWooProductData($product);
}
public function setupWooBlocksProductData($html, $data, $product)
{
$this->setupWooProductData($product);
return $html;
}
public function setupWooProductData($product) {
if ( !is_a($product,"WC_Product")
|| wooProductIsType( $product, 'variable' )
|| wooProductIsType( $product, 'grouped' )
) {
return; // skip variable products
}
$product_id = $product->get_id();
$params = array();
$event = new SingleEvent('woo_add_to_cart_on_button_click',EventTypes::$STATIC,'woo');
$event->args = ['productId' => $product_id,'quantity' => 1];
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
/** @var Pixel|Settings $pixel */
$events = $pixel->generateEvents( $event );
foreach ($events as $event) {
// prepare event data
$eventData = $event->getData();
$eventData = EventsManager::filterEventParams($eventData,"woo");
$params[$pixel->getSlug()] = $eventData; // replace data!!(now use only one event)
}
}
if ( empty( $params ) ) {
return;
}
$params = json_encode( $params );
?>
<script type="application/javascript" style="display:none">
/* <![CDATA[ */
window.pysWooProductData = window.pysWooProductData || [];
window.pysWooProductData[ <?php echo $product_id; ?> ] = <?php echo $params; ?>;
/* ]]> */
</script>
<?php
}
public static function setupWooSingleProductData() {
global $product;
if ( ! is_object( $product)) $product = wc_get_product( get_the_ID() );
if(!$product || !is_a($product,"WC_Product") ) return;
if ( wooProductIsType( $product, 'external' ) ) {
$eventType = 'woo_affiliate';
} else {
$eventType = 'woo_add_to_cart_on_button_click';
}
$product_id = $product->get_id();
// main product id
$product_ids[] = $product_id;
// variations ids
if ( wooProductIsType( $product, 'variable' ) ) {
$product_ids = array_merge($product_ids, $product->get_children());
}
$params = array();
foreach ( $product_ids as $product_id ) {
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
/** @var Pixel|Settings $pixel */
$initEvent = new SingleEvent($eventType,EventTypes::$STATIC,"woo");
$initEvent->args = ['productId' => $product_id,'quantity' => 1];
$events = [];
if(method_exists($pixel,'generateEvents')) {
add_filter('pys_conditional_post_id', function($id) use ($product_id) { return $product_id; });
$events = $pixel->generateEvents( $initEvent );
remove_all_filters('pys_conditional_post_id',10);
} else {
if( $pixel->addParamsToEvent( $initEvent )) {
$events[] = $initEvent;
}
}
if(count($events) == 0) continue;
foreach ($events as $event) {
// prepare event data
$eventData = $event->getData();
$eventData = EventsManager::filterEventParams($eventData,"woo");
$params[ $product_id ][ $pixel->getSlug() ] = $eventData; // replace (use only one event for product)
}
}
}
if ( empty( $params ) ) {
return;
}
?>
<script type="application/javascript" style="display:none">
/* <![CDATA[ */
window.pysWooProductData = window.pysWooProductData || [];
<?php foreach ( $params as $product_id => $product_data ) : ?>
window.pysWooProductData[<?php echo $product_id; ?>] = <?php echo json_encode( $product_data ); ?>;
<?php endforeach; ?>
/* ]]> */
</script>
<?php
}
public function setupEddSingleDownloadData() {
global $post;
$download_ids = array();
if ( edd_has_variable_prices( $post->ID ) ) {
$prices = edd_get_variable_prices( $post->ID );
foreach ( $prices as $price_index => $price_data ) {
$download_ids[] = $post->ID . '_' . $price_index;
}
} else {
$download_ids[] = $post->ID;
}
$params = array();
foreach ( $download_ids as $download_id ) {
$event = EventsEdd()->getEvent('edd_add_to_cart_on_button_click');
$event->args = $download_id;
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
/** @var Pixel|Settings $pixel */
$events = $pixel->generateEvents( $event );
foreach ($events as $singleEvent) {
$eventData = $singleEvent->getData();
$eventData = EventsManager::filterEventParams($eventData,"edd");
/**
* Format is pysEddProductData[ id ][ id ] or pysEddProductData[ id ] [ id_1, id_2, ... ]
*/
$params[ $download_id ][ $pixel->getSlug() ] = [ // replace data there use only one event
'params' => $eventData['params']
];
}
}
}
?>
<script type="application/javascript" style="display:none">
/* <![CDATA[ */
window.pysEddProductData = window.pysEddProductData || [];
window.pysEddProductData[<?php echo $post->ID; ?>] = <?php echo json_encode( $params ); ?>;
/* ]]> */
</script>
<?php
}
}

View File

@@ -0,0 +1,391 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class NoticesFixed {
private static $_instance;
private $dismissedKey = "pys_free_fixed_dismissed_notices";
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
add_action( 'init', [$this,'init'] );
}
function init() {
if ( ! current_user_can( 'manage_pys' ) ) {
return;
}
add_action( 'admin_notices', [$this,'showNotices'] );
add_action( 'wp_ajax_pys_fixed_notice_dismiss', [$this,'catchOnCloseNotice'] );
add_action('wp_ajax_pys_fixed_notice_opt_dismiss', [$this,'allCloseNotice']);
}
function showNotices() {
require_once PYS_FREE_PATH . '/notices/fixed.php';
$user_id = get_current_user_id();
$this->isNeedToShow(adminGetFixedNotices(),(array)get_user_meta( $user_id, $this->dismissedKey,true ));
}
function allCloseNotice(){
require_once PYS_FREE_PATH . '/notices/fixed.php';
$notices = adminGetFixedNotices();
$user_id = get_current_user_id();
if ( empty( $user_id ) ) {
return;
}
if ( empty( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'pys_fixed_notice_opt_dismiss') ) {
return;
}
$dismissedSlugs = (array)get_user_meta( $user_id, $this->dismissedKey,true);
foreach ($notices as $noticesGroup)
{
foreach ($noticesGroup['multiMessage'] as $noticesMessage) {
$dismissedSlugs[] = sanitize_text_field( $noticesMessage['slug'] );
}
}
$dismissedSlugs = array_unique($dismissedSlugs);
update_user_meta($user_id, $this->dismissedKey, $dismissedSlugs );
echo json_encode($dismissedSlugs);
die();
}
function catchOnCloseNotice() {
require_once PYS_FREE_PATH . '/notices/fixed.php';
$notices = adminGetFixedNotices();
$user_id = get_current_user_id();
if ( empty( $user_id ) || empty( $_POST['addon_slug'] ) || empty( $_POST['meta_key'] ) ) {
return;
}
if ( empty( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'pys_fixed_notice_dismiss' ) ) {
return;
}
$dismissedSlugs = (array)get_user_meta( $user_id, $this->dismissedKey,true);
foreach ($_POST['meta_key'] as $meta_key)
{
$dismissedSlugs[] = sanitize_text_field( $meta_key );
}
// save dismissed notice
update_user_meta($user_id, $this->dismissedKey, $dismissedSlugs );
echo json_encode($this->whoIsNext($notices));
die();
}
private function renderNotice($notice) {
if ( ! current_user_can( 'manage_pys' ) ) {
return;
}
if ( ! $notice ) {
return;
}
?>
<div class="notice notice-info is-dismissible pys-promo-fixed-notice pys-fixed-notice <?php echo (isset($notice['enabelDismiss']) && $notice['enabelDismiss']==false)? 'notice-disable-dismiss' : '';?>" data-slug="<?=$notice['slug']?>">
<div class="logo-notice">
<img src="<?php echo PYS_FREE_URL; ?>/dist/images/logo-original.png" alt="plugin logo"/>
</div>
<div class="notice-content">
<div class="notice-item">
<?php if(isset($notice['title'])) : ?>
<div class="notice-title">
<span>
<?php echo $notice['title'];?>
</span>
</div>
<?php endif;?>
<?php if($notice['message']) : ?>
<div class="notice-message">
<p><?php echo $notice['message']; ?></p>
</div>
<?php endif;?>
</div>
</div>
<button type="button" class="notice-dismiss custom-dismiss-button"><span class="screen-reader-text">Dismiss</span></button>
</div>
<script type='application/javascript'>
jQuery(document).on('click', '.pys-promo-fixed-notice .notice-dismiss', function () {
_this = jQuery(this);
jQuery.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'json',
data: {
action: 'pys_fixed_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_fixed_notice_dismiss'))?>',
addon_slug: 'free',
meta_key: [jQuery(this).parents('.pys-promo-fixed-notice').data('slug')]
},
success: function (response)
{
console.log(response);
_this.closest('.pys-promo-fixed-notice').slideUp();
}
});
});
</script>
<?php
}
private function renderNoticeGroped($group)
{
if ( ! current_user_can( 'manage_pys' ) ) {
return;
}
if(isset($group['multiMessage'])):
?>
<div class="notice notice-info is-dismissible pys-chain-fixed-notice pys-fixed-notice <?php echo isset($group['color'])? 'notice-color-'.$group['color']:'';?> <?php echo (isset($group['enabelDismiss']) && $group['enabelDismiss']==false)? 'notice-disable-dismiss' : '';?>" >
<div class="notice_content">
<?php if(isset($group['enabelLogo']) && $group['enabelLogo']!=false) :?>
<div class="logo-notice">
<img src="<?php echo PYS_FREE_URL; ?>/dist/images/logo-original.png" alt="plugin logo"/>
</div>
<?php endif;?>
<div class="notice-content">
<?php foreach ($group['multiMessage'] as $notice) :
if ( ! $notice ) {
return;
}
?>
<div class="notice-item" data-slug="<?=$notice['slug']?>">
<?php if(isset($notice['title']) && $notice['title'] != '') : ?>
<div class="notice-title">
<span>
<?php echo $notice['title'];?>
</span>
</div>
<?php endif;?>
<?php if(isset($notice['message']) && $notice['message'] != '') : ?>
<div class="notice-message">
<p><?php echo $notice['message']; ?></p>
<?php if((isset($notice['button_text']) && isset($notice['button_url'])) && ($notice['button_text'] != '' && $notice['button_url'] != '')) : ?>
<a class="notice-watch-link" href="<?= $notice['button_url']?>" target="_blank"><?= $notice['button_text']?></a>
<?php endif;?>
</div>
<?php endif;?>
<hr>
</div>
<?php endforeach;?>
<?php if(isset($group['enabelYoutubeLink']) && $group['enabelYoutubeLink']!=false) :?>
<div class="bottom-chanel-link">
<span>Improve your tracking with our video tips: <a href="https://www.youtube.com/channel/UCnie2zvwAjTLz9B4rqvAlFQ?sub_confirmation=1" target="_blank">Subscribe to our YouTube channel</a></span>
</div>
<?php endif;?>
</div>
<button type="button" class="notice-dismiss custom-dismiss-button"><span class="screen-reader-text">Dismiss</span></button>
</div>
<?php if(isset($group['optoutEnabel']) && $group['optoutEnabel']!=false) : ?>
<div class="notice_opt_out_block">
<div class="opt_out_message">
<span><?php echo $group['optoutMessage'];?></span>
</div>
<div class="opt_out_dismiss_button"><button><?php echo $group['optoutButtonText'];?></button></div>
</div>
<?php endif;?>
</div>
<?php endif;?>
<script type='application/javascript'>
jQuery(document).on('click','.opt_out_dismiss_button button', function (e){
e.preventDefault();
_this = jQuery(this);
jQuery.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'json',
data: {
action: 'pys_fixed_notice_opt_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_fixed_notice_opt_dismiss'))?>',
addon_slug: 'free'
},
success: function (response)
{
_this.closest('.pys-chain-fixed-notice').slideUp();
}
});
});
jQuery(document).on('click', '.pys-chain-fixed-notice .notice-watch-link', function (e) {
_this = jQuery(this);
jQuery.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'json',
data: {
action: 'pys_fixed_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_fixed_notice_dismiss'))?>',
addon_slug: 'free',
meta_key: [_this.closest('.notice-item').data('slug')]
},
success: function (response)
{
console.log(response);
_this.closest('.notice-item').addClass('closed-notice');
_this.closest('.notice-item').slideUp();
if(_this.closest('.pys-chain-fixed-notice').find('.notice-item').length == _this.closest('.pys-chain-fixed-notice').find('.notice-item.closed-notice').length)
{
_this.closest('.pys-chain-fixed-notice').slideUp();
}
}
});
});
</script>
<script type='application/javascript'>
jQuery(document).on('click', '.pys-chain-fixed-notice .notice-dismiss', function () {
var array_notice = [];
jQuery(this).closest('.pys-chain-fixed-notice').find('.notice-item').each(function (){
array_notice.push(jQuery(this).data('slug'));
})
_this = jQuery(this);
jQuery.ajax({
url: ajaxurl,
type: 'POST',
dataType: 'json',
data: {
action: 'pys_fixed_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_fixed_notice_dismiss'))?>',
addon_slug: 'free',
meta_key: array_notice
},
success: function (response)
{
console.log(response);
console.log(_this.closest('.pys-chain-fixed-notice'));
_this.closest('.pys-chain-fixed-notice').slideUp();
},
});
});
</script>
<?php
}
private function isNeedToShow($noticeGroups,$showedNoticesSlug) {
$activePlugins = [];
$grouped_notice_by_multimessage = array();
if(isWooCommerceActive()) {
$activePlugins[]='woo';
}
if(isWcfActive()) {
$activePlugins[]='wcf';
}
if(isEddActive()) {
$activePlugins[]='edd';
}
foreach ($noticeGroups as $keyGroup => $noticeGroup) {
// check is notice has some plugin dependencies
if( isset($noticeGroup['plugins']) && (count($noticeGroup['plugins']) == 0
|| (count(array_intersect($noticeGroup['plugins'], $activePlugins)) == count($activePlugins)
&& count($noticeGroup['plugins']) == count($activePlugins)))
) {
if(isset($noticeGroup['type']) && $noticeGroup['type'] == 'promo'){
if(!in_array($noticeGroup['slug'],$showedNoticesSlug)) {
$this->renderNotice($noticeGroup);
}
}
}
}
$this->renderNoticeGroped($this->whoIsNext($noticeGroups));
}
private function whoIsNext($noticeGroups) {
$minOrderBlock = 999999;
$user_id = get_current_user_id();
$noticeBlock = array();
foreach ($noticeGroups as $keyGroup => $noticeGroup) {
if(isset($noticeGroup['type']) && $noticeGroup['type'] == 'event chain')
{
$paramGroup = $noticeGroup;
unset($paramGroup['multiMessage']);
$noticeBlock[$noticeGroup['order']] = $paramGroup;
foreach ($noticeGroup['multiMessage'] as $notice){
if(!in_array($notice['slug'], (array)get_user_meta( $user_id, $this->dismissedKey,true ))) {
$noticeBlock[$noticeGroup['order']]['multiMessage'][] = $notice;
}
}
}
}
foreach ($noticeBlock as $block)
{
if(($block['order'] <= $minOrderBlock) && isset($block['multiMessage'])){
$minOrderBlock = $block['order'];
}
}
if(get_user_meta($user_id, 'free_next_chain_notice', true) != $minOrderBlock)
{
if(get_user_meta($user_id, 'free_next_chain_notice', true) < $minOrderBlock && $minOrderBlock != 999999)
{
update_user_meta($user_id, 'free_expiration_chain_notice_dismissed_at', time() + $this->convertTimeToSeconds(isset($noticeBlock[$minOrderBlock]['wait']) ? $noticeBlock[$minOrderBlock]['wait'] : 24, 'hours'));
}
else if(get_user_meta($user_id, 'free_next_chain_notice', true) > $minOrderBlock && $minOrderBlock != 999999)
{
update_user_meta($user_id, 'free_expiration_chain_notice_dismissed_at', time() + $this->convertTimeToSeconds(0, 'seconds'));
}
update_user_meta($user_id, 'free_next_chain_notice', $minOrderBlock);
}
if(isset($noticeBlock[$minOrderBlock]) && (get_user_meta($user_id, 'free_next_chain_notice', true) == $minOrderBlock && time() >= get_user_meta($user_id, 'free_expiration_chain_notice_dismissed_at', true)))
{
return $noticeBlock[$minOrderBlock];
}
}
private function convertTimeToSeconds($timeValue = 24, $type = 'hours')
{
switch ($type){
case 'hours':
$time = $timeValue * 60 * 60;
break;
case 'minute':
$time = $timeValue * 60;
break;
case 'seconds':
$time = $timeValue;
break;
}
return $time;
}
}
/**
* @return NoticesFixed
*/
function NoticesFixed() {
return NoticesFixed::instance();
}
NoticesFixed();

View File

@@ -0,0 +1,39 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
interface Pixel {
public function enabled();
public function configured();
/**
* Return array of pixel IDs.
*
* @return array
*/
public function getPixelIDs();
/**
* Return array of pixel options for front-end.
*
* @return array
*/
public function getPixelOptions();
/**
* @param string $eventType
* @param CustomEvent|array|null $args
*
* @return array|bool
*/
public function getEventData( $eventType, $args = null );
public function outputNoScriptEvents();
}

View File

@@ -0,0 +1,537 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// uncomment this line for testing
//set_site_transient( 'update_plugins', null );
/**
* Allows plugins to use their own update API.
*
* This is used strictly for add-on updates, NOT for updating the core plugin itself (PixelYourSite).
* If you decide to download and install free or paid add-ons from our site (Pinterest Tag, Bing Tag), we will perform checks for updates.
* If you hold a valid license for the add-on, we will download the update from our server.
*
*
* @author Easy Digital Downloads
* @version 1.6.14
*
*/
class Plugin_Updater {
private $api_url = '';
private $api_data = array();
private $name = '';
private $slug = '';
private $version = '';
private $wp_override = false;
private $cache_key = '';
/**
* Class constructor.
*
* @uses plugin_basename()
* @uses hook()
*
* @param string $_api_url The URL pointing to the custom API endpoint.
* @param string $_plugin_file Path to the plugin file.
* @param array $_api_data Optional data to send with API calls.
*/
public function __construct( $_api_url, $_plugin_file, $_api_data = null ) {
global $edd_plugin_data;
$this->api_url = trailingslashit( $_api_url );
$this->api_data = $_api_data;
$this->name = plugin_basename( $_plugin_file );
$this->slug = basename( $_plugin_file, '.php' );
$this->version = $_api_data['version'];
$this->wp_override = isset( $_api_data['wp_override'] ) ? (bool) $_api_data['wp_override'] : false;
$this->beta = ! empty( $this->api_data['beta'] ) ? true : false;
$this->cache_key = md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
$edd_plugin_data[ $this->slug ] = $this->api_data;
// Set up hooks.
$this->init();
}
/**
* Set up WordPress filters to hook into WP's update process.
*
* @uses add_filter()
*
* @return void
*/
public function init() {
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
remove_action( 'after_plugin_row_' . $this->name, 'wp_plugin_update_row', 10 );
add_action( 'after_plugin_row_' . $this->name, array( $this, 'show_update_notification' ), 10, 2 );
add_action( 'admin_init', array( $this, 'show_changelog' ) );
}
/**
* Check for Updates at the defined API endpoint and modify the update array.
*
* This function dives into the update API just when WordPress creates its update array,
* then adds a custom API call and injects the custom plugin data retrieved from the API.
* It is reassembled from parts of the native WordPress plugin update code.
* See wp-includes/update.php line 121 for the original wp_update_plugins() function.
*
* @uses api_request()
*
* @param array $_transient_data Update array build by WordPress.
*
* @return array Modified update array with custom plugin data.
*/
public function check_update( $_transient_data ) {
global $pagenow;
if ( ! is_object( $_transient_data ) ) {
$_transient_data = new \stdClass;
}
if ( 'plugins.php' == $pagenow && is_multisite() ) {
return $_transient_data;
}
if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
return $_transient_data;
}
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->api_request( 'plugin_latest_version',
array( 'slug' => $this->slug, 'beta' => $this->beta ) );
if($this->slug == "pixelyoursite-pinterest") {
$timeout = strtotime( '+48 hours', current_time( 'timestamp' ) );
} else {
$timeout = strtotime( '+3 hours', current_time( 'timestamp' ) );
}
$this->set_version_info_cache( $version_info,"",$timeout );
}
if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
$_transient_data->response[ $this->name ] = $version_info;
}
$_transient_data->last_checked = current_time( 'timestamp' );
$_transient_data->checked[ $this->name ] = $this->version;
}
return $_transient_data;
}
/**
* show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
*
* @param string $file
* @param array $plugin
*/
public function show_update_notification( $file, $plugin ) {
if ( is_network_admin() ) {
return;
}
if ( ! current_user_can( 'update_plugins' ) ) {
return;
}
if ( ! is_multisite() ) {
return;
}
if ( $this->name != $file ) {
return;
}
// Remove our filter on the site transient
remove_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ), 10 );
$update_cache = get_site_transient( 'update_plugins' );
$update_cache = is_object( $update_cache ) ? $update_cache : new \stdClass();
if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
$version_info = $this->get_cached_version_info();
if ( false === $version_info ) {
$version_info = $this->api_request( 'plugin_latest_version',
array( 'slug' => $this->slug, 'beta' => $this->beta ) );
if($this->slug == "pixelyoursite-pinterest") {
$timeout = strtotime( '+48 hours', current_time( 'timestamp' ) );
} else {
$timeout = strtotime( '+3 hours', current_time( 'timestamp' ) );
}
$this->set_version_info_cache( $version_info,"",$timeout );
}
if ( ! is_object( $version_info ) ) {
return;
}
if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
$update_cache->response[ $this->name ] = $version_info;
}
$update_cache->last_checked = current_time( 'timestamp' );
$update_cache->checked[ $this->name ] = $this->version;
set_site_transient( 'update_plugins', $update_cache );
} else {
$version_info = $update_cache->response[ $this->name ];
}
// Restore our filter
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_update' ) );
if ( ! empty( $update_cache->response[ $this->name ] ) && version_compare( $this->version,
$version_info->new_version, '<' ) ) {
// build a plugin list row, with update notification
$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
# <tr class="plugin-update-tr"><td colspan="' . $wp_list_table->get_column_count() . '" class="plugin-update colspanchange">
echo '<tr class="plugin-update-tr" id="' . $this->slug . '-update" data-slug="' . $this->slug . '" data-plugin="' . $this->slug . '/' . $file . '">';
echo '<td colspan="3" class="plugin-update colspanchange">';
echo '<div class="update-message notice inline notice-warning notice-alt">';
$changelog_link = self_admin_url( 'index.php?edd_sl_action=view_plugin_changelog&plugin=' . $this->name . '&slug=' . $this->slug . '&TB_iframe=true&width=772&height=911' );
if ( empty( $version_info->download_link ) ) {
printf(
__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s.',
'easy-digital-downloads' ),
esc_html( $version_info->name ),
'<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
esc_html( $version_info->new_version ),
'</a>'
);
} else {
printf(
__( 'There is a new version of %1$s available. %2$sView version %3$s details%4$s or %5$supdate now%6$s.',
'easy-digital-downloads' ),
esc_html( $version_info->name ),
'<a target="_blank" class="thickbox" href="' . esc_url( $changelog_link ) . '">',
esc_html( $version_info->new_version ),
'</a>',
'<a href="' . esc_url( wp_nonce_url( self_admin_url( 'update.php?action=upgrade-plugin&plugin=' ) . $this->name,
'upgrade-plugin_' . $this->name ) ) . '">',
'</a>'
);
}
do_action( "in_plugin_update_message-{$file}", $plugin, $version_info );
echo '</div></td></tr>';
}
}
/**
* Updates information on the "View version x.x details" page with custom data.
*
* @uses api_request()
*
* @param mixed $_data
* @param string $_action
* @param object $_args
*
* @return object $_data
*/
public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
if ( $_action != 'plugin_information' ) {
return $_data;
}
if ( ! isset( $_args->slug ) || ( $_args->slug != $this->slug ) ) {
return $_data;
}
$to_send = array(
'slug' => $this->slug,
'is_ssl' => is_ssl(),
'fields' => array(
'banners' => array(),
'reviews' => false
)
);
$cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
// Get the transient where we store the api request for this plugin for 24 hours
$edd_api_request_transient = $this->get_cached_version_info( $cache_key );
//If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
if ( empty( $edd_api_request_transient ) ) {
$api_response = $this->api_request( 'plugin_information', $to_send );
// Expires in 3 hours
if($this->slug == "pixelyoursite-pinterest") {
$timeout = strtotime( '+48 hours', current_time( 'timestamp' ) );
} else {
$timeout = strtotime( '+3 hours', current_time( 'timestamp' ) );
}
$this->set_version_info_cache( $api_response, $cache_key,$timeout );
if ( false !== $api_response ) {
$_data = $api_response;
}
} else {
$_data = $edd_api_request_transient;
}
// Convert sections into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
$new_sections = array();
foreach ( $_data->sections as $key => $value ) {
$new_sections[ $key ] = $value;
}
$_data->sections = $new_sections;
}
// Convert banners into an associative array, since we're getting an object, but Core expects an array.
if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
$new_banners = array();
foreach ( $_data->banners as $key => $value ) {
$new_banners[ $key ] = $value;
}
$_data->banners = $new_banners;
}
return $_data;
}
/**
* Disable SSL verification in order to prevent download update failures
*
* @param array $args
* @param string $url
*
* @return object $array
*/
public function http_request_args( $args, $url ) {
$verify_ssl = $this->verify_ssl();
if ( strpos( $url, 'https://' ) !== false && strpos( $url, 'edd_action=package_download' ) ) {
$args['sslverify'] = $verify_ssl;
}
return $args;
}
/**
* Calls the API and, if successfull, returns the object delivered by the API.
*
* @uses get_bloginfo()
* @uses wp_remote_post()
* @uses is_wp_error()
*
* @param string $_action The requested action.
* @param array $_data Parameters for the API action.
*
* @return false|object
*/
private function api_request( $_action, $_data ) {
global $wp_version;
$data = array_merge( $this->api_data, $_data );
if ( $data['slug'] != $this->slug ) {
return;
}
if ( $this->api_url == trailingslashit( home_url() ) ) {
return false; // Don't allow a plugin to ping itself
}
$api_params = array(
'edd_action' => 'get_version',
'license' => ! empty( $data['license'] ) ? $data['license'] : '',
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
'version' => isset( $data['version'] ) ? $data['version'] : false,
'slug' => $data['slug'],
'author' => $data['author'],
'url' => home_url(),
'beta' => ! empty( $data['beta'] ),
);
$verify_ssl = $this->verify_ssl();
$request = wp_remote_post( $this->api_url,
array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
if ( ! is_wp_error( $request ) ) {
$request = json_decode( wp_remote_retrieve_body( $request ) );
}
if ( $request && isset( $request->sections ) ) {
$request->sections = maybe_unserialize( $request->sections );
} else {
$request = false;
}
if ( $request && isset( $request->banners ) ) {
$request->banners = maybe_unserialize( $request->banners );
}
if ( ! empty( $request->sections ) ) {
foreach ( $request->sections as $key => $section ) {
$request->$key = (array) $section;
}
}
return $request;
}
public function show_changelog() {
global $edd_plugin_data;
if ( empty( $_REQUEST['edd_sl_action'] ) || 'view_plugin_changelog' != $_REQUEST['edd_sl_action'] ) {
return;
}
if ( empty( $_REQUEST['plugin'] ) ) {
return;
}
if ( empty( $_REQUEST['slug'] ) ) {
return;
}
if ( ! current_user_can( 'update_plugins' ) ) {
wp_die( __( 'You do not have permission to install plugin updates', 'easy-digital-downloads' ),
__( 'Error', 'easy-digital-downloads' ), array( 'response' => 403 ) );
}
$slag = sanitize_title($_REQUEST['slug']);
$data = $edd_plugin_data[ $slag ];
$beta = ! empty( $data['beta'] ) ? true : false;
$cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $beta . '_version_info' );
$version_info = $this->get_cached_version_info( $cache_key );
if ( false === $version_info ) {
$api_params = array(
'edd_action' => 'get_version',
'item_name' => isset( $data['item_name'] ) ? $data['item_name'] : false,
'item_id' => isset( $data['item_id'] ) ? $data['item_id'] : false,
'slug' => $slag,
'author' => $data['author'],
'url' => home_url(),
'beta' => ! empty( $data['beta'] )
);
$verify_ssl = $this->verify_ssl();
$request = wp_remote_post( $this->api_url,
array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
if ( ! is_wp_error( $request ) ) {
$version_info = json_decode( wp_remote_retrieve_body( $request ) );
}
if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
$version_info->sections = maybe_unserialize( $version_info->sections );
} else {
$version_info = false;
}
if ( ! empty( $version_info ) ) {
foreach ( $version_info->sections as $key => $section ) {
$version_info->$key = (array) $section;
}
}
if($slag == "pixelyoursite-pinterest") {
$timeout = strtotime( '+48 hours', current_time( 'timestamp' ) );
} else {
$timeout = strtotime( '+3 hours', current_time( 'timestamp' ) );
}
$this->set_version_info_cache( $version_info, $cache_key,$timeout );
}
if ( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
}
exit;
}
public function get_cached_version_info( $cache_key = '' ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->cache_key;
}
$cache = get_option( $cache_key );
if ( empty( $cache['timeout'] ) || current_time( 'timestamp' ) > $cache['timeout'] ) {
return false; // Cache is expired
}
return json_decode( $cache['value'] );
}
public function set_version_info_cache( $value = '', $cache_key = '',$timeout = null ) {
if ( empty( $cache_key ) ) {
$cache_key = $this->cache_key;
}
if($timeout == null) {
$timeout = strtotime( '+3 hours', current_time( 'timestamp' ) );
}
$data = array(
'timeout' => $timeout,
'value' => json_encode( $value )
);
update_option( $cache_key, $data, 'no' );
}
/**
* Returns if the SSL of the store should be verified.
*
* @since 1.6.13
* @return bool
*/
private function verify_ssl() {
return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this );
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
interface Plugin {
public function getPluginName();
public function getPluginVersion();
public function getPluginFile();
public function adminUpdateLicense();
}

View File

@@ -0,0 +1,770 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* PixelYourSite Core class.
*/
final class PYS extends Settings implements Plugin {
private static $_instance;
/** @var $eventsManager EventsManager */
private $eventsManager;
/** @var $registeredPixels array Registered pixels */
private $registeredPixels = array();
/** @var $registeredPlugins array Registered plugins (addons) */
private $registeredPlugins = array();
private $adminPagesSlugs = array();
/**
* @var PYS_Logger
*/
private $logger;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function getPluginName() {}
public function getPluginFile() {}
public function getPluginVersion() {
return PYS_FREE_VERSION;
}
public function __construct() {
// initialize settings
parent::__construct( 'core' );
add_action( 'admin_init', array( $this, 'updatePlugin' ), 0 );
add_action( 'admin_init', 'PixelYourSite\manageAdminPermissions' );
// Priority 9 used to keep things same as on PRO version
add_action( 'init', array( $this, 'init' ), 9 );
add_action( 'init', array( $this, 'afterInit' ), 11 );
add_action( 'admin_menu', array( $this, 'adminMenu' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'adminEnqueueScripts' ) );
add_action( 'admin_notices', 'PixelYourSite\adminRenderNotices' );
add_action( 'admin_init', array( $this, 'adminProcessRequest' ), 11 );
// run Events Manager
add_action( 'template_redirect', array( $this, 'managePixels' ) );
// track user login event
add_action('wp_login', [$this,'userLogin'], 10, 2);
// track user registrations
add_action( 'user_register', array( $this, 'userRegisterHandler' ) );
// "admin_permission" option custom sanitization function
add_filter( 'pys_core_settings_sanitize_admin_permissions_field', function( $value ) {
// "administrator" always should be allowed
if ( ! is_array( $value ) || ! in_array( 'administrator', $value ) ) {
$value[] = 'administrator';
}
manageAdminPermissions();
return $this->sanitize_multi_select_field( $value );
} );
add_action( 'wp_ajax_pys_get_gdpr_filters_values', array( $this, 'ajaxGetGdprFiltersValues' ) );
add_action( 'wp_ajax_nopriv_pys_get_gdpr_filters_values', array( $this, 'ajaxGetGdprFiltersValues' ) );
/*
* Restore settings after COG plugin
* */
add_action( 'deactivate_pixel-cost-of-goods/pixel-cost-of-goods.php',array($this,"restoreSettingsAfterCog"));
$this->logger = new PYS_Logger();
}
public function init() {
register_post_type( 'pys_event', array(
'public' => false,
'supports' => array( 'title' )
) );
// initialize options
$this->locateOptions(
PYS_FREE_PATH . '/includes/options_fields.json',
PYS_FREE_PATH . '/includes/options_defaults.json'
);
// register pixels and plugins (add-ons)
do_action( 'pys_register_pixels', $this );
do_action( 'pys_register_plugins', $this );
// load dummy Pinterest plugin for admin UI
if ( ! array_key_exists( 'pinterest', $this->registeredPlugins ) ) {
/** @noinspection PhpIncludeInspection */
require_once PYS_FREE_PATH . '/modules/pinterest/pinterest.php';
}
// load dummy Bing plugin for admin UI
if ( ! array_key_exists( 'bing', $this->registeredPlugins ) ) {
/** @noinspection PhpIncludeInspection */
require_once PYS_FREE_PATH . '/modules/bing/bing.php';
}
// maybe disable Facebook for WooCommerce pixel output
if ( isWooCommerceActive()
&& array_key_exists( 'facebook', $this->registeredPixels ) && Facebook()->configured() ) {
add_filter( 'facebook_for_woocommerce_integration_pixel_enabled', '__return_false' );
}
$this->logger->init();
if(Facebook()->getOption('test_api_event_code_expiration_at'))
{
foreach (Facebook()->getOption('test_api_event_code_expiration_at') as $key => $test_code_expiration_at)
{
if(time() >= $test_code_expiration_at)
{
Facebook()->updateOptions(array("test_api_event_code" => array()));
Facebook()->updateOptions(array("test_api_event_code_expiration_at" => array()));
}
}
}
$eventsFormFactory = apply_filters("pys_form_event_factory",[]);
if(!$eventsFormFactory)
{
$options = array(
'enable_success_send_form' => false
);
PYS()->updateOptions($options);
}
EnrichOrder()->init();
AjaxHookEventManager::instance()->addHooks();
}
public function utmTemplate() {
include 'views/html-utm-templates.php';
}
/**
* Extend options after post types are registered
*/
public function afterInit() {
// add available public custom post types to settings
foreach ( get_post_types( array( 'public' => true, '_builtin' => false ), 'objects' ) as $post_type ) {
// skip product post type when WC is active
if ( isWooCommerceActive() && $post_type->name == 'product' ) {
continue;
}
// skip download post type when EDD is active
if ( isEddActive() && $post_type->name == 'download' ) {
continue;
}
$this->addOption( 'general_event_on_' . $post_type->name . '_enabled', 'checkbox', false );
}
maybeMigrate();
}
/**
* @param Pixel|Settings $pixel
*/
public function registerPixel( &$pixel ) {
$this->registeredPixels[ $pixel->getSlug() ] = $pixel;
}
/**
* Hook
* @param String $user_login
* @param \WP_User $user
*/
function userLogin($user_login, $user) {
update_user_meta($user->ID,'pys_just_login',true);
}
public function userRegisterHandler( $user_id ) {
if ( PYS()->getOption( 'woo_complete_registration_enabled' )
|| PYS()->getOption( 'automatic_event_signup_enabled' )
) {
update_user_meta( $user_id, 'pys_complete_registration', true );
}
}
/**
* Return array of registered pixels
*
* @return array
*/
public function getRegisteredPixels() {
return $this->registeredPixels;
}
/**
* @param Pixel|Settings $plugin
*/
public function registerPlugin( &$plugin ) {
$this->registeredPlugins[ $plugin->getSlug() ] = $plugin;
}
/**
* Return array of registered plugins
*
* @return array
*/
public function getRegisteredPlugins() {
return $this->registeredPlugins;
}
/**
* Front-end entry point
*/
public function managePixels() {
if (defined('DOING_AJAX') && DOING_AJAX) {
return;
}
// disable Events Manager on Customizer and preview mode
if (is_admin() || is_customize_preview() || is_preview()) {
return;
}
// disable Events Manager on Elementor editor
if (did_action('elementor/preview/init')
|| did_action('elementor/editor/init')
|| (isset( $_GET['action'] ) && $_GET['action'] == 'piotnetforms') // skip preview for piotnet forms plugin
) {
return;
}
// disable Events Manager on Divi Builder
if (function_exists('et_core_is_fb_enabled') && et_core_is_fb_enabled()) {
return;
}
if(PYS()->getOption( 'block_robot_enabled') && $this->is_user_agent_bot())
{
return;
}
if(PYS()->getOption( 'block_ip_enabled') && in_array($this->get_user_ip(), PYS()->getOption('blocked_ips')))
{
return;
}
$theme = wp_get_theme(); // gets the current theme
if ( ('Bricks' == $theme->name || 'Bricks' == $theme->parent_theme) && isset($_GET['bricks']) && $_GET['bricks']=='run') {
return;
}
// output debug info
if(!PYS()->getOption( 'hide_version_plugin_in_console')) {
add_action('wp_head', function () {
echo "<script type='application/javascript'>console.log('PixelYourSite Free version " . PYS_FREE_VERSION . "');</script>\r\n";
}, 1);
}
if ( isDisabledForCurrentRole() ) {
return;
}
// setup events
$this->eventsManager = new EventsManager();
// at least one pixel should be configured
if ( ! Facebook()->configured() && ! GA()->configured() && ! Pinterest()->configured() && ! Bing()->configured() ) {
if(!PYS()->getOption( 'hide_version_plugin_in_console')) {
add_action('wp_head', function () {
echo "<script type='application/javascript'>console.warn('PixelYourSite: no pixel configured.');</script>\r\n";
});
}
return;
}
}
function get_user_ip(){
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip = $_SERVER['REMOTE_ADDR'];
}
return $ip;
}
function is_user_agent_bot(){
if (!empty($_SERVER['HTTP_USER_AGENT'])) {
$options = array(
'YandexBot', 'YandexAccessibilityBot', 'YandexMobileBot','YandexDirectDyn',
'YandexScreenshotBot', 'YandexImages', 'YandexVideo', 'YandexVideoParser',
'YandexMedia', 'YandexBlogs', 'YandexFavicons', 'YandexWebmaster',
'YandexPagechecker', 'YandexImageResizer','YandexAdNet', 'YandexDirect',
'YaDirectFetcher', 'YandexCalendar', 'YandexSitelinks', 'YandexMetrika',
'YandexNews', 'YandexNewslinks', 'YandexCatalog', 'YandexAntivirus',
'YandexMarket', 'YandexVertis', 'YandexForDomain', 'YandexSpravBot',
'YandexSearchShop', 'YandexMedianaBot', 'YandexOntoDB', 'YandexOntoDBAPI',
'Googlebot', 'Googlebot-Image', 'Googlebot-News', 'Googlebot-Video',
'Mediapartners-Google', 'AdsBot-Google', 'Chrome-Lighthouse', 'Lighthouse',
'Mail.RU_Bot', 'bingbot', 'Accoona', 'ia_archiver', 'Ask Jeeves',
'OmniExplorer_Bot', 'W3C_Validator', 'WebAlta', 'YahooFeedSeeker', 'Yahoo!',
'Ezooms', 'Tourlentabot', 'MJ12bot', 'AhrefsBot', 'SearchBot', 'SiteStatus',
'Nigma.ru', 'Baiduspider', 'Statsbot', 'SISTRIX', 'AcoonBot', 'findlinks',
'proximic', 'OpenindexSpider','statdom.ru', 'Exabot', 'Spider', 'SeznamBot',
'oBot', 'C-T bot', 'Updownerbot', 'Snoopy', 'heritrix', 'Yeti',
'DomainVader', 'DCPbot', 'PaperLiBot', 'APIs-Google', 'AdsBot-Google-Mobile',
'AdsBot-Google-Mobile', 'AdsBot-Google-Mobile-Apps', 'FeedFetcher-Google',
'Google-Read-Aloud', 'DuplexWeb-Google', 'Storebot-Google'
);
foreach($options as $row) {
if (stripos($_SERVER['HTTP_USER_AGENT'], $row) !== false) {
return true;
}
}
}
return false;
}
public function ajaxGetGdprFiltersValues() {
wp_send_json_success( array(
'all_disabled_by_api' => apply_filters( 'pys_disable_by_gdpr', false ),
'facebook_disabled_by_api' => apply_filters( 'pys_disable_facebook_by_gdpr', false ),
'analytics_disabled_by_api' => apply_filters( 'pys_disable_analytics_by_gdpr', false ),
'pinterest_disabled_by_api' => apply_filters( 'pys_disable_pinterest_by_gdpr', false ),
'bing_disabled_by_api' => apply_filters( 'pys_disable_bing_by_gdpr', false ),
) );
}
public function getEventsManager() {
return $this->eventsManager;
}
public function adminMenu() {
global $submenu;
add_menu_page( 'PixelYourSite', 'PixelYourSite', 'manage_pys', 'pixelyoursite',
array( $this, 'adminPageMain' ), PYS_FREE_URL . '/dist/images/favicon.png' );
$addons = $this->registeredPlugins;
if ( $addons['head_footer'] ) {
unset( $addons['head_footer'] );
}
// display Licenses menu item only when at lest one addon is active
if ( count( $addons ) ) {
add_submenu_page( 'pixelyoursite', 'Licenses', 'Licenses',
'manage_pys', 'pixelyoursite_licenses', array( $this, 'adminPageLicenses' ) );
}
if(isWooCommerceActive()) {
add_submenu_page( 'pixelyoursite', 'WooCommerce Reports', 'WooCommerce Reports',
'manage_pys', 'pixelyoursite_woo_reports', array( $this, 'wooReport' ) );
}
if(isEddActive()) {
add_submenu_page( 'pixelyoursite', 'EDD Reports', 'EDD Reports',
'manage_pys', 'pixelyoursite_edd_reports', array( $this, 'eddReport' ) ,9);
}
add_submenu_page( 'pixelyoursite', 'UTM Builder', 'UTM Builder',
'manage_pys', 'pixelyoursite_utm', array( $this, 'utmTemplate' ) );
add_submenu_page( 'pixelyoursite', 'System Report', 'System Report',
'manage_pys', 'pixelyoursite_report', array( $this, 'adminPageReport' ) );
// core admin pages
$this->adminPagesSlugs = array(
'pixelyoursite',
'pixelyoursite_licenses',
'pixelyoursite_report',
'pixelyoursite_woo_reports',
'pixelyoursite_edd_reports',
'pixelyoursite_utm',
);
// rename first submenu item
if ( isset( $submenu['pixelyoursite'] ) ) {
$submenu['pixelyoursite'][0][0] = 'Dashboard';
}
$this->adminSaveSettings();
}
public function adminEnqueueScripts() {
wp_enqueue_style( 'pys_notice', PYS_FREE_URL . '/dist/styles/notice.css', array(), PYS_FREE_VERSION );
if ( in_array( getCurrentAdminPage(), $this->adminPagesSlugs ) ) {
wp_register_style( 'select2_css', PYS_FREE_URL . '/dist/styles/select2.min.css' );
wp_enqueue_script( 'select2_js', PYS_FREE_URL . '/dist/scripts/select2.min.js',
array( 'jquery' ) );
wp_enqueue_script( 'popper', PYS_FREE_URL . '/dist/scripts/popper.min.js', 'jquery' );
wp_enqueue_script( 'bootstrap', PYS_FREE_URL . '/dist/scripts/bootstrap.min.js', 'jquery',
'popper' );
wp_enqueue_style( 'pys_css', PYS_FREE_URL . '/dist/styles/admin.css', array( 'select2_css' ), PYS_FREE_VERSION );
wp_enqueue_script( 'pys_js', PYS_FREE_URL . '/dist/scripts/admin.js', array( 'jquery', 'select2_js', 'popper',
'bootstrap' ), PYS_FREE_VERSION );
}
}
public function adminPageMain() {
$this->adminResetSettings();
include 'views/html-wrapper-main.php';
}
public function adminPageReport() {
include 'views/html-report.php';
}
public function wooReport() {
include 'views/html-report-woo.php';
}
public function eddReport() {
include 'views/html-report-edd.php';
}
public function adminPageLicenses() {
$this->adminUpdateLicense();
/** @var Plugin|Settings $plugin */
foreach ( $this->registeredPlugins as $plugin ) {
if ( $plugin->getSlug() !== 'head_footer' ) {
$plugin->adminUpdateLicense();
}
}
include 'views/html-licenses.php';
}
public function adminUpdateLicense() {}
public function updatePlugin() {
foreach ( $this->registeredPlugins as $slug => $plugin ) {
if ( $slug == 'head_footer' ) {
continue;
}
updatePlugin( $plugin );
}
}
public function adminSecurityCheck() {
// verify user access
if ( ! current_user_can( 'manage_pys' ) ) {
return false;
}
// nonce filed and PYS data are required request
if ( ! isset( $_REQUEST['_wpnonce'] ) || ! isset( $_REQUEST['pys'] ) ) {
return false;
}
return true;
}
public function adminProcessRequest() {
$this->adminUpdateCustomEvents();
$this->adminEnableGdprAjax();
}
private function adminUpdateCustomEvents() {
if ( ! $this->adminSecurityCheck() ) {
return;
}
/**
* Single Custom Event Actions
*/
if ( isset( $_REQUEST['pys']['event'] ) && isset( $_REQUEST['action'] ) ) {
$nonce = isset( $_REQUEST['_wpnonce'] ) ? $_REQUEST['_wpnonce'] : null;
$action = $_REQUEST['action'];
if(isset( $_REQUEST['pys']['event']['post_id'] )) {
$post_id = sanitize_key($_REQUEST['pys']['event']['post_id']) ;
} else {
$post_id = false;
}
if ( $action == 'update' && wp_verify_nonce( $nonce, 'pys_update_event' ) ) {
if ( $post_id ) {
$event = CustomEventFactory::getById( $post_id );
$event->update( $_REQUEST['pys']['event'] );
} else {
if(isset( $_REQUEST['pys']['event']) && is_array($_REQUEST['pys']['event'])) {
CustomEventFactory::create( $_REQUEST['pys']['event'] );
} else {
CustomEventFactory::create( [] );
}
}
} elseif ( $action == 'enable' && $post_id && wp_verify_nonce( $nonce, 'pys_enable_event' ) ) {
$event = CustomEventFactory::getById( $post_id );
$event->enable();
} elseif ( $action == 'disable' && $post_id && wp_verify_nonce( $nonce, 'pys_disable_event' ) ) {
$event = CustomEventFactory::getById( $post_id );
$event->disable();
} elseif ( $action == 'remove' && $post_id && wp_verify_nonce( $nonce, 'pys_remove_event' ) ) {
CustomEventFactory::remove( $post_id );
}
purgeCache();
// redirect to events tab
wp_safe_redirect( buildAdminUrl( 'pixelyoursite', 'events' ) );
exit;
}
/**
* Bulk Custom Events Actions
*/
if ( isset( $_REQUEST['pys']['bulk_event_action'], $_REQUEST['pys']['selected_events'] )
&& isset( $_REQUEST['pys']['bulk_event_action_nonce'] )
&& wp_verify_nonce( $_REQUEST['pys']['bulk_event_action_nonce'], 'bulk_event_action' )
&& is_array( $_REQUEST['pys']['selected_events'] ) ) {
foreach ( $_REQUEST['pys']['selected_events'] as $event_id ) {
$event_id = (int) $event_id;
switch ( $_REQUEST['pys']['bulk_event_action'] ) {
case 'enable':
$event = CustomEventFactory::getById( $event_id );
$event->enable();
break;
case 'disable':
$event = CustomEventFactory::getById( $event_id );
$event->disable();
break;
case 'clone':
CustomEventFactory::makeClone( $event_id );
break;
case 'delete':
CustomEventFactory::remove( $event_id );
break;
}
}
purgeCache();
// redirect to events tab
wp_safe_redirect( buildAdminUrl( 'pixelyoursite', 'events' ) );
exit;
}
}
private function adminSaveSettings() {
if ( ! $this->adminSecurityCheck() ) {
return;
}
if ( wp_verify_nonce( $_REQUEST['_wpnonce'], 'pys_save_settings' ) ) {
if(isset( $_POST['pys']['core'] ) && is_array($_POST['pys']['core'])) {
$core_options = $_POST['pys']['core'];
} else {
$core_options = array();
}
$gdpr_ajax_enabled = isset( $core_options['gdpr_ajax_enabled'] )
? $core_options['gdpr_ajax_enabled'] // value from form data
: $this->getOption( 'gdpr_ajax_enabled' ); // previous value
// allow 3rd party plugins to by-pass option value
$core_options['gdpr_ajax_enabled'] = apply_filters( 'pys_gdpr_ajax_enabled', $gdpr_ajax_enabled );
if (isPixelCogActive() ) {
if (isset($core_options['woo_purchase_value_option'])) {
$core_options = $this->updateDefaultNoCogOption($core_options,'woo_purchase_value_option','woo_purchase_value_cog');
}
if (isset($core_options['woo_view_content_value_option'])) {
$core_options = $this->updateDefaultNoCogOption($core_options,'woo_view_content_value_option','woo_content_value_cog');
}
if (isset($core_options['woo_add_to_cart_value_option'])) {
$core_options = $this->updateDefaultNoCogOption($core_options,'woo_add_to_cart_value_option','woo_add_to_cart_value_cog');
}
if (isset($core_options['woo_initiate_checkout_value_option'])) {
$core_options = $this->updateDefaultNoCogOption($core_options,'woo_initiate_checkout_value_option','woo_initiate_checkout_value_cog');
}
}
// update core options
$this->updateOptions( $core_options );
$objects = array_merge( $this->registeredPixels, $this->registeredPlugins );
// update plugins and pixels options
foreach ( $objects as $obj ) {
/** @var Plugin|Pixel|Settings $obj */
$obj->updateOptions();
}
purgeCache();
}
}
private function updateDefaultNoCogOption($core_options,$optionName,$defaultOptionName) {
$val = $core_options[$optionName];
$currentVal = $this->getOption($optionName);
if($val != 'cog') {
$core_options[$defaultOptionName] = $val;
} elseif ( $currentVal != 'cog' ) {
$core_options[$defaultOptionName] = $currentVal;
}
return $core_options;
}
private function adminResetSettings() {
if ( ! $this->adminSecurityCheck() ) {
return;
}
if ( wp_verify_nonce( $_REQUEST['_wpnonce'], 'pys_save_settings' ) && isset( $_REQUEST['pys']['reset_settings'] ) ) {
if ( isPinterestActive() ) {
$old_options = array(
'license_key' => Pinterest()->getOption( 'license_key' ),
'license_status' => Pinterest()->getOption( 'license_status' ),
'license_expires' => Pinterest()->getOption( 'license_expires' ),
'pixel_id' => Pinterest()->getOption( 'pixel_id' ),
);
Pinterest()->resetToDefaults();
Pinterest()->updateOptions( $old_options );
}
PYS()->resetToDefaults();
Facebook()->resetToDefaults();
GA()->resetToDefaults();
// do redirect
wp_safe_redirect( buildAdminUrl( 'pixelyoursite' ) );
exit;
}
}
private function adminEnableGdprAjax() {
if ( ! $this->adminSecurityCheck() ) {
return;
}
if ( isset( $_REQUEST['pys']['enable_gdpr_ajax'] ) ) {
$this->updateOptions( array(
'gdpr_ajax_enabled' => true,
'gdpr_cookie_law_info_integration_enabled' => true,
'consent_magic_integration_enabled' => true,
) );
add_action( 'admin_notices', 'PixelYourSite\adminGdprAjaxEnabledNotice' );
purgeCache();
}
}
function restoreSettingsAfterCog() {
$params = array();
$oldPurchase = $this->getOption("woo_purchase_value_cog");
$oldContent = $this->getOption("woo_content_value_cog");
$oldAddCart = $this->getOption("woo_add_to_cart_value_cog");
$oldInitCheckout = $this->getOption("woo_initiate_checkout_value_cog");
if($this->getOption('woo_purchase_value_option') == 'cog') {
if(!empty($oldPurchase)) $params['woo_purchase_value_option'] = $oldPurchase;
else $params['woo_purchase_value_option'] = "price";
}
if($this->getOption('woo_view_content_value_option') == 'cog') {
if(!empty($oldContent)) $params['woo_view_content_value_option'] = $oldContent;
else $params['woo_view_content_value_option'] = "price";
}
if($this->getOption('woo_add_to_cart_value_option') == 'cog') {
if(!empty($oldAddCart)) $params['woo_add_to_cart_value_option'] = $oldAddCart;
else $params['woo_add_to_cart_value_option'] = "price";
}
if($this->getOption('woo_initiate_checkout_value_option') == 'cog') {
if(!empty($oldInitCheckout)) $params['woo_initiate_checkout_value_option'] = $oldInitCheckout;
else $params['woo_initiate_checkout_value_option'] = "price";
}
$params['woo_purchase_value_cog'] = '';
$params['woo_content_value_cog'] = '';
$params['woo_add_to_cart_value_cog'] = '';
$params['woo_initiate_checkout_value_cog'] = '';
$this->updateOptions($params);
}
public function getLog() {
return $this->logger;
}
}
/**
* @return PYS
*/
function PYS() {
return PYS::instance();
}

View File

@@ -0,0 +1,822 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
abstract class Settings {
/**
* Options section slug
*
* @var string
*/
private $slug;
/**
* Options values
*
* @var array
*/
private $values = array();
/**
* Database option key
*
* @var string
*/
private $option_key = '';
/**
* Default options values
*
* @var array
*/
private $defaults = array();
/**
* List of all options
*
* @var array
*/
private $options = array();
private $defaults_json_path;
/**
* Constructor
*
* @param string $slug
*/
public function __construct( $slug ) {
$this->slug = $slug;
$this->option_key = 'pys_' . $slug;
}
public function getSlug() {
return $this->slug;
}
/**
* Load options fields and options defaults from specified files
*
* @param string $fields Path to options fields file
* @param string $defaults Path to options defaults file
*/
public function locateOptions( $fields, $defaults ) {
$this->loadJSON( $fields, false );
$this->loadJSON( $defaults, true );
$this->defaults_json_path = $defaults;
}
public function resetToDefaults() {
if ( ! file_exists( $this->defaults_json_path ) ) {
return;
}
$content = file_get_contents( $this->defaults_json_path );
$values = json_decode( $content, true );
$this->updateOptions( $values );
}
/**
* Load options fields or options defaults from specified file
*
* @param string $file
* @param bool $is_defaults
*/
private function loadJSON( $file, $is_defaults ) {
if ( ! file_exists( $file ) ) {
return;
}
$content = file_get_contents( $file );
$values = json_decode( $content, true );
if ( null === $values ) {
return;
}
if ( $is_defaults ) {
$this->defaults = $values;
} else {
$this->options = $values;
}
}
/**
* Add new option field
*
* @param string $key
* @param string $field_type
* @param mixed $default
*/
public function addOption( $key, $field_type, $default ) {
$this->options[ $key ] = $field_type;
$this->defaults[ $key ] = $default;
}
/**
* Gets an option value or its default value
*
* @param string $key Option key
* @param mixed $fallback Option fallback value if no default is set
*
* @return mixed The value specified for the option or a default value for the option.
*/
public function getOption( $key, $fallback = null ) {
$this->maybeLoad();
// get option default if unset
if ( ! isset( $this->values[ $key ] ) ) {
$this->values[ $key ] = isset( $this->defaults[ $key ] )
? $this->defaults[ $key ] : null;
}
// use fall back value if default is not set
if ( null === $this->values[ $key ] && ! is_null( $fallback ) ) {
$this->values[ $key ] = $fallback;
}
return $this->values[ $key ];
}
public function setOption($key, $value){
$this->maybeLoad();
if (isset($value) ) {
$this->values[ $key ] = $value;
}
}
/**
* Load values from database
*
* @param bool $force Force options load
*/
private function maybeLoad( $force = false ) {
if ( $force || empty( $this->values ) ) {
$this->values = get_option( $this->option_key, null );
}
// if there are no settings defined, use default values
if ( ! is_array( $this->values ) ) {
$this->values = $this->defaults;
}
}
public function reloadOptions() {
$this->maybeLoad( true );
}
/**
* Sanitize and save options
*
* @param null|array $values Optional. If set, options values will be received from param instead of $_POST.
*/
public function updateOptions( $values = null ) {
$this->maybeLoad();
if ( is_array( $values ) ) {
$form_data = $values;
} else {
$form_data = isset( $_POST['pys'][ $this->slug ] ) ? $_POST['pys'][ $this->slug ] : array();
}
// save posted fields
foreach ( $form_data as $key => $value ) {
if ( isset( $this->options[ $key ] ) ) {
$this->values[ $key ] = $this->sanitize_form_field( $key, $value );
}
}
update_option( $this->option_key, $this->values );
}
/**
* Sanitize form field
*
* @param string $key Field key
* @param array $value Field value
*
* @return mixed Sanitized field value
*/
private function sanitize_form_field( $key, $value ) {
$type = $this->options[ $key ];
// look for very specific sanitization filter
$filter_name = "{$this->option_key}_settings_sanitize_{$key}_field";
if ( has_filter( $filter_name ) ) {
return apply_filters( $filter_name, $value );
}
// look for a sanitize_FIELDTYPE_field method
if ( is_callable( array( $this, 'sanitize_' . $type . '_field' ) ) ) {
return $this->{'sanitize_' . $type . '_field'}( $value );
}
// fallback to text
return $this->sanitize_text_field( $value );
}
/**
* Output text input
*
* @param $key
* @param string $placeholder
* @param bool $disabled
* @param bool $hidden
* @param bool $empty
*/
public function render_text_input( $key, $placeholder = '', $disabled = false, $hidden = false, $empty = false) {
$attr_name = "pys[$this->slug][$key]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$attr_value = $empty == false ? $this->getOption( $key ) : "";
$classes = array( 'form-control' );
if( $hidden ) {
$classes[] = 'form-control-hidden';
}
$classes = implode( ' ', $classes );
?>
<input <?php disabled( $disabled ); ?> type="text" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
class="<?php esc_attr_e( $classes ); ?>">
<?php
}
/**
* Output pixel ID input (text)
*
* @param $key
* @param string $placeholder
* @param int $index
*/
public function render_pixel_id( $key, $placeholder = '', $index = 0 ) {
$attr_name = "pys[$this->slug][$key][]";
$attr_id = 'pys_' . $this->slug . '_' . $key . '_' . $index;
$values = (array) $this->getOption( $key );
$attr_value = isset( $values[ $index ] ) ? $values[ $index ] : null;
?>
<input type="text" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
class="form-control">
<?php
}
/**
* Output text area input array item
*
* @param $key
* @param string $placeholder
* @param int $index
*/
public function render_text_area_array_item( $key, $placeholder = '', $index = 0 ) {
$attr_name = "pys[$this->slug][$key][]";
$attr_id = 'pys_' . $this->slug . '_' . $key . '_' . $index;
$values = (array) $this->getOption( $key );
$attr_value = isset( $values[ $index ] ) ? $values[ $index ] : null;
?>
<textarea type="text" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
class="form-control"><?php esc_attr_e( $attr_value ); ?></textarea>
<?php
}
/**
* Output text input array item
*
* @param $key
* @param string $placeholder
* @param int $index
*/
public function render_text_input_array_item( $key, $placeholder = '', $index = 0,$hidden = false ) {
$attr_name = "pys[$this->slug][$key][]";
$attr_id = 'pys_' . $this->slug . '_' . $key . '_' . $index;
$values = (array) $this->getOption( $key );
$attr_value = isset( $values[ $index ] ) ? $values[ $index ] : null;
?>
<input type=<?=$hidden? "hidden": "text"?> name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
class="form-control">
<?php
}
/**
* Output text area input
*
* @param $key
* @param string $placeholder
* @param bool $disabled
* @param bool $hidden
*/
public function render_text_area_input( $key, $placeholder = '', $disabled = false, $hidden = false ) {
$attr_name = "pys[$this->slug][$key]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$attr_value = $this->getOption( $key );
$classes = array( 'form-control' );
if( $hidden ) {
$classes[] = 'form-control-hidden';
}
$classes = implode( ' ', $classes );
?>
<textarea <?php disabled( $disabled ); ?> name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>" rows="5"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
class="<?php esc_attr_e( $classes ); ?>"><?php esc_html_e( $attr_value ); ?></textarea>
<?php
}
/**
* Output checkbox input stylized as switcher
*
* @param $key
* @param bool $collapse
* @param bool $disabled
*/
public function render_switcher_input( $key, $collapse = false, $disabled = false ) {
$attr_name = "pys[$this->slug][$key]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$attr_value = $this->getOption( $key );
$classes = array( 'custom-switch' );
if ( $collapse ) {
$classes[] = 'collapse-control';
}
if ( $disabled ) {
$classes[] = 'disabled';
$attr_name = "";
$attr_value = false;
}
$classes = implode( ' ', $classes );
?>
<div class="<?php esc_attr_e( $classes ); ?>">
<?php if ( ! $disabled ) : ?>
<input type="hidden" name="<?php esc_attr_e( $attr_name ); ?>" value="0">
<?php endif; ?>
<?php if ( $collapse ) : ?>
<input type="checkbox" name="<?php esc_attr_e( $attr_name ); ?>" value="1" <?php disabled( $disabled,
true ); ?> <?php checked( $attr_value, true ); ?>
id="<?php esc_attr_e( $attr_id ); ?>"
class="custom-switch-input"
data-target="pys_<?php esc_attr_e( $this->slug ); ?>_<?php esc_attr_e( $key ); ?>_panel">
<?php else : ?>
<input type="checkbox" name="<?php esc_attr_e( $attr_name ); ?>" value="1" <?php disabled( $disabled,
true ); ?> <?php checked( $attr_value, true ); ?> id="<?php esc_attr_e( $attr_id ); ?>"
class="custom-switch-input">
<?php endif; ?>
<label class="custom-switch-btn" for="<?php esc_attr_e( $attr_id ); ?>"></label>
</div>
<?php
}
/**
* Output checkbox input
*
* @param $key
* @param $label
* @param bool $disabled
*/
public function render_checkbox_input( $key, $label, $disabled = false ) {
$attr_name = "pys[$this->slug][$key]";
$attr_value = $this->getOption( $key );
?>
<label class="custom-control custom-checkbox">
<input type="hidden" name="<?php esc_attr_e( $attr_name ); ?>" value="0">
<input type="checkbox" name="<?php esc_attr_e( $attr_name ); ?>" value="1"
class="custom-control-input" <?php disabled( $disabled, true ); ?> <?php checked( $attr_value,
true ); ?>>
<span class="custom-control-indicator"></span>
<span class="custom-control-description"><?php echo wp_kses_post( $label ); ?></span>
</label>
<?php
}
/**
* Output radio input
*
* @param $key
* @param $value
* @param $label
* @param bool $disabled
*/
public function render_radio_input( $key, $value, $label, $disabled = false, $with_pro_badge = false ) {
$attr_name = "pys[$this->slug][$key]";
?>
<label class="custom-control custom-radio">
<input type="radio" name="<?php esc_attr_e( $attr_name ); ?>" <?php disabled( $disabled, true ); ?>
class="custom-control-input" <?php checked( $this->getOption( $key ), $value ); ?>
value="<?php esc_attr_e( $value ); ?>">
<span class="custom-control-indicator"></span>
<span class="custom-control-description"><?php echo wp_kses_post( $label ); ?></span>
<?php if ( $with_pro_badge ) {
renderCogBadge();
} ?>
</label>
<?php
}
/**
* Output number input
*
* @param string $key
* @param string $placeholder
* @param bool $disabled
*/
public function render_number_input( $key, $placeholder = '', $disabled = false ) {
$attr_name = "pys[$this->slug][$key]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$attr_value = $this->getOption( $key );
?>
<input <?php disabled( $disabled ); ?> type="number" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
min="0" class="form-control">
<?php
}
/**
* Output select input
*
* @param $key
* @param $options
* @param bool $disabled
* @param null $visibility_target
* @param null $visibility_value
*/
public function render_select_input( $key, $options, $disabled = false, $visibility_target = null,
$visibility_value = null ) {
$attr_name = "pys[$this->slug][$key]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$classes = array( 'form-control-sm' );
if ( $visibility_target ) {
$classes[] = 'controls-visibility';
}
$classes = implode( ' ', $classes );
?>
<select class="<?php esc_attr_e( $classes ); ?>" id="<?php esc_attr_e( $attr_id ); ?>"
name="<?php esc_attr_e( $attr_name ); ?>" <?php disabled( $disabled ); ?>
data-target="<?php esc_attr_e( $visibility_target ); ?>"
data-value="<?php esc_attr_e( $visibility_value ); ?>" autocomplete="off">
<option value="" disabled selected>Please, select...</option>
<?php foreach ( $options as $option_key => $option_value ) : ?>
<option value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key,
esc_attr( $this->getOption( $key ) ) ); ?> <?php disabled( $option_key,
'disabled' ); ?>><?php echo esc_attr( $option_value ); ?></option>
<?php endforeach; ?>
</select>
<?php
}
/**
* Output multi select input
*
* @param $key
* @param $values
* @param bool $disabled
*/
public function render_multi_select_input( $key, $values, $disabled = false ) {
$attr_name = "pys[$this->slug][$key][]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$selected = $this->getOption( $key );
?>
<input type="hidden" name="<?php esc_attr_e( $attr_name ); ?>" value="">
<select class="form-control pys-pysselect2" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>" <?php disabled( $disabled ); ?> style="width: 100%;"
multiple>
<?php foreach ( $values as $option_key => $option_value ) : ?>
<option value="<?php echo esc_attr( $option_key ); ?>"
<?php selected( in_array( $option_key, $selected ) ); ?>
<?php disabled( $option_key, 'disabled' ); ?>
>
<?php echo esc_attr( $option_value ); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
/**
* Output tags select input
*
* @param $key
* @param bool $disabled
*/
public function render_tags_select_input( $key, $disabled = false ) {
$attr_name = "pys[$this->slug][$key][]";
$attr_id = 'pys_' . $this->slug . '_' . $key;
$tags = $this->getOption( $key );
$tags = is_array( $tags ) ? array_filter( $tags ) : array();
?>
<input type="hidden" name="<?php esc_attr_e( $attr_name ); ?>" value="">
<select class="form-control pys-tags-pysselect2" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>" <?php disabled( $disabled ); ?> style="width: 100%;"
multiple>
<?php foreach ( $tags as $tag ) : ?>
<option value="<?php echo esc_attr( $tag ); ?>" selected>
<?php echo esc_attr( $tag ); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
/**
* Sanitize text field value
*
* @param $value
*
* @return string
*/
public function sanitize_text_field( $value ) {
$value = is_null( $value ) ? '' : $value;
return wp_kses_post( trim( stripslashes( $value ) ) );
}
/**
* Sanitize textarea field value
*
* @param $value
*
* @return string
*/
public function sanitize_textarea_field( $value ){
$value = is_null( $value ) ? '' : $value;
return trim( stripslashes( $value ) );
}
/**
* Sanitize number field value
*
* @param $value
*
* @return int
*/
public function sanitize_number_field( $value ) {
return (int) $value;
}
/**
* Sanitize checkbox field value
*
* @param $value
*
* @return bool
*/
public function sanitize_checkbox_field( $value ) {
if ( is_bool( $value ) || is_numeric( $value ) ) {
return (bool) $value;
} else {
return false;
}
}
/**
* Sanitize radio field value
*
* @param $value
*
* @return null|string
*/
public function sanitize_radio_field( $value ) {
return ! is_null( $value ) ? trim( stripslashes( $value ) ) : null;
}
/**
* Sanitize select field value
*
* @see deepSanitizeTextField()
*
* @param $value
*
* @return array|string
*/
public function sanitize_select_field( $value ) {
$value = is_null( $value ) ? '' : $value;
return deepSanitizeTextField( stripslashes( $value ) );
}
/**
* Sanitize tags select value
*
* @see deepSanitizeTextField()
*
* @param $value
*
* @return array
*/
public function sanitize_multi_select_field( $value ) {
return is_array( $value ) ? array_map( 'PixelYourSite\deepSanitizeTextField', $value ) : array();
}
/**
* @param $value
*
* @return array
*/
public function sanitize_tag_select_field( $value ) {
return is_array( $value ) ? array_map( 'PixelYourSite\deepSanitizeTextField', $value ) : array();
}
/**
* Sanitize array field value
*
* @param $values
*
* @return array
*/
public function sanitize_array_field( $values ) {
$values = is_array( $values ) ? $values : array();
$sanitized = array();
foreach ( $values as $key => $value ) {
$new_value = $this->sanitize_text_field( $value );
if ( ! empty( $new_value ) && ! in_array( $new_value, $sanitized ) ) {
$sanitized[ $key ] = $new_value;
}
}
return $sanitized;
}
/**
* Sanitize array field value
*
* @param $values
*
* @return array
*/
public function sanitize_array_textarea_field( $values ) {
$values = is_array( $values ) ? $values : array();
$sanitized = array();
foreach ( $values as $key => $value ) {
$new_value = $this->sanitize_textarea_field( $value );
if ( ! empty( $new_value ) && ! in_array( $new_value, $sanitized ) ) {
$sanitized[ $key ] = $new_value;
}
}
return $sanitized;
}
public function render_checkbox_input_array( $key, $label, $index = 0, $disabled = false ) {
$attr_name = "pys[$this->slug][$key][]";
$attr_values = (array)$this->getOption( $key );
$value = "index_".$index;
$valueIndex = array_search($value,$attr_values);
?>
<label class="custom-control custom-checkbox">
<input type="checkbox" name="<?php esc_attr_e( $attr_name ); ?>" value="<?=$value?>"
class="custom-control-input" <?php disabled( $disabled, true ); ?>
<?=$valueIndex !== false ? "checked" : "" ?>>
<span class="custom-control-indicator"></span>
<span class="custom-control-description"><?php echo wp_kses_post( $label ); ?></span>
</label>
<?php
}
public function convertTimeToSeconds($timeValue = 24, $type = 'hours')
{
switch ($type){
case 'hours':
$time = $timeValue * 60 * 60;
break;
case 'minute':
$time = $timeValue * 60;
break;
case 'seconds':
$time = $timeValue;
break;
}
return $time;
}
}

View File

@@ -0,0 +1,128 @@
<?php
namespace PixelYourSite;
class EnrichOrder {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function init() {
//woo
if(PYS()->getOption("woo_enabled_save_data_to_orders")) {
add_action( 'woocommerce_checkout_update_order_meta',array($this,'woo_save_checkout_fields'),10, 2);
add_action( 'add_meta_boxes', array($this,'woo_add_order_meta_boxes') );
if(PYS()->getOption("woo_add_enrich_to_admin_email")) {
add_action( 'woocommerce_email_customer_details', array($this,'woo_add_enrich_to_admin_email'),80,4 );
}
}
// edd
if(PYS()->getOption("edd_enabled_save_data_to_orders")) {
add_filter('edd_payment_meta', array($this, 'edd_save_checkout_fields'),10,2);
add_action('edd_view_order_details_main_after', array($this, 'add_edd_order_details'));
}
}
function add_edd_order_details($payment_id) {
echo '<div id="edd-payment-notes" class="postbox">
<h3 class="hndle"><span>PixelYourSite</span></h3>';
echo "<div style='margin:20px'><p>With the paid plugin, you can see more data on the Easy Digital Downloads Reports page.
<a target='_blank' href='https://www.pixelyoursite.com/easy-digital-downloads-first-party-reports/?utm_source=free-plugin-edd-order&utm_medium=free-plugin-edd-order&utm_campaign=free-plugin-edd-order&utm_content=free-plugin-edd-order&utm_term=free-plugin-edd-order'>Click here for details.</a>
</p>You can stop storing this data from the plugin's <a href='".admin_url("admin.php?page=pixelyoursite&tab=edd")."' target='_blank'>Easy Digital Downloads page</a></div>";
include 'views/html-edd-order-box.php';
echo '</div>';
}
function woo_add_order_meta_boxes () {
$screen = isWooUseHPStorage()
? wc_get_page_screen_id( 'shop-order' )
: 'shop_order';
add_meta_box( 'pys_enrich_fields_woo', __('PixelYourSite','pixelyoursite'),
array($this,"woo_render_order_fields"), $screen);
}
function woo_render_order_fields($post) {
$orderId = ( $post instanceof \WP_Post ) ? $post->ID : $post->get_id();
echo "<div style='margin:20px 10px'><p>With the paid plugin, you can see more data on the WooCommerce Reports page.
<a href='https://www.pixelyoursite.com/woocommerce-first-party-reports?utm_source=free-plugin&utm_medium=order-page&utm_campaign=reports-order-page&utm_content=woocommerce-reports-client-page&utm_term=order-page-reports' target='_blank'>Click here for details</a>
</p>You can stop storing this data from the plugin's <a href='".admin_url("admin.php?page=pixelyoursite&tab=woo")."' target='_blank'>WooCommerce page</a>.</div>";
include 'views/html-order-meta-box.php';
}
function woo_save_checkout_fields($order_id, $data) {
$pysData = [];
$pysData['pys_landing'] = isset($_REQUEST['pys_landing']) ? sanitize_text_field($_REQUEST['pys_landing']) : "";
$pysData['pys_source'] = isset($_REQUEST['pys_source']) ? sanitize_text_field($_REQUEST['pys_source']) : "";
$pysData['pys_utm'] = isset($_REQUEST['pys_utm']) ? sanitize_text_field($_REQUEST['pys_utm']) : "";
$pysData['pys_browser_time'] = isset($_REQUEST['pys_browser_time']) ? sanitize_text_field($_REQUEST['pys_browser_time']) : "";
$pysData['last_pys_landing'] = isset($_REQUEST['last_pys_landing']) ? sanitize_text_field($_REQUEST['last_pys_landing']) : "";
$pysData['last_pys_source'] = isset($_REQUEST['last_pys_source']) ? sanitize_text_field($_REQUEST['last_pys_source']) : "";
$pysData['last_pys_utm'] = isset($_REQUEST['last_pys_utm']) ? sanitize_text_field($_REQUEST['last_pys_utm']) : "";
$pysData['pys_utm_id'] = isset($_REQUEST['pys_utm_id']) ? sanitize_text_field($_REQUEST['pys_utm_id']) : "";
$pysData['last_pys_utm_id'] = isset($_REQUEST['last_pys_utm_id']) ? sanitize_text_field($_REQUEST['last_pys_utm_id']) : "";
$order = wc_get_order($order_id);
if($order) {
$order->update_meta_data("pys_enrich_data",$pysData);
$order->save();
}
}
/**
* @param \WC_Order$order
* @param $sent_to_admin
* @param $plain_text
* @param $email
*/
function woo_add_enrich_to_admin_email($order, $sent_to_admin) {
if($sent_to_admin) {
$orderId = $order->get_id();
echo "<h2 style='text-align: center'>". __('PixelYourSite','pixelyoursite')."</h2>";
echo "Your clients don't see this information! We send it to you in this \"New Order\" email. If you want to remove this data from the \"New Order\" email, open <a href='".admin_url("admin.php?page=pixelyoursite&tab=woo")."' target='_blank'>PixelYourSite's WooCommerce page</a>, disable \"Send reports data to the New Order email\" and save.
<br/>With PixelYourSite Professional, you can view and download this data from the plugin's own reports page. Find out how WooCommerce Reports work and how to visualize and download your data: <a href='https://www.pixelyoursite.com/woocommerce-first-party-reports?utm_source=free-plugin&utm_medium=order-email&utm_campaign=order-email-link&utm_content=woocommerce-reports&utm_term=woocommerce-reports-email-link' target='_blank'>Click here for details</a>.<br/>";
include 'views/html-order-meta-box.php';
}
}
function edd_save_checkout_fields( $payment_meta ,$init_payment_data) {
if ( 0 !== did_action('edd_pre_process_purchase') ) {
$pysData = [];
$pysData['pys_landing'] = isset($_POST['pys_landing']) ? sanitize_text_field($_POST['pys_landing']) : "";
$pysData['pys_source'] = isset($_POST['pys_source']) ? sanitize_text_field($_POST['pys_source']) : "";
$pysData['pys_utm'] = isset($_POST['pys_utm']) ? sanitize_text_field($_POST['pys_utm']) : "";
$pysData['pys_browser_time'] = isset($_POST['pys_browser_time']) ? sanitize_text_field($_POST['pys_browser_time']) : "";
$pysData['last_pys_landing'] = isset($_REQUEST['last_pys_landing']) ? sanitize_text_field($_REQUEST['last_pys_landing']) : "";
$pysData['last_pys_source'] = isset($_REQUEST['last_pys_source']) ? sanitize_text_field($_REQUEST['last_pys_source']) : "";
$pysData['last_pys_utm'] = isset($_REQUEST['last_pys_utm']) ? sanitize_text_field($_REQUEST['last_pys_utm']) : "";
$pysData['pys_utm_id'] = isset($_REQUEST['pys_utm_id']) ? sanitize_text_field($_REQUEST['pys_utm_id']) : "";
$pysData['last_pys_utm_id'] = isset($_REQUEST['last_pys_utm_id']) ? sanitize_text_field($_REQUEST['last_pys_utm_id']) : "";
$payment_meta['pys_enrich_data'] = $pysData;
}
return $payment_meta;
}
}
/**
* @return EnrichOrder
*/
function EnrichOrder() {
return EnrichOrder::instance();
}
EnrichOrder();

View File

@@ -0,0 +1,41 @@
<?php
namespace PixelYourSite\Enrich;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @param array $utms
*/
function printUtm($utms) {
$utmList = [];
$utmKeys = [
"utm_source",
"utm_medium",
"utm_campaign",
"utm_content",
"utm_term",
];
foreach($utms as $utm) {
$item = explode(":",$utm);
$name = $item[0];
$value = $item[1] == "undefined" ? "No ".$name." detected for this order" : $item[1];
$utmList[$name] = $value;
}
foreach ($utmKeys as $key) {
if(key_exists($key,$utmList)) {
?>
<tr>
<th><?=$key?>:</th>
<td><?=$utmList[$key]?></td>
</tr>
<?php
}
}
}

View File

@@ -0,0 +1,105 @@
<?php
include_once "function-helper.php";
$payment = new EDD_Payment( $payment_id );
$meta = $payment->get_meta();
?>
<style>
table.pys_order_meta {
width: 100%;text-align:left
}
table.pys_order_meta td.border span {
border-top: 1px solid #f1f1f1;
display: block;
}
table.pys_order_meta th,
table.pys_order_meta td {
padding:10px
}
</style>
<div class="inside">
<?php if(isset($meta['pys_enrich_data'])) :
$data = $meta['pys_enrich_data'];
?>
<table class="pys_order_meta">
<tr>
<td colspan="2" ><strong>FIRST VISIT</strong></td>
</tr>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<tr >
<th>Landing Page:</th>
<td><a href="<?=$data['pys_landing']?>" target="_blank" ><?=$data['pys_landing']?></a></td>
</tr>
<tr>
<th>Traffic source:</th>
<td><?=$data['pys_source']?></td>
</tr>
<?php
$utms = explode("|",$data['pys_utm']);
\PixelYourSite\Enrich\printUtm($utms);
?>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<tr>
<td colspan="2" ><strong>LAST VISIT</strong></td>
</tr>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<tr >
<?php
$lastLanding = isset($data['last_pys_landing']) ? $data['last_pys_landing'] : "";?>
<th>Landing Page:</th>
<td><a href="<?=$lastLanding?>" target="_blank" ><?=$lastLanding?></a></td>
</tr>
<tr>
<th>Traffic source:</th>
<td><?= isset($data['last_pys_source']) ? $data['last_pys_source'] : ""?></td>
</tr>
<?php
if(!empty($data['last_pys_utm'])) {
$utms = explode("|",$data['last_pys_utm']);
\PixelYourSite\Enrich\printUtm($utms);
}
?>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<?php
$userTime = explode("|",$data['pys_browser_time']);
?>
<tr >
<th>Client's browser time</th>
<td></td>
</tr>
<tr >
<th>Hour:</th>
<td><?=$userTime[0]?></td>
</tr>
<tr >
<th>Day:</th>
<td><?=$userTime[1]?></td>
</tr>
<tr >
<th>Month:</th>
<td><?=$userTime[2]?></td>
</tr>
<tr>
<td colspan="2" class="border"<td><span></span></td>
</tr>
</table>
<?php else: ?>
<h2>No data</h2>
<?php endif; ?>
</div>

View File

@@ -0,0 +1,104 @@
<?php
include_once "function-helper.php";
$order = wc_get_order($orderId);
$data = $order->get_meta("pys_enrich_data",true);
$dataAnalytics = $order->get_meta("pys_enrich_data_analytics",true);
if($dataAnalytics && is_array($dataAnalytics) && is_array($data)) {
$data = array_merge($data,$dataAnalytics);
}
if($data && is_array($data)) :
?>
<style>
table.pys_order_meta {
width: 100%;text-align:left
}
table.pys_order_meta td.border span {
border-top: 1px solid #f1f1f1;
display: block;
}
table.pys_order_meta th,
table.pys_order_meta td {
padding:10px
}
</style>
<table class="pys_order_meta">
<tr>
<td colspan="2" ><strong>FIRST VISIT</strong></td>
</tr>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<tr >
<th>Landing Page:</th>
<td><a href="<?=$data['pys_landing']?>" target="_blank" ><?=$data['pys_landing']?></a></td>
</tr>
<tr>
<th>Traffic source:</th>
<td><?=isset($data['pys_source']) ? $data['pys_source'] : ""?></td>
</tr>
<?php
if(!empty($data['pys_utm'])) {
$utms = explode("|",$data['pys_utm']);
\PixelYourSite\Enrich\printUtm($utms);
}
?>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<tr>
<td colspan="2" ><strong>LAST VISIT</strong></td>
</tr>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<tr >
<?php
$lastLanding = isset($data['last_pys_landing']) ? $data['last_pys_landing'] : "";?>
<th>Landing Page:</th>
<td><a href="<?=$lastLanding?>" target="_blank" ><?=$lastLanding?></a></td>
</tr>
<tr>
<th>Traffic source:</th>
<td><?=isset($data['last_pys_source']) ? $data['last_pys_source'] : ""?></td>
</tr>
<?php
if(!empty($data['last_pys_utm'])) {
$utms = explode("|",$data['last_pys_utm']);
\PixelYourSite\Enrich\printUtm($utms);
}
?>
<tr>
<td colspan="2" class="border"><span></span></td>
</tr>
<?php
if(!empty($data['pys_browser_time'])) :
$userTime = explode("|",$data['pys_browser_time']);
?>
<tr >
<th>Client's browser time</th>
<td></td>
</tr>
<tr >
<th>Hour:</th>
<td><?=$userTime[0]?></td>
</tr>
<tr >
<th>Day:</th>
<td><?=$userTime[1]?></td>
</tr>
<tr >
<th>Month:</th>
<td><?=$userTime[2]?></td>
</tr>
<?php endif; ?>
</table>
<?php else: ?>
<h2>No data</h2>
<?php endif; ?>

View File

@@ -0,0 +1,29 @@
<?php
namespace PixelYourSite;
/**
* @deprecated
*/
class GroupedEvent extends PYSEvent
{
private $events = array();
public function __construct($id, $type,$category='') {
parent::__construct($id, $type,$category);
}
/**
* @param PYSEvent $event
*/
public function addEvent($event) {
$this->events[] = $event;
}
/**
* @return PYSEvent[]
*/
public function getEvents() {
return $this->events;
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace PixelYourSite;
class SingleEvent extends PYSEvent{
public $params = array(
);
public $payload = array(
'delay' => 0
);
public function __construct($id,$type,$category=''){
parent::__construct($id,$type,$category);
$this->payload['type'] = $type;
}
/**
* Insert Array params for event
* @param array $data
*/
function addParams($data) {
if(is_array($data)) {
$this->params = array_merge($this->params,$data);
} else {
error_log("addParams no array ".print_r($data,true));
}
}
/**
* Insert additional Array data for event
* @param array $data
*/
function addPayload($data) {
if(is_array($data)) {
$this->payload = array_merge($this->payload,$data);
} else {
error_log("addPayload no array ".print_r($data,true));
}
}
function getData() {
$data = $this->payload;
$data['params'] = sanitizeParams($this->params);
$data['e_id'] = $this->getId();
$data['delay'] = isset( $this->payload['delay'] ) ? $this->payload['delay'] : 0;
$data['ids'] = isset( $this->payload['ids'] ) ? $this->payload['ids'] : array();
$data['hasTimeWindow'] = isset( $this->payload['hasTimeWindow'] ) ? $this->payload['hasTimeWindow'] : false;
$data['timeWindow'] = isset( $this->payload['timeWindow'] ) ? $this->payload['timeWindow'] : 0;
$data['pixelIds'] = isset( $this->payload['pixelIds'] ) ? $this->payload['pixelIds'] : array();
$data['eventID'] = isset( $this->payload['eventID'] ) ? $this->payload['eventID'] : "";
$data['woo_order'] = isset( $this->payload['woo_order'] ) ? $this->payload['woo_order'] : "";
$data['edd_order'] = isset( $this->payload['edd_order'] ) ? $this->payload['edd_order'] : "";
return $data;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace PixelYourSite;
class EventTypes {
static public $DYNAMIC = "dyn";
static public $STATIC = "static";
static public $TRIGGER = "trigger";
}
abstract class PYSEvent {
protected $id;
protected $type;
protected $category;
public $args = null;
/**
* GroupedEvent constructor.
* @param String $id // unique id use in js object like key
* @param String $type // can be static(fire when open page) or dynamic (fire when some event did)
* @param String $category // event category like woo, edd signal etc
*/
public function __construct($id,$type,$category=''){
$this->id = $id;
$this->type = $type;
$this->category = $category;
}
function getId() {
return $this->id;
}
function getType() {
return $this->type;
}
function getCategory() {
return $this->category;
}
}

View File

@@ -0,0 +1,166 @@
<?php
namespace PixelYourSite;
/*
* Automatic Events we will fire this event in order to capture all actions like clicks, video
views, downloads, comments, forms.
* */
class EventsAutomatic extends EventsFactory {
private static $_instance;
private $events = array(
'automatic_event_form' ,
'automatic_event_signup' ,
'automatic_event_login' ,
'automatic_event_download' ,
'automatic_event_comment' ,
'automatic_event_scroll' ,
'automatic_event_time_on_page' ,
'automatic_event_search' ,
);
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
private function __construct() {
add_filter("pys_event_factory",[$this,"register"]);
}
function register($list) {
$list[] = $this;
return $list;
}
static function getSlug() {
return "automatic";
}
function getEvents() {
return $this->events;
}
function getCount() {
$count = 0;
if($this->isEnabled()) {
foreach ($this->events as $event) {
if(PYS()->getOption($event."_enabled")) {
$count++;
}
}
}
return $count;
}
function isEnabled() {
return PYS()->getOption("automatic_events_enabled");
}
// return option for js part
function getOptions() {
return array(
);
}
/**
* Check is event ready for fire
* @param $event
* @return bool
*/
function isReadyForFire($event) {
if(!$this->isEnabled()) return false;
if(!in_array($event,$this->events)) return false;
switch($event) {
case "automatic_event_login" : {
if($user_id = get_current_user_id()) {
if (get_user_meta($user_id, 'pys_just_login', true)) {
delete_user_meta($user_id, 'pys_just_login');
return PYS()->getOption( $event."_enabled");
}
}
return false;
}
case 'automatic_event_signup' : {
if ( $user_id = get_current_user_id() ) {
if ( get_user_meta( $user_id, 'pys_complete_registration', true ) ) {
return PYS()->getOption( $event."_enabled");
}
}
return false;
}
case 'automatic_event_search' : {
return PYS()->getOption( $event."_enabled") && is_search();
}
default: {
return PYS()->getOption( $event."_enabled");
}
}
}
/**
* @param String $event
* @return SingleEvent
*/
function getEvent($event) {
$payload = [];
$params = [];
$item = new SingleEvent($event,EventTypes::$DYNAMIC,self::getSlug());
switch ($event) {
case "automatic_event_form": {
$payload['name'] = 'Form';
}break;
case "automatic_event_download": {
$payload['name'] = 'Download';
$payload["extensions"] = PYS()->getOption( 'automatic_event_download_extensions' );
}break;
case "automatic_event_comment": {
$payload['name'] = 'Comment';
}break;
case "automatic_event_scroll": {
$payload['name'] = 'PageScroll';
$payload["scroll_percent"] = PYS()->getOption('automatic_event_scroll_value');
}break;
case "automatic_event_time_on_page": {
$payload['name'] = 'TimeOnPage';
$payload["time_on_page"] = PYS()->getOption('automatic_event_time_on_page_value');
}break;
case "automatic_event_search":
case "automatic_event_signup":
case "automatic_event_login": {
$item = new SingleEvent($event,EventTypes::$STATIC,self::getSlug());
} break;
}
$item->addParams($params);
$item->addPayload($payload);
return $item;
}
}
/**
* @return EventsAutomatic
*/
function EventsAutomatic() {
return EventsAutomatic::instance();
}
EventsAutomatic();

View File

@@ -0,0 +1,91 @@
<?php
namespace PixelYourSite;
class EventsCustom extends EventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
static function getSlug() {
return "custom";
}
private function __construct() {
add_filter("pys_event_factory",[$this,"register"]);
}
function register($list) {
$list[] = $this;
return $list;
}
function getEvents(){
return CustomEventFactory::get( 'active' );
}
function getCount()
{
if(!$this->isEnabled()) {
return 0;
}
return count($this->getEvents());
}
function isEnabled()
{
return PYS()->getOption( 'custom_events_enabled' );
}
function getOptions()
{
return array();
}
/**
* @param CustomEvent $event
* @return bool
*/
function isReadyForFire($event)
{
switch ($event->getTriggerType()) {
case 'page_visit': {
$triggers = $event->getPageVisitTriggers();
return !empty( $triggers ) && compareURLs( $triggers );
}
}
return false;
}
/**
* @param CustomEvent $event
* @return PYSEvent
*/
function getEvent($event)
{
switch ($event->getTriggerType()) {
case 'page_visit': {
$singleEvent = new SingleEvent('custom_event',EventTypes::$STATIC,'custom');
$singleEvent->args = $event;
return $singleEvent;
}
}
}
}
/**
* @return EventsCustom
*/
function EventsCustom() {
return EventsCustom::instance();
}
EventsCustom();

View File

@@ -0,0 +1,223 @@
<?php
namespace PixelYourSite;
class EventsEdd extends EventsFactory {
private $events = array(
//'edd_frequent_shopper', pro
//'edd_vip_client',pro
//'edd_big_whale',pro
'edd_view_content',
'edd_view_category',
'edd_add_to_cart_on_checkout_page',
'edd_remove_from_cart',
'edd_initiate_checkout',
'edd_purchase',
'edd_add_to_cart_on_button_click'
);
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
static function getSlug() {
return "edd";
}
private function __construct() {
add_filter("pys_event_factory",[$this,"register"]);
}
function register($list) {
$list[] = $this;
return $list;
}
function getEvents() {
return $this->events;
}
function getCount()
{
$size = 0;
if(!$this->isEnabled()) {
return 0;
}
foreach ($this->events as $event) {
if($this->isActive($event)){
$size++;
}
}
return $size;
}
function isEnabled()
{
return isEddActive();
}
function getOptions()
{
if($this->isEnabled()) {
return array(
'enabled' => true,
'enabled_save_data_to_orders' => PYS()->getOption('edd_enabled_save_data_to_orders'),
'addToCartOnButtonEnabled' => isEventEnabled( 'edd_add_to_cart_enabled' ) && PYS()->getOption( 'edd_add_to_cart_on_button_click' ),
'addToCartOnButtonValueEnabled' => PYS()->getOption( 'edd_add_to_cart_value_enabled' ),
'addToCartOnButtonValueOption' => PYS()->getOption( 'edd_add_to_cart_value_option' ),
);
} else {
return array(
'enabled' => false
);
}
}
function isReadyForFire($event)
{
switch ($event) {
case 'edd_add_to_cart_on_button_click': {
return PYS()->getOption( 'edd_add_to_cart_enabled' ) && PYS()->getOption( 'edd_add_to_cart_on_button_click' );
}
case 'edd_purchase': {
if(PYS()->getOption( 'edd_purchase_enabled' ) && edd_is_success_page()) {
/**
* When a payment gateway used, user lands to Payment Confirmation page first, which does automatic
* redirect to Purchase Confirmation page. We filter Payment Confirmation to avoid double Purchase event.
*/
if ( isset( $_GET['payment-confirmation'] ) ) {
//@fixme: some users will not reach success page and event will not be fired
//return;
}
$payment_key = getEddPaymentKey();
$order_id = (int) edd_get_purchase_id_by_key( $payment_key );
$status = edd_get_payment_status( $order_id );
// pending payment status used because we can't fire event on IPN
if ( strtolower( $status ) != 'publish' && strtolower( $status ) != 'pending' && strtolower( $status ) != 'complete' ) {
return false;
}
update_post_meta( $order_id, '_pys_purchase_event_fired', true );
return true;
}
return false;
}
case 'edd_initiate_checkout': {
return PYS()->getOption( 'edd_initiate_checkout_enabled' ) && edd_is_checkout();
}
case 'edd_remove_from_cart': {
return PYS()->getOption( 'edd_remove_from_cart_enabled') && edd_is_checkout();
}
case 'edd_add_to_cart_on_checkout_page' : {
return PYS()->getOption( 'edd_add_to_cart_enabled' ) && PYS()->getOption( 'edd_add_to_cart_on_checkout_page' )
&& edd_is_checkout();
}
case 'edd_view_category': {
return PYS()->getOption( 'edd_view_category_enabled' ) && is_tax( 'download_category' );
}
case 'edd_view_content' : {
return PYS()->getOption( 'edd_view_content_enabled' ) && is_singular( 'download' );
}
}
return false;
}
function getEvent($event)
{
switch ($event) {
case 'edd_initiate_checkout':
case 'edd_purchase':
case 'edd_add_to_cart_on_checkout_page' :
case 'edd_view_category':
case 'edd_view_content':{
return new SingleEvent($event,EventTypes::$STATIC,'edd');
}
case 'edd_remove_from_cart': {
return $this->getRemoveFromCartEvents($event);
}
case 'edd_add_to_cart_on_button_click': {
return new SingleEvent($event,EventTypes::$DYNAMIC,'edd');
}
}
}
private function isActive($event)
{
switch ($event) {
case 'edd_add_to_cart_on_button_click': {
return PYS()->getOption( 'edd_add_to_cart_enabled' ) && PYS()->getOption( 'edd_add_to_cart_on_button_click' );
}
case 'edd_purchase': {
return PYS()->getOption( 'edd_purchase_enabled' );
}
case 'edd_initiate_checkout': {
return PYS()->getOption( 'edd_initiate_checkout_enabled' ) ;
}
case 'edd_remove_from_cart': {
return PYS()->getOption( 'edd_remove_from_cart_enabled');
}
case 'edd_add_to_cart_on_checkout_page' : {
return PYS()->getOption( 'edd_add_to_cart_enabled' ) && PYS()->getOption( 'edd_add_to_cart_on_checkout_page' );
}
case 'edd_view_category': {
return PYS()->getOption( 'edd_view_category_enabled' ) ;
}
case 'edd_view_content' : {
return PYS()->getOption( 'edd_view_content_enabled' ) ;
}
}
return false;
}
private function getRemoveFromCartEvents($eventId) {
$events = [];
foreach (edd_get_cart_contents() as $cart_item_key => $cart_item) {
$event = new SingleEvent($eventId,EventTypes::$DYNAMIC,self::getSlug());
$event->args = ['key'=>$cart_item_key,'item'=>$cart_item];
$events[]=$event;
}
return $events;
}
private function getEddCartActiveCategories($categoryPixels){
$catIds = array();
$keys = array_keys($categoryPixels);
$cart = edd_get_cart_contents();
foreach ( $cart as $cart_item_key => $cart_item ) {
$download_id = (int) $cart_item['id'];
$productCatIds = Facebook\HelpersCategory\getIntersectEddProduct($download_id,$keys);
foreach ($productCatIds as $id) {
if(!in_array($categoryPixels[$id],$catIds)) // disable duplicate pixel_id
$catIds[]=$id;
}
}
return array_unique($catIds);
}
}
/**
* @return EventsEdd
*/
function EventsEdd() {
return EventsEdd::instance();
}
EventsEdd();

View File

@@ -0,0 +1,95 @@
<?php
namespace PixelYourSite;
class EventsFdp extends EventsFactory
{
private $events = array(
'fdp_view_content',
'fdp_view_category',
'fdp_add_to_cart',
'fdp_purchase',
);
private static $_instance;
public static function instance()
{
if (is_null(self::$_instance)) {
self::$_instance = new self();
}
return self::$_instance;
}
static function getSlug() {
return "fdp";
}
private function __construct()
{
add_filter("pys_event_factory",[$this,"register"]);
}
function register($list) {
$list[] = $this;
return $list;
}
function getEvents() {
return $this->events;
}
function getCount()
{
return 0;
}
function isEnabled()
{
return Facebook()->enabled() && PYS()->getOption( 'fdp_enabled' );
}
function getOptions()
{
return array();
}
function isReadyForFire($event)
{
switch ($event) {
case 'fdp_purchase':
case 'fdp_add_to_cart':
case 'fdp_view_content': {
return is_single() && get_post_type() == 'post';
}
case 'fdp_view_category': {
return is_category();
}
}
}
function getEvent($event)
{
switch ($event) {
case 'fdp_view_category':
case 'fdp_view_content': {
return new SingleEvent($event,EventTypes::$STATIC,'fdp');
}
case 'fdp_add_to_cart':
case 'fdp_purchase': {
return new SingleEvent($event,EventTypes::$TRIGGER,'fdp');
}
}
}
}
/**
* @return EventsFdp
*/
function EventsFdp() {
return EventsFdp::instance();
}
EventsFdp();

View File

@@ -0,0 +1,320 @@
<?php
namespace PixelYourSite;
class EventsWoo extends EventsFactory {
private $events = array(
//"woo_frequent_shopper",
//"woo_vip_client",
//"woo_big_whale",
"woo_view_content",
//"woo_view_content_for_category",
"woo_view_category",
"woo_view_item_list",
//"woo_view_item_list_single",
//"woo_view_item_list_search",
//"woo_view_item_list_shop",
//"woo_view_item_list_tag",
"woo_add_to_cart_on_cart_page",
//"woo_add_to_cart_on_cart_page_category",
"woo_add_to_cart_on_checkout_page",
//"woo_add_to_cart_on_checkout_page_category",
"woo_initiate_checkout",
//"woo_initiate_checkout_category",
"woo_purchase",
//"woo_initiate_set_checkout_option",
//"woo_initiate_checkout_progress_f",
//"woo_initiate_checkout_progress_l",
//"woo_initiate_checkout_progress_e",
//"woo_initiate_checkout_progress_o",
"woo_remove_from_cart",
"woo_add_to_cart_on_button_click",
//"woo_affiliate",
//"woo_paypal",
//"woo_select_content_category",
//"woo_select_content_single",
//"woo_select_content_search",
//"woo_select_content_shop",
// "woo_select_content_tag",
);
public $doingAMP = false;
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
static function getSlug() {
return "woo";
}
private function __construct() {
add_filter("pys_event_factory",[$this,"register"]);
}
function register($list) {
$list[] = $this;
return $list;
}
function getCount()
{
$size = 0;
if(!$this->isEnabled()) {
return 0;
}
foreach ($this->events as $event) {
if($this->isActive($event)){
$size++;
}
}
if(PYS()->getOption( 'woo_complete_registration_enabled' ))
$size++;
return $size;
}
function isEnabled()
{
return isWooCommerceActive();
}
function getOptions() {
if($this->isEnabled()) {
global $post;
$data = array(
'enabled' => true,
'enabled_save_data_to_orders' => PYS()->getOption('woo_enabled_save_data_to_orders'),
'addToCartOnButtonEnabled' => PYS()->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' ),
'addToCartOnButtonValueEnabled' => PYS()->getOption( 'woo_add_to_cart_value_enabled' ),
'addToCartOnButtonValueOption' => PYS()->getOption( 'woo_add_to_cart_value_option' ),
'singleProductId' => isWooCommerceActive() && is_singular( 'product' ) ? $post->ID : null,
'removeFromCartSelector' => isWooCommerceVersionGte( '3.0.0' )
? 'form.woocommerce-cart-form .remove'
: '.cart .product-remove .remove',
'addToCartCatchMethod' => PYS()->getOption('woo_add_to_cart_catch_method')
);
return $data;
} else {
return array(
'enabled' => false,
);
}
}
function isReadyForFire($event)
{
switch ($event) {
case 'woo_add_to_cart_on_button_click': {
return PYS()->getOption( 'woo_add_to_cart_enabled' )
&& PYS()->getOption( 'woo_add_to_cart_on_button_click' )
&& PYS()->getOption('woo_add_to_cart_catch_method') == "add_cart_js"; // or use in hook
}
case 'woo_remove_from_cart': {
return PYS()->getOption( 'woo_remove_from_cart_enabled') && is_cart();
}
case 'woo_purchase' : {
if(PYS()->getOption( 'woo_purchase_enabled' ) && is_order_received_page() &&
isset( $_REQUEST['key'] ) && $_REQUEST['key'] != ""
&& empty($_REQUEST['wc-api']) // if is not api request
) {
$order_key = sanitize_key($_REQUEST['key']);
$order_id = (int) wc_get_order_id_by_order_key( $order_key );
$order = wc_get_order($order_id);
if(!$order) return false;
$status = "wc-".$order->get_status("edit");
$disabledStatuses = (array)PYS()->getOption("woo_order_purchase_disabled_status");
if( in_array($status,$disabledStatuses)) {
return false;
}
return true;
}
return false;
}
case 'woo_view_content' : {
return PYS()->getOption( 'woo_view_content_enabled' ) && is_product();
}
case 'woo_view_category': {
return PYS()->getOption( 'woo_view_category_enabled' ) && is_tax( 'product_cat' );
}
case 'woo_view_item_list': {
return PYS()->getOption( 'woo_view_item_list_enabled' ) && is_tax( 'product_cat' );
}
case 'woo_add_to_cart_on_cart_page': {
return PYS()->getOption( 'woo_add_to_cart_enabled' ) &&
PYS()->getOption( 'woo_add_to_cart_on_cart_page' ) &&
is_cart()
&& count(WC()->cart->get_cart())>0;
}
case 'woo_add_to_cart_on_checkout_page': {
return PYS()->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_checkout_page' )
&& is_checkout() && ! is_wc_endpoint_url()
&& count(WC()->cart->get_cart())>0;
}
case 'woo_initiate_checkout': {
return PYS()->getOption( 'woo_initiate_checkout_enabled' ) && is_checkout() && ! is_wc_endpoint_url();
}
}
return false;
}
function getEvent($event)
{
switch ($event) {
case 'woo_remove_from_cart':{
return $this->getRemoveFromCartEvents($event);
}
case 'woo_initiate_checkout':
case 'woo_add_to_cart_on_checkout_page':
case 'woo_add_to_cart_on_cart_page':
case 'woo_view_category':
case 'woo_view_item_list':
case 'woo_view_content':
return new SingleEvent($event,EventTypes::$STATIC,'woo');
case 'woo_add_to_cart_on_button_click':
return new SingleEvent($event,EventTypes::$DYNAMIC,'woo');
case 'woo_purchase' : {
$events = array();
$order_key = sanitize_key($_REQUEST['key']);
$order_id = (int) wc_get_order_id_by_order_key( $order_key );
$order = wc_get_order($order_id);
if($order) {
$order->update_meta_data("_pys_purchase_event_fired",true);
$order->save();
}
$events[] = new SingleEvent($event,EventTypes::$STATIC,'woo');
// add child event complete_registration
if(PYS()->getOption( 'woo_complete_registration_enabled' )) {
$events[] = new SingleEvent('woo_complete_registration',EventTypes::$STATIC,'woo');
}
return $events;
}
}
error_log("Not handle event ".$event);
return null;
}
private function isActive($event)
{
switch ($event) {
case 'woo_add_to_cart_on_button_click': {
return PYS()->getOption( 'woo_add_to_cart_enabled' ) && PYS()->getOption( 'woo_add_to_cart_on_button_click' );
}
case 'woo_remove_from_cart': {
return PYS()->getOption( 'woo_remove_from_cart_enabled') ;
}
case 'woo_purchase' : {
return PYS()->getOption( 'woo_purchase_enabled' );
}
case 'woo_view_content' : {
return PYS()->getOption( 'woo_view_content_enabled' ) ;
}
case 'woo_view_category': {
return PYS()->getOption( 'woo_view_category_enabled' ) ;
}
case 'woo_initiate_checkout': {
return PYS()->getOption( 'woo_initiate_checkout_enabled' );
}
}
return false;
}
function getRemoveFromCartEvents($eventId) {
$events = [];
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$event = new SingleEvent($eventId,EventTypes::$DYNAMIC,self::getSlug());
$event->args = ['key'=>$cart_item_key,'item'=>$cart_item];
$events[]=$event;
}
return $events;
}
private function getWooCartActiveCategories($activeIds) {
$fireForCategory = array();
foreach (WC()->cart->cart_contents as $cart_item_key => $cart_item) {
$_product = wc_get_product( $cart_item['product_id'] );
if(!$_product) continue;
$productCat = $_product->get_category_ids();
foreach ($activeIds as $key => $value) {
if(in_array($key,$productCat)) {
$fireForCategory[] = $key;
}
}
}
return array_unique($fireForCategory);
}
private function getWooOrderActiveCategories($orderId,$activeIds) {
$order = new \WC_Order( $orderId );
$fireForCategory = array();
foreach ($order->get_items() as $item) {
$_product = wc_get_product( $item->get_product_id() );
if(!$_product) continue;
$productCat = $_product->get_category_ids();
foreach ($activeIds as $key => $value) {
if(in_array($key,$productCat)) { // fire initiate_checkout for all category pixel
$fireForCategory[] = $key;
}
}
}
return array_unique($fireForCategory);
}
/**
* Always returns empty customer LTV-related values to make plugin compatible with PRO version.
* Used by Pinterest add-on.
*
* @return array
*/
function getCustomerTotals($order_id = null){
return [
'ltv' => null,
'avg_order_value' => null,
'orders_count' => null,
];
}
function getEvents() {
return $this->events;
}
}
/**
* @return EventsWoo
*/
function EventsWoo() {
return EventsWoo::instance();
}
EventsWoo();

View File

@@ -0,0 +1,52 @@
<?php
namespace PixelYourSite;
abstract class EventsFactory {
static function getSlug(){
return "";
}
abstract function getCount();
abstract function isEnabled();
abstract function getOptions();
abstract function getEvents();
/**
* Check is event ready for fire
* @param $event
* @return bool
*/
abstract function isReadyForFire($event);
/**
* @param String $event
* @return SingleEvent
*/
abstract function getEvent($event);
function generateEvents() {
if(!$this->isEnabled()) return array();
$eventsList = array();
foreach ($this->getEvents() as $eventName) {
if($this->isReadyForFire($eventName)) {
foreach ( PYS()->getRegisteredPixels() as $pixel ) {
$events = $this->getEvent($eventName);
if(!is_array($events)) $events = array($events); // some type of events can return array
foreach ($events as $event) {
$singleEvents = $pixel->generateEvents( $event );
foreach ($singleEvents as $singleEvent) {
if(!apply_filters("pys_validate_pixel_event",true,$singleEvent,$pixel)) continue;
$eventsList[$pixel->getSlug()][] = $singleEvent;
}
}
}
}
}
return $eventsList;
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class FormEventCF7 extends Settings implements FormEventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
parent::__construct( 'CF7' );
$this->locateOptions(
PYS_FREE_PATH . '/includes/formEvents/options_fields.json',
PYS_FREE_PATH . '/includes/formEvents/options_defaults.json'
);
if($this->isActivePlugin()){
add_filter("pys_form_event_factory",[$this,"register"]);
}
}
function register($list) {
$list[] = $this;
return $list;
}
public function getSlug() {
return "CF7";
}
public function getName() {
return "Contact Form 7";
}
function isEnabled()
{
return $this->getOption( 'enabled' );
}
function isActivePlugin()
{
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
return is_plugin_active( 'contact-form-7/wp-contact-form-7.php' );
}
function getForms(){
global $wpdb;
$forms = wp_cache_get( 'cf7-forms' );
if ( empty( $forms ) ) {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = $wpdb->get_results(
$wpdb->prepare(
'SELECT ID, post_title FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_status = %s', "wpcf7_contact_form", "publish"
)
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = wp_list_pluck( $forms, 'post_title', 'ID' );
wp_cache_add( 'cf7-forms', $forms );
}
return $forms;
}
function getOptions() {
return array(
"name" => $this->getName(),
"enabled" => $this->getOption( "enabled"),
"form_ID_event" => $this->getOption( "form_ID_event")
);
}
}
/**
* @return EventsCustom
*/
function FormEventCF7() {
return FormEventCF7::instance();
}
FormEventCF7();

View File

@@ -0,0 +1,88 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class FormEventFluentForm extends Settings implements FormEventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
parent::__construct( 'Fluentform' );
$this->locateOptions(
PYS_FREE_PATH . '/includes/formEvents/options_fields.json',
PYS_FREE_PATH . '/includes/formEvents/options_defaults.json'
);
if($this->isActivePlugin()){
add_filter("pys_form_event_factory",[$this,"register"]);
}
}
function register($list) {
$list[] = $this;
return $list;
}
public function getSlug() {
return "fluentform";
}
public function getName() {
return "Fluentform";
}
function isEnabled()
{
return $this->getOption( 'enabled' );
}
function isActivePlugin()
{
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
return is_plugin_active( 'fluentform/fluentform.php' );
}
function getForms(){
global $wpdb, $table_prefix;
$forms = array();
if ( empty( $forms ) ) {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = $wpdb->get_results(
$wpdb->prepare(
'SELECT id, title FROM '.$table_prefix.'fluentform_forms WHERE `status` = %s ORDER BY %s DESC', "published", "created_at"
)
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = wp_list_pluck( $forms, 'title', 'id' );
}
return $forms;
}
function getOptions() {
return array(
"name" => $this->getName(),
"enabled" => $this->getOption( "enabled"),
"form_ID_event" => $this->getOption( "form_ID_event")
);
}
}
/**
* @return FormEventFluentForm
*/
function FormEventFluentForm() {
return FormEventFluentForm::instance();
}
FormEventFluentForm();

View File

@@ -0,0 +1,91 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class FormEventFormidable extends Settings implements FormEventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
parent::__construct( 'Formidable' );
$this->locateOptions(
PYS_FREE_PATH . '/includes/formEvents/options_fields.json',
PYS_FREE_PATH . '/includes/formEvents/options_defaults.json'
);
if($this->isActivePlugin()){
add_filter("pys_form_event_factory",[$this,"register"]);
}
}
function register($list) {
$list[] = $this;
return $list;
}
public function getSlug() {
return "formidable";
}
public function getName() {
return "Formidable";
}
function isEnabled()
{
return $this->getOption( 'enabled' );
}
function isActivePlugin()
{
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
return is_plugin_active( 'formidable/formidable.php' );
}
function getForms(){
global $wpdb, $table_prefix;
$forms = array();
if ( empty( $forms ) ) {
$forms = $wpdb->get_results(
$wpdb->prepare(
'SELECT id, name FROM `'.$table_prefix.'frm_forms` WHERE `status` LIKE %s ORDER BY created_at DESC', "published"
)
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = wp_list_pluck( $forms, 'name', 'id' );
}
return $forms;
}
function getOptions() {
return array(
"name" => $this->getName(),
"enabled" => $this->getOption( "enabled"),
"form_ID_event" => $this->getOption( "form_ID_event")
);
}
}
/**
* @return EventsCustom
*/
function FormEventFormidable() {
return FormEventFormidable::instance();
}
FormEventFormidable();

View File

@@ -0,0 +1,88 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class FormEventNinjaForm extends Settings implements FormEventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
parent::__construct( 'NinjaForm' );
$this->locateOptions(
PYS_FREE_PATH . '/includes/formEvents/options_fields.json',
PYS_FREE_PATH . '/includes/formEvents/options_defaults.json'
);
if($this->isActivePlugin()){
add_filter("pys_form_event_factory",[$this,"register"]);
}
}
function register($list) {
$list[] = $this;
return $list;
}
public function getSlug() {
return "ninjaform";
}
public function getName() {
return "Ninja Form";
}
function isEnabled()
{
return $this->getOption( 'enabled' );
}
function isActivePlugin()
{
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
return is_plugin_active( 'ninja-forms/ninja-forms.php' );
}
function getForms(){
global $wpdb, $table_prefix;
$forms = array();
if ( empty( $forms ) ) {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = $wpdb->get_results(
$wpdb->prepare(
'SELECT id, title FROM '.$table_prefix.'nf3_forms ORDER BY %s DESC', "created_at"
)
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = wp_list_pluck( $forms, 'title', 'id' );
}
return $forms;
}
function getOptions() {
return array(
"name" => $this->getName(),
"enabled" => $this->getOption( "enabled"),
"form_ID_event" => $this->getOption( "form_ID_event")
);
}
}
/**
* @return FormEventNinjaForm
*/
function FormEventNinjaForm() {
return FormEventNinjaForm::instance();
}
FormEventNinjaForm();

View File

@@ -0,0 +1,88 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class FormEventWPForms extends Settings implements FormEventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
parent::__construct( 'WPForms' );
$this->locateOptions(
PYS_FREE_PATH . '/includes/formEvents/options_fields.json',
PYS_FREE_PATH . '/includes/formEvents/options_defaults.json'
);
if($this->isActivePlugin()){
add_filter("pys_form_event_factory",[$this,"register"]);
}
}
function register($list) {
$list[] = $this;
return $list;
}
public function getSlug() {
return "wpforms";
}
public function getName() {
return "WPForms";
}
function isEnabled()
{
return $this->getOption( 'enabled' );
}
function isActivePlugin()
{
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
return is_plugin_active( 'wpforms-lite/wpforms.php' );
}
function getForms(){
global $wpdb;
$forms = array();
if ( empty( $forms ) ) {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = $wpdb->get_results(
$wpdb->prepare(
'SELECT ID, post_title FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_status = %s', "wpforms", "publish"
)
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = wp_list_pluck( $forms, 'post_title', 'ID' );
}
return $forms;
}
function getOptions() {
return array(
"name" => $this->getName(),
"enabled" => $this->getOption( "enabled"),
"form_ID_event" => $this->getOption( "form_ID_event")
);
}
}
/**
* @return EventsCustom
*/
function FormEventWPForms() {
return FormEventWPForms::instance();
}
FormEventWPForms();

View File

@@ -0,0 +1,88 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class FormEventForminator extends Settings implements FormEventsFactory {
private static $_instance;
public static function instance() {
if ( is_null( self::$_instance ) ) {
self::$_instance = new self();
}
return self::$_instance;
}
public function __construct() {
parent::__construct( 'forminator' );
$this->locateOptions(
PYS_FREE_PATH . '/includes/formEvents/options_fields.json',
PYS_FREE_PATH . '/includes/formEvents/options_defaults.json'
);
if($this->isActivePlugin()){
add_filter("pys_form_event_factory",[$this,"register"]);
}
}
function register($list) {
$list[] = $this;
return $list;
}
public function getSlug() {
return "forminator";
}
public function getName() {
return "Forminator";
}
function isEnabled()
{
return $this->getOption( 'enabled' );
}
function isActivePlugin()
{
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once(ABSPATH . 'wp-admin/includes/plugin.php');
}
return is_plugin_active( 'forminator/forminator.php' );
}
function getForms(){
global $wpdb;
$forms = array();
if ( empty( $forms ) ) {
// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = $wpdb->get_results(
$wpdb->prepare(
'SELECT ID, post_title FROM ' . $wpdb->posts . ' WHERE post_type = %s AND post_status = %s', "forminator_forms", "publish"
)
);
// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
$forms = wp_list_pluck( $forms, 'post_title', 'ID' );
}
return $forms;
}
function getOptions() {
return array(
"name" => $this->getName(),
"enabled" => $this->getOption( "enabled"),
"form_ID_event" => $this->getOption( "form_ID_event")
);
}
}
/**
* @return EventsCustom
*/
function FormEventForminator() {
return FormEventForminator::instance();
}
FormEventForminator();

View File

@@ -0,0 +1,18 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
interface FormEventsFactory {
public function getSlug();
public function getName();
public function isEnabled();
public function isActivePlugin();
public function getOptions();
public function getForms();
}

View File

@@ -0,0 +1,4 @@
{
"enabled": true,
"form_ID_event": ""
}

View File

@@ -0,0 +1,4 @@
{
"enabled": "checkbox",
"form_ID_event": "array_v"
}

View File

@@ -0,0 +1,863 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function buildAdminUrl( $page, $tab = '', $action = '', $extra = array() ) {
$args = array( 'page' => $page );
if ( $tab ) {
$args['tab'] = $tab;
}
if ( $action ) {
$args['action'] = $action;
}
$args = array_merge( $args, $extra );
return add_query_arg( $args, admin_url( 'admin.php' ) );
}
function getCurrentAdminPage() {
if(!empty($_GET['page'])) {
return sanitize_text_field($_GET['page']);
}
return '';
}
function getCurrentAdminTab() {
if(!empty( $_GET['tab'] ) ) {
return sanitize_text_field($_GET['tab']);
}
return 'general';
}
function getCurrentAdminAction() {
if(!empty( $_GET['action'] ) ) {
return sanitize_text_field($_GET['action']);
}
return '';
}
function getAdminPrimaryNavTabs() {
$tabs = array(
'general' => array(
'url' => buildAdminUrl( 'pixelyoursite' ),
'name' => 'General',
),
'events' => array(
'url' => buildAdminUrl( 'pixelyoursite', 'events' ),
'name' => 'Events',
),
);
if ( isWooCommerceActive() ) {
$tabs['woo'] = array(
'url' => buildAdminUrl( 'pixelyoursite', 'woo' ),
'name' => 'WooCommerce',
);
}
if ( isEddActive() ) {
$tabs['edd'] = array(
'url' => buildAdminUrl( 'pixelyoursite', 'edd' ),
'name' => 'EasyDigitalDownloads',
);
}
if ( isWcfActive() ) {
$tabs['wcf'] = array(
'url' => buildAdminUrl( 'pixelyoursite', 'wcf' ),
'name' => 'CartFlows',
);
}
$tabs['gdpr'] = array(
'url' => buildAdminUrl( 'pixelyoursite', 'gdpr' ),
'name' => 'Consent',
'class' => 'orange'
);
return $tabs;
}
function getAdminSecondaryNavTabs() {
$tabs = array(
'facebook_settings' => array(
'url' => buildAdminUrl( 'pixelyoursite', 'facebook_settings' ),
'name' => 'Facebook Settings',
),
'ga_settings' => array(
'url' => buildAdminUrl( 'pixelyoursite', 'ga_settings' ),
'name' => 'Google Analytics Settings',
),
);
$tabs = apply_filters( 'pys_admin_secondary_nav_tabs', $tabs );
$tabs['superpack_settings'] = array(
'url' => buildAdminUrl( 'pixelyoursite', 'superpack_settings' ),
'name' => 'Super Pack Settings',
);
$tabs['head_footer'] = array(
'url' => buildAdminUrl( 'pixelyoursite', 'head_footer' ),
'name' => 'Head & Footer',
);
return $tabs;
}
function cardCollapseBtn($attr = "") {
echo '<span class="card-collapse" '.$attr.'><i class="fa fa-sliders" aria-hidden="true"></i></span>';
}
/**
* @param string $key
* @param Settings $settings
*/
function renderCollapseTargetAttributes( $key, $settings ) {
echo 'class="pys_' . $settings->getSlug() . '_' . esc_attr( $key ) . '_panel"';
}
function manageAdminPermissions() {
global $wp_roles;
$roles = PYS()->getOption( 'admin_permissions', array( 'administrator' ) );
foreach ( $wp_roles->roles as $role => $options ) {
if ( in_array( $role, $roles ) ) {
$wp_roles->add_cap( $role, 'manage_pys' );
} else {
$wp_roles->remove_cap( $role, 'manage_pys' );
}
}
}
function renderPopoverButton( $popover_id ) {
?>
<button type="button" class="btn btn-link" role="button" data-toggle="pys-popover" data-trigger="focus"
data-placement="right" data-popover_id="<?php esc_attr_e( $popover_id ); ?>">
<i class="fa fa-info-circle" aria-hidden="true"></i>
</button>
<?php
}
function renderExternalHelpIcon( $url ) {
?>
<a class="btn btn-link" target="_blank" href="<?php echo esc_url( $url ); ?>">
<i class="fa fa-info-circle" aria-hidden="true"></i>
</a>
<?php
}
function purgeCache() {
if ( function_exists( 'w3tc_pgcache_flush' ) ) { // W3 Total Cache
w3tc_pgcache_flush();
} elseif ( function_exists( 'wp_cache_clean_cache' ) ) { // WP Super Cache
global $file_prefix, $supercachedir;
if ( empty( $supercachedir ) && function_exists( 'get_supercache_dir' ) ) {
$supercachedir = get_supercache_dir();
}
wp_cache_clean_cache( $file_prefix );
} elseif ( class_exists( 'WpeCommon' ) ) {
if ( method_exists( 'WpeCommon', 'purge_memcached' ) ) {
\WpeCommon::purge_memcached();
}
// if ( method_exists( 'WpeCommon', 'clear_maxcdn_cache' ) ) {
// \WpeCommon::clear_maxcdn_cache();
// }
if ( method_exists( 'WpeCommon', 'purge_varnish_cache' ) ) {
\WpeCommon::purge_varnish_cache();
}
} elseif ( method_exists( 'WpFastestCache', 'deleteCache' ) ) {
global $wp_fastest_cache;
if ( ! empty( $wp_fastest_cache ) ) {
$wp_fastest_cache->deleteCache();
}
} elseif ( function_exists( 'sg_cachepress_purge_cache' ) ) {
sg_cachepress_purge_cache();
}
}
function adminIncompatibleVersionNotice( $pluginName, $minVersion ) {
?>
<div class="notice notice-error">
<p>You are using incompatible version of <?php esc_html_e( $pluginName ); ?>. PixelYourSite requires at
least <?php esc_html_e( $pluginName ); ?> <?php echo $minVersion; ?>. Please, update to
latest version.</p>
</div>
<?php
}
function adminRenderNotices() {
if ( ! current_user_can( 'manage_pys' ) ) {
return;
}
/**
* Expiration notices
*/
$now = time();
$apiTokens = Facebook()->getOption('server_access_api_token');
if(Facebook()->enabled() && !$apiTokens)
{
$meta_key = 'pys_notice_dont_CAPI_start_delay';
$user_id = get_current_user_id();
$start_delay = get_user_meta( $user_id, $meta_key );
$day_ago = time() - DAY_IN_SECONDS;
if($start_delay && $start_delay > $day_ago) {
adminRenderNotCAPI(PYS());
}
else if(!$start_delay){
update_user_meta($user_id, $meta_key, time());
}
}
if ( isPinterestActive( false ) && isPinterestVersionIncompatible() ) {
adminIncompatibleVersionNotice( 'PixelYourSite Pinterest Add-On', PYS_FREE_PINTEREST_MIN_VERSION );
} elseif ( isPinterestActive() ) {
$expire_at = Pinterest()->getOption( 'license_expires' );
if ( $expire_at && $now > $expire_at ) {
adminRenderLicenseExpirationNotice( Pinterest() );
}
}
if ( isBingActive( false ) && isBingVersionIncompatible() ) {
adminIncompatibleVersionNotice( 'PixelYourSite Bing Add-On', PYS_FREE_BING_MIN_VERSION );
} elseif ( isBingActive() ) {
$expire_at = Bing()->getOption( 'license_expires' );
if ( $expire_at && $now > $expire_at ) {
adminRenderLicenseExpirationNotice( Bing() );
}
}
/**
* Pixel ID notices
*/
$facebook_pixel_id = Facebook()->getPixelIDs() ;
if ( Facebook()->enabled() && empty( $facebook_pixel_id ) ) {
$no_facebook_pixels = true;
} else {
$no_facebook_pixels = false;
}
$ga_tracking_id = GA()->getPixelIDs() ;
if ( GA()->enabled() && empty( $ga_tracking_id ) ) {
$no_ga_pixels = true;
} else {
$no_ga_pixels = false;
}
$pinterest_pixel_id = Pinterest()->getOption( 'pixel_id' );
$pinterest_license_status = Pinterest()->getOption( 'license_status' );
if ( isPinterestActive() && Pinterest()->enabled()
&& ! empty( $pinterest_license_status ) // license active or was active before
&& empty( $pinterest_pixel_id ) ) {
$no_pinterest_pixels = true;
} else {
$no_pinterest_pixels = false;
}
if ( isPinterestActive() ) {
if ( $no_facebook_pixels && $no_ga_pixels && $no_pinterest_pixels ) {
adminRenderNoPixelsNotice();
} else {
if ( $no_facebook_pixels ) {
adminRenderNoPixelNotice( Facebook() );
}
if ( $no_ga_pixels ) {
adminRenderNoPixelNotice( GA() );
}
if ( $no_pinterest_pixels ) {
adminRenderNoPixelNotice( Pinterest() );
}
}
// show notice if licence was never activated
if (Pinterest()->enabled() && empty($pinterest_license_status)) {
adminRenderActivatePinterestLicence();
}
} else {
if ( $no_facebook_pixels && $no_ga_pixels ) {
adminRenderNoPixelsNotice();
} else {
if ( $no_facebook_pixels ) {
adminRenderNoPixelNotice( Facebook() );
}
if ( $no_ga_pixels ) {
adminRenderNoPixelNotice( GA() );
}
}
}
if ( isBingActive() ) {
$bing_license_status = Bing()->getOption( 'license_status' );
// show notice if licence was never activated
if (Bing()->enabled() && empty($bing_license_status)) {
adminRenderActivateBingLicence();
}
}
/**
* GDPR
*/
if ( isCookieLawInfoPluginActivated() && ! PYS()->getOption( 'gdpr_ajax_enabled' ) ) {
adminGdprAjaxNotEnabledNotice();
}
}
/**
* @param Plugin|Settings $plugin
*/
function adminRenderLicenseExpirationNotice( $plugin ) {
if ( 'pixelyoursite' == getCurrentAdminPage() ) {
return; // do not show notice on plugin pages
}
$slug = $plugin->getSlug();
$user_id = get_current_user_id();
// show only if never dismissed or dismissed more than a week ago
$meta_key = 'pys_' . $slug . '_expiration_notice_dismissed_at';
$dismissed_at = get_user_meta( $user_id, $meta_key );
if ( $dismissed_at ) {
if ( is_array( $dismissed_at ) ) {
$dismissed_at = reset( $dismissed_at );
}
$week_ago = time() - WEEK_IN_SECONDS;
if ( $week_ago < $dismissed_at ) {
return;
}
}
$license_key = $plugin->getOption( 'license_key' );
?>
<div class="notice notice-error is-dismissible pys_<?php esc_attr_e( $slug ); ?>_expiration_notice">
<p><strong>Your <?php echo $plugin->getPluginName(); ?> license key is expired</strong>, so you no longer get any updates. Don't miss our
latest improvements and make sure that everything works smoothly.</p>
<p>If you renewed your license but you still see this message, click on the "<a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite_licenses' ) ); ?>">Reactivate License</a>" button.</p>
<p class="mb-0"><a href="https://www.pixelyoursite.com/checkout/?edd_license_key=<?php esc_attr_e(
$license_key ); ?>&utm_campaign=admin&utm_source=licenses&utm_medium=renew" target="_blank"><strong>Click here to renew your license now</strong></a></p>
</div>
<script type="application/javascript">
jQuery(document).on('click', '.pys_<?php esc_attr_e( $slug ); ?>_expiration_notice .notice-dismiss', function () {
jQuery.ajax({
url: ajaxurl,
data: {
action: 'pys_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: '<?php esc_attr_e( $slug ); ?>',
meta_key: 'expiration_notice'
}
})
})
</script>
<?php
}
add_action( 'wp_ajax_pys_notice_dismiss', 'PixelYourSite\adminNoticeDismissHandler' );
function adminNoticeDismissHandler() {
if ( empty( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'pys_notice_dismiss' ) ) {
return;
}
if ( empty( $_REQUEST['user_id'] ) || empty( $_REQUEST['addon_slug'] ) || empty( $_REQUEST['meta_key'] ) ) {
return;
}
// save time when notice was dismissed
$meta_key = 'pys_' . sanitize_text_field( $_REQUEST['addon_slug'] ) . '_' . sanitize_text_field( $_REQUEST['meta_key'] ) . '_dismissed_at';
$userId = sanitize_text_field( $_REQUEST['user_id'] );
update_user_meta($userId, $meta_key, time() );
}
function adminRenderNotCAPI( $plugin ) {
$slug = $plugin->getSlug();
$user_id = get_current_user_id();
// show only if never dismissed or dismissed more than a week ago
$meta_key = 'pys_' . $slug . '_CAPI_notice_dismissed_at';
$dismissed_at = get_user_meta( $user_id, $meta_key );
if ( $dismissed_at ) {
if ( is_array( $dismissed_at ) ) {
$dismissed_at = reset( $dismissed_at );
}
$week_ago = time() - WEEK_IN_SECONDS;
if ( $week_ago < $dismissed_at ) {
return;
}
else
{
?>
<div class="notice notice-error is-dismissible pys_<?php esc_attr_e( $slug ); ?>_CAPI_notice">
<p><b>PixelYourSite Tip: </b>Don't forget to enable Meta Conversion API events. They can improve your ads performance and conversion tracking. Watch this video to learn how: <a href="https://www.youtube.com/watch?v=1rKd57SS094" target="_blank">watch the video</a>.</p>
</div>
<?php
}
}
else
{
?>
<div class="notice notice-error is-dismissible pys_<?php esc_attr_e( $slug ); ?>_CAPI_notice">
<p><b>PixelYourSite Tip: </b>Improve your Meta Ads conversion tracking and performance with Conversion API events. Simply add your token to enable CAPI. Watch this video to learn how to do it: <a href="https://www.youtube.com/watch?v=1rKd57SS094" target="_blank">watch the video</a>.</p>
</div>
<?php
}
?>
<script type="application/javascript">
jQuery(document).on('click', '.pys_<?php esc_attr_e( $slug ); ?>_CAPI_notice .notice-dismiss', function () {
jQuery.ajax({
url: ajaxurl,
data: {
action: 'pys_notice_CAPI_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_CAPI_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: '<?php esc_attr_e( $slug ); ?>',
meta_key: 'CAPI_notice'
}
})
})
</script>
<?php
}
add_action( 'wp_ajax_pys_notice_CAPI_dismiss', 'PixelYourSite\adminNoticeCAPIDismissHandler' );
function adminNoticeCAPIDismissHandler() {
if ( empty( $_REQUEST['nonce'] ) || ! wp_verify_nonce( $_REQUEST['nonce'], 'pys_notice_CAPI_dismiss' ) ) {
return;
}
if ( empty( $_REQUEST['user_id'] ) || empty( $_REQUEST['addon_slug'] ) || empty( $_REQUEST['meta_key'] ) ) {
return;
}
// save time when notice was dismissed
$meta_key = 'pys_' . sanitize_text_field( $_REQUEST['addon_slug'] ) . '_' . sanitize_text_field( $_REQUEST['meta_key'] ) . '_dismissed_at';
update_user_meta( sanitize_text_field($_REQUEST['user_id']), $meta_key, time() );
die();
}
function adminRenderActivatePinterestLicence() {
if ( 'pixelyoursite_licenses' == getCurrentAdminPage() ) {
return; // do not show notice licenses page
}
?>
<div class="notice notice-error">
<p>Activate your Pinterest add-on license: <a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite_licenses' ) ); ?>">click here</a>.</p>
</div>
<?php
}
function adminRenderActivateBingLicence() {
if ( 'pixelyoursite_licenses' == getCurrentAdminPage() ) {
return; // do not show notice licenses page
}
?>
<div class="notice notice-error">
<p>Activate your PixelYourSite Microsoft UET (Bing) add-on license: <a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite_licenses' ) ); ?>">click here</a>.</p>
</div>
<?php
}
function adminRenderNoPixelsNotice() {
if ( 'pixelyoursite' == getCurrentAdminPage() ) {
return; // do not show notice on plugin pages
}
$user_id = get_current_user_id();
// do not show dismissed notice
$meta_key = 'pys_core_no_pixels_dismissed_at';
$dismissed_at = get_user_meta( $user_id, $meta_key );
if ( $dismissed_at ) {
return;
}
?>
<div class="notice notice-warning is-dismissible pys_core_no_pixels_notice">
<p>You have no pixel configured with PixelYourSite. You can add the Meta Pixel (formerly Facebook Pixel), Google Analytics or the
Pinterest Tag. <a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite' ) ); ?>">Start tracking
everything now</a></p>
</div>
<script type="application/javascript">
jQuery(document).on('click', '.pys_core_no_pixels_notice .notice-dismiss', function () {
jQuery.ajax({
url: ajaxurl,
data: {
action: 'pys_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: 'core',
meta_key: 'no_pixels'
}
})
})
</script>
<?php
}
/**
* @param Plugin|Settings $plugin
*/
function adminRenderNoPixelNotice( $plugin ) {
if ( 'pixelyoursite' == getCurrentAdminPage() ) {
return; // do not show notice on plugin pages
}
$slug = $plugin->getSlug();
$user_id = get_current_user_id();
// do not show dismissed notice
$meta_key = 'pys_' . $slug . '_no_pixel_dismissed_at';
$dismissed_at = get_user_meta( $user_id, $meta_key );
if ( $dismissed_at ) {
return;
}
?>
<div class="notice notice-warning is-dismissible pys_<?php esc_attr_e( $slug ); ?>_no_pixel_notice">
<?php if ( $slug == 'facebook' ) : ?>
<p>Add your Meta Pixel (formerly Facebook Pixel) ID and start tracking everything with PixelYourSite. <a
href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite' ) ); ?>">Click Here</a></p>
<?php elseif ( $slug == 'ga' && ( isWooCommerceActive() || isEddActive() ) ) : ?>
<p>Add your Google Analytics tracking ID inside PixelYourSite and start tracking everything. Enhanced
Ecommerce is fully supported for WooCommerce or Easy Digital Downloads. <a
href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite' ) ); ?>">Click Here</a></p>
<p>(If you use another Google Analytics plugin, disable it in order to avoid conflicts)</p>
<?php elseif ( $slug == 'ga' && ! isWooCommerceActive() && ! isEddActive() ) : ?>
<p>Add your Google Analytics ID inside PixelYourSite and start tracking everything. <a
href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite' ) ); ?>">Click Here</a></p>
<p>(If you use another Google Analytics plugin, disable it in order to avoid conflicts)</p>
<?php elseif ( $slug == 'pinterest' ) : ?>
<p>Add your Pinterest pixel ID and start tracking everything with PixelYourSite. <a
href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite' ) ); ?>">Click Here</a></p>
<?php endif; ?>
</div>
<script type="application/javascript">
jQuery(document).on('click', '.pys_<?php esc_attr_e( $slug ); ?>_no_pixel_notice .notice-dismiss', function () {
jQuery.ajax({
url: ajaxurl,
data: {
action: 'pys_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: '<?php esc_attr_e( $slug ); ?>',
meta_key: 'no_pixel'
}
})
})
</script>
<?php
}
function renderDummyTextInput( $placeholder = '' ) {
?>
<input type="text" disabled="disabled" placeholder="<?php esc_html_e( $placeholder ); ?>" class="form-control">
<?php
}
function renderDummyNumberInput($default = 0) {
?>
<input type="number" disabled="disabled" min="0" max="100" class="form-control" value="<?=$default?>">
<?php
}
function renderDummySwitcher($isEnable = false) {
$attr = $isEnable ? " checked='checked'" : "";
?>
<div class="custom-switch disabled">
<input type="checkbox" value="1" <?=$attr?> disabled="disabled" class="custom-switch-input">
<label class="custom-switch-btn"></label>
</div>
<?php
}
function renderDummyCheckbox( $label, $with_pro_badge = false ) {
?>
<label class="custom-control custom-checkbox <?php echo $with_pro_badge ? 'custom-checkbox-badge' : ''; ?>">
<input type="checkbox" value="1"
class="custom-control-input" disabled="disabled">
<span class="custom-control-indicator"></span>
<span class="custom-control-description">
<?php echo wp_kses_post( $label ); ?>
<?php if ( $with_pro_badge ) {
renderProBadge();
} ?>
</span>
</label>
<?php
}
function renderDummyRadioInput( $label, $checked = false ) {
?>
<label class="custom-control custom-radio">
<input type="radio" disabled="disabled"
class="custom-control-input" <?php checked( $checked ); ?>>
<span class="custom-control-indicator"></span>
<span class="custom-control-description"><?php echo wp_kses_post( $label ); ?></span>
</label>
<?php
}
function renderDummyTagsFields( $tags = array() ) {
?>
<select class="form-control pys-tags-pysselect2" disabled="disabled" style="width: 100%;" multiple>
<?php foreach ( $tags as $tag ) : ?>
<option value="<?php echo esc_attr( $tag ); ?>" selected>
<?php echo esc_attr( $tag ); ?>
</option>
<?php endforeach; ?>
</select>
<?php
}
function renderDummySelectInput( $value, $full_width = false ) {
$attr_width = $full_width ? 'width: 100%;' : '';
?>
<select class="form-control form-control-sm" disabled="disabled" autocomplete="off" style="<?php esc_attr_e( $attr_width ); ?>">
<option value="" disabled selected><?php esc_html_e( $value ); ?></option>
</select>
<?php
}
function renderDummyGoogleAdsConversionLabelInputs() {
?>
<div class="row mt-1 mb-2">
<div class="col-11 col-offset-left form-inline">
<label>Add conversion label </label>
<?php renderDummyTextInput( 'Enter conversion label' ); ?>
<?php renderProBadge('https://www.pixelyoursite.com/google-ads-tag'); ?>
</div>
<div class="col-1">
<button type="button" class="btn btn-link" role="button" data-toggle="pys-popover" data-trigger="focus"
data-placement="right" data-popover_id="google_ads_conversion_label" data-original-title=""
title="">
<i class="fa fa-info-circle" aria-hidden="true"></i>
</button>
</div>
</div>
<?php
}
function renderProBadge( $url = null,$label = "Pro Feature" ) {
if ( ! $url ) {
$url = 'https://www.pixelyoursite.com/';
}
$url = untrailingslashit( $url ) . '/?utm_source=pys-free-plugin&utm_medium=pro-badge&utm_campaign=pro-feature';
echo '&nbsp;<a href="' . esc_url( $url ) . '" target="_blank" class="badge badge-pill badge-pro">'.$label.' <i class="fa fa-external-link" aria-hidden="true"></i></a>';
}
function renderCogBadge( $label = "You need this plugin" ) {
$url = 'https://www.pixelyoursite.com/woocommerce-cost-of-goods';
echo '&nbsp;<a href="' . esc_url( $url ) . '" target="_blank" class="badge badge-pill badge-pro">'.$label.' <i class="fa fa-external-link" aria-hidden="true"></i></a>';
}
function renderSpBadge() {
echo '&nbsp;<a href="https://www.pixelyoursite.com/super-pack?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-super-pack" target="_blank" class="badge badge-pill badge-pro">Pro Feature <i class="fa fa-external-link" aria-hidden="true"></i></a>';
}
function renderHfBadge() {
echo '&nbsp;<a href="https://www.pixelyoursite.com/head-footer-scripts?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-head-footer" target="_blank" class="badge badge-pill badge-pro">Pro Feature <i class="fa fa-external-link" aria-hidden="true"></i></a>';
}
function addMetaTagFields($pixel,$url) { ?>
<div class="row">
<div class="col-12">
<h4 class="label mb-3">Verify your domain:</h4>
<?php
$pixel->render_text_input_array_item('verify_meta_tag','Add the verification meta-tag there');
?>
<?php if(!empty($url)) : ?>
<small class="form-text"><a href="<?=$url?>" target="_blank">Learn how to verify your domain</a></small>
<?php endif; ?>
</div>
</div>
<hr>
<?php
$metaTags = (array) $pixel->getOption( 'verify_meta_tag' );
foreach ($metaTags as $index => $val) :
if($index == 0) continue; ?>
<div class="row">
<div class="col-10">
<?php
$pixel->render_text_input_array_item('verify_meta_tag','Add the verification meta-tag there',$index);
?>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm remove-meta-row">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
<hr>
<?php
endforeach;
?>
<div class="row" id="pys_add_<?=$pixel->getSlug()?>_meta_tag_button_row">
<div class="col-12">
<button class="btn btn-sm btn-primary" type="button" id="pys_add_<?=$pixel->getSlug()?>_meta_tag">
Add another verification meta-tag
</button>
<script>
jQuery(document).ready(function ($) {
$('#pys_add_<?=$pixel->getSlug()?>_meta_tag').click(function (e) {
e.preventDefault();
var newField = '<div class="row"><div class="col-10">' +
'<input type="text" placeholder="Add the verification meta-tag there" name="pys[<?=$pixel->getSlug()?>][verify_meta_tag][]" id="pys_facebook_meta_tag_0" value="" placeholder="" class="form-control">' +
'</div>' +
'<div class="col-2">' +
'<button type="button" class="btn btn-sm remove-meta-row"><i class="fa fa-trash-o" aria-hidden="true"></i></button>' +
'</div></div><hr>';
var $row = $(newField)
.insertBefore('#pys_add_<?=$pixel->getSlug()?>_meta_tag_button_row')
});
});
</script>
</div>
</div>
<?php }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,410 @@
<?php
namespace PixelYourSite\Events;
use PixelYourSite;
use PixelYourSite\CustomEvent;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderHiddenInput( &$event, $key ) {
$attr_name = "pys[event][$key]";
$attr_value = $event->$key;
?>
<input type="hidden" name="<?php esc_attr_e( $attr_name ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>">
<?php
}
/**
* @param CustomEvent $event
* @param string $key
* @param string $placeholder
*/
function renderTextInput( &$event, $key, $placeholder = '' ) {
$attr_name = "pys[event][$key]";
$attr_id = 'pys_event_' . $key;
$attr_value = $event->$key;
?>
<input type="text" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
class="form-control">
<?php
}
/**
* @param CustomEvent $event
* @param string $key
* @param array $options
*/
function renderGroupSelectInput( &$event, $key, $groups, $full_width = false ) {
$attr_name = "pys[event][$key]";
$attr_id = 'pys_event_' . $key;
$attr_value = $event->$key;
$attr_width = $full_width ? 'width: 100%;' : '';
?>
<select class="form-control-sm" id="<?php esc_attr_e( $attr_id ); ?>"
name="<?php esc_attr_e( $attr_name ); ?>" autocomplete="off" style="<?php esc_attr_e( $attr_width ); ?>">
<?php foreach ($groups as $group => $options) :?>
<optgroup label="<?=$group?>">
<?php foreach ( $options as $option_key => $option_value ) : ?>
<option group="<?=$group?>" value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key,
esc_attr( $attr_value ) ); ?> <?php disabled( $option_key,
'disabled' ); ?>><?php echo esc_attr( $option_key ); ?></option>
<?php endforeach; ?>
</optgroup>
<?php endforeach; ?>
</select>
<?php
}
/**
* @param CustomEvent $event
* @param string $key
* @param string $placeholder
*/
function renderGAParamInput( $key, $val ) {
$attr_name = "pys[event][ga_params][$key]";
$attr_id = 'pys_event_ga_' . $key;
$attr_value = $val;
?>
<input type="text" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
class="form-control">
<?php
}
/**
* @param CustomEvent $event
* @param string $key
* @param string $placeholder
*/
function renderNumberInput( &$event, $key, $placeholder = null ) {
$attr_name = "pys[event][$key]";
$attr_id = 'pys_event_' . $key;
$attr_value = $event->$key;
?>
<input type="number" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="<?php esc_attr_e( $placeholder ); ?>"
min="0" class="form-control">
<?php
}
/**
* @param CustomEvent $event
* @param string $key
* @param bool $disabled
*/
function renderSwitcherInput( &$event, $key,$disabled = false ) {
$attr_name = "pys[event][$key]";
$attr_id = 'pys_event_' . $key;
$attr_value = $event->$key;
$classes = array( 'custom-switch' );
if ( $disabled ) {
$attr_value = false;
$classes[] = 'disabled';
}
$classes = implode( ' ', $classes );
?>
<div class="<?php esc_attr_e( $classes ); ?>">
<?php if ( ! $disabled ) : ?>
<input type="hidden" name="<?php esc_attr_e( $attr_name ); ?>" value="0">
<?php endif; ?>
<input type="checkbox" name="<?php esc_attr_e( $attr_name ); ?>" value="1" <?php checked( $attr_value,
true ); ?> <?php disabled( $disabled, true ); ?>
id="<?php esc_attr_e( $attr_id ); ?>" class="custom-switch-input">
<label class="custom-switch-btn" for="<?php esc_attr_e( $attr_id ); ?>"></label>
</div>
<?php
}
/**
* @param CustomEvent $event
* @param string $key
* @param array $options
*/
function renderSelectInput( &$event, $key, $options, $full_width = false ) {
if ( $key == 'currency' ) {
$attr_name = "pys[event][facebook_params][$key]";
$attr_id = 'pys_event_facebook_params_' . $key;
$attr_value = $event->getFacebookParam( $key );
} else {
$attr_name = "pys[event][$key]";
$attr_id = 'pys_event_' . $key;
$attr_value = $event->$key;
}
$attr_width = $full_width ? 'width: 100%;' : '';
?>
<select class="form-control-sm" id="<?php esc_attr_e( $attr_id ); ?>"
name="<?php esc_attr_e( $attr_name ); ?>" autocomplete="off" style="<?php esc_attr_e( $attr_width ); ?>">
<?php foreach ( $options as $option_key => $option_value ) : ?>
<?php if ( ! PixelYourSite\startsWith( $option_key, 'disabled' ) ) : ?>
<option value="<?php echo esc_attr( $option_key ); ?>" <?php selected( $option_key,
esc_attr( $attr_value ) ); ?>><?php echo esc_attr( $option_value ); ?></option>
<?php else : ?>
<option disabled="disabled"><?php echo esc_attr( $option_value ); ?></option>
<?php endif; ?>
<?php endforeach; ?>
</select>
<?php
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderTriggerTypeInput( &$event, $key ) {
$options = array(
'page_visit' => 'Page visit',
'url_click' => 'Click on HTML link - PRO',
'css_click' => 'Click on CSS selector - PRO',
'css_mouseover' => 'Mouse over CSS selector - PRO',
'scroll_pos' => 'Page Scroll - PRO',
'post_type' => 'Post type - PRO',
);
$eventsFormFactory = apply_filters("pys_form_event_factory",[]);
foreach ($eventsFormFactory as $activeFormPlugin) :
$options[$activeFormPlugin->getSlug()] = $activeFormPlugin->getName().' - PRO';
endforeach;
renderSelectInput( $event, $key, $options );
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderPostTypeSelect(&$event, $key) {
$types = get_post_types(null,"objects ");
$options = array();
foreach ($types as $type) {
$options[$type->name]=$type->label;
}
renderSelectInput( $event, $key, $options );
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderCurrencyParamInput( &$event, $key ) {
$currencies = array(
'AUD' => 'Australian Dollar',
'BRL' => 'Brazilian Real',
'CAD' => 'Canadian Dollar',
'CZK' => 'Czech Koruna',
'DKK' => 'Danish Krone',
'EUR' => 'Euro',
'HKD' => 'Hong Kong Dollar',
'HUF' => 'Hungarian Forint',
'IDR' => 'Indonesian Rupiah',
'ILS' => 'Israeli New Sheqel',
'JPY' => 'Japanese Yen',
'KRW' => 'Korean Won',
'MYR' => 'Malaysian Ringgit',
'MXN' => 'Mexican Peso',
'NOK' => 'Norwegian Krone',
'NZD' => 'New Zealand Dollar',
'PHP' => 'Philippine Peso',
'PLN' => 'Polish Zloty',
'RON' => 'Romanian Leu',
'GBP' => 'Pound Sterling',
'SGD' => 'Singapore Dollar',
'SEK' => 'Swedish Krona',
'CHF' => 'Swiss Franc',
'TWD' => 'Taiwan New Dollar',
'THB' => 'Thai Baht',
'TRY' => 'Turkish Lira',
'USD' => 'U.S. Dollar',
'ZAR' => 'South African Rands'
);
$currencies = apply_filters( 'pys_currencies_list', $currencies );
$options[''] = 'Please, select...';
$options = array_merge( $options, $currencies );
$options['disabled'] = '';
$options['custom'] = 'Custom currency';
renderSelectInput( $event, $key, $options, true );
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderFacebookEventTypeInput( &$event, $key ) {
$options = array(
'ViewContent' => 'ViewContent',
'AddToCart' => 'AddToCart',
'AddToWishlist' => 'AddToWishlist',
'InitiateCheckout' => 'InitiateCheckout',
'AddPaymentInfo' => 'AddPaymentInfo',
'Purchase' => 'Purchase',
'Lead' => 'Lead',
'CompleteRegistration' => 'CompleteRegistration',
'Subscribe' => 'Subscribe',
'CustomizeProduct' => 'CustomizeProduct',
'FindLocation' => 'FindLocation',
'StartTrial' => 'StartTrial',
'SubmitApplication' => 'SubmitApplication',
'Schedule' => 'Schedule',
'Contact' => 'Contact',
'Donate' => 'Donate',
'disabled' => '',
'CustomEvent' => 'CustomEvent',
);
renderSelectInput( $event, $key, $options );
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderFacebookParamInput( &$event, $key ) {
$attr_name = "pys[event][facebook_params][$key]";
$attr_id = 'pys_event_facebook_' . $key;
$attr_value = $event->getFacebookParam( $key );
?>
<input type="text" name="<?php esc_attr_e( $attr_name ); ?>"
id="<?php esc_attr_e( $attr_id ); ?>"
value="<?php esc_attr_e( $attr_value ); ?>"
placeholder="Enter value"
class="form-control">
<?php
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderGoogleAnalyticsActionInput( &$event, $key ) {
$options = array(
'_custom' => 'Custom Action',
'disabled' => '',
'add_payment_info' => 'add_payment_info',
'add_to_cart' => 'add_to_cart',
'add_to_wishlist' => 'add_to_wishlist',
'begin_checkout' => 'begin_checkout',
'checkout_progress' => 'checkout_progress',
'generate_lead' => 'generate_lead',
'login' => 'login',
'purchase' => 'purchase',
'refund' => 'refund',
'remove_from_cart' => 'remove_from_cart',
'search' => 'search',
'select_content' => 'select_content',
'set_checkout_option' => 'set_checkout_option',
'share' => 'share',
'sign_up' => 'sign_up',
'view_item' => 'view_item',
'view_item_list' => 'view_item_list',
'view_promotion' => 'view_promotion',
'view_search_results' => 'view_search_results',
);
renderSelectInput( $event, $key, $options, true );
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderGoogleAnalyticsV4ActionInput( &$event, $key ) {
renderGroupSelectInput( $event, $key, $event->GAEvents, false );
}
/**
* @param CustomEvent $event
* @param string $key
*/
function renderPinterestEventTypeInput( &$event, $key ) {
$options = array(
'pagevisit' => 'PageVisit',
'viewcategory' => 'ViewCategory',
'search' => 'Search',
'addtocart' => 'AddToCart',
'checkout' => 'Checkout',
'watchvideo' => 'WatchVideo',
'signup' => 'Signup',
'lead' => 'Lead',
'custom' => 'Custom',
'disabled' => '',
'CustomEvent' => 'Partner Defined',
);
renderSelectInput( $event, $key, $options );
}

View File

@@ -0,0 +1,100 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function getEddPaymentKey() {
global $edd_receipt_args;
$session = edd_get_purchase_session();
if ( isset( $_GET['payment_key'] ) ) {
return urldecode( $_GET['payment_key'] );
} else if ( $session && isset($session['purchase_key']) ) {
return $session['purchase_key'];
} elseif ( $edd_receipt_args && isset($edd_receipt_args['payment_key']) && $edd_receipt_args['payment_key'] ) {
return $edd_receipt_args['payment_key'];
} else {
return false;
}
}
/**
* Always returns download price as is to make Free compatible with PRO.
* Used by Pinterest add-on.
*
* @return float
*/
function getEddDownloadPrice( $download_id, $price_index = null ) {
return getEddDownloadPriceToDisplay( $download_id, $price_index );
}
function getEddDownloadPriceToDisplay( $download_id, $price_index = null ) {
if ( edd_has_variable_prices( $download_id ) ) {
$prices = edd_get_variable_prices( $download_id );
if ( $price_index !== null ) {
// get selected price option
$price = isset( $prices[ $price_index ] ) ? $prices[ $price_index ]['amount'] : 0;
} else {
// get default price option
$default_option = edd_get_default_variable_price( $download_id );
$price = $prices[ $default_option ]['amount'];
}
} else {
$price = edd_get_download_price( $download_id );
}
return (float) $price;
}
function getEddEventValue( $option, $amount, $global, $percent = 100 ) {
switch ( $option ) {
case 'global':
$value = (float) $global;
break;
case 'percent':
$percents = (float) $percent;
$percents = str_replace( '%', null, $percents );
$percents = (float) $percents / 100;
$value = (float) $amount * $percents;
break;
default: // "price" option
$value = (float) $amount;
}
return $value;
}
/**
* Always returns array with empty values.
* Used by Pinterest add-on.
*
* @return array
*/
function getEddDownloadLicenseData( $download_id ) {
return array(
'transaction_type' => null,
'license_site_limit' => null,
'license_time_limit' => null,
'license_version' => null,
);
}

View File

@@ -0,0 +1,140 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* ConsentMagic
*/
function isConsentMagicPluginActivated() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active( 'consent-magic-pro/consent-magic-pro.php' );
}
function isConsentMagicPluginInstalled() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
$installed_plugins = get_plugins();
$plugin_slug = "consent-magic-pro/consent-magic-pro.php";
return array_key_exists( $plugin_slug, $installed_plugins ) || in_array( $plugin_slug, $installed_plugins, true );
}
function isConsentMagicPluginLicenceActivated() {
$id = get_option('cs_product_id');
if($id && get_option('wc_am_client_'.$id.'_activated') == 'Activated') {
return true;
}
return false;
}
/**
* @link https://wordpress.org/plugins/ginger/
*/
function isGingerPluginActivated() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active( 'ginger/ginger-eu-cookie-law.php' );
}
/**
* @link https://wordpress.org/plugins/cookiebot/
* @link https://www.cookiebot.com/en/developer/
*/
function isCookiebotPluginActivated() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active( 'cookiebot/cookiebot.php' );
}
/**
* @link https://wordpress.org/plugins/cookie-notice/
*/
function isCookieNoticePluginActivated() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active( 'cookie-notice/cookie-notice.php' );
}
/**
* GDPR Cookie Consent
*
* @link https://wordpress.org/plugins/cookie-law-info/
*/
function isCookieLawInfoPluginActivated() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active( 'cookie-law-info/cookie-law-info.php' )
|| is_plugin_active( 'webtoffee-gdpr-cookie-consent/cookie-law-info.php' ) ;
}
/**
* GDPR Real Cookie Banner
*
* @link https://wordpress.org/plugins/real-cookie-banner/
*/
function isRealCookieBannerPluginActivated() {
if ( ! function_exists( 'is_plugin_active' ) ) {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
}
return is_plugin_active( 'real-cookie-banner-pro/index.php' )
|| is_plugin_active( 'real-cookie-banner/index.php' ) ;
}
function adminGdprAjaxNotEnabledNotice() {
$url = buildAdminUrl( 'pixelyoursite', 'gdpr', false, array(
'_wpnonce' => wp_create_nonce( 'pys_enable_gdpr_ajax' ),
'pys' => array(
'enable_gdpr_ajax' => true,
),
) );
?>
<div class="notice notice-error pys_core_gdpr_ajax_notice">
<p>You use the <strong>GDPR Cookie Consent</strong> and <strong>PixelYourSite</strong> plugins. You
must turn on "Enable AJAX filter values update" option to avoid problems with cache plugins.
<a href="<?php echo esc_url( $url ); ?>"><strong>CLICK HERE TO
ENABLE</strong></a>.</p>
</div>
<?php
}
function adminGdprAjaxEnabledNotice() {
?>
<div class="notice notice-success">
<p>All good :)</p>
</div>
<?php
}

View File

@@ -0,0 +1,574 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @param Plugin|Settings $plugin
*/
function renderLicenseControls( $plugin ) {
$slug = $plugin->getSlug();
$input_name = "pys[{$slug}][license_action]";
$license_status = $plugin->getOption( 'license_status' );
?>
<div class="row">
<?php if( $license_status == 'valid' || $license_status == 'expired') : ?>
<div class="col-3">
<?php $plugin->render_text_input( 'license_key', 'Enter your license key', true, true, false); ?>
<button class="btn btn-block btn-sm btn-primary" name="<?php esc_attr_e( $input_name ); ?>"
value="reactivate">Reactivate License</button>
</div>
<?php else : ?>
<div class="col-9">
<?php $plugin->render_text_input( 'license_key', 'Enter your license key', false, false, false ); ?>
</div>
<?php endif; ?>
<div class="col-3">
<?php if( $license_status == 'valid' || $license_status == 'expired') : ?>
<button class="btn btn-block btn-sm btn-danger" name="<?php esc_attr_e( $input_name ); ?>"
value="deactivate">Deactivate License</button>
<?php else : ?>
<button class="btn btn-block btn-sm btn-primary" name="<?php esc_attr_e( $input_name ); ?>"
value="activate">Activate License</button>
<?php endif; ?>
</div>
</div>
<?php
$license_key = $plugin->getOption( 'license_key' );
$license_expires = $plugin->getOption( 'license_expires', null );
$license_expires_soon = false;
$license_expired = false;
if( $license_expires ) {
$now = time();
if( $now >= $license_expires ) {
$license_expired = true;
} elseif ( $now >= ( $license_expires - 30 * DAY_IN_SECONDS ) ) {
$license_expires_soon = true;
}
}
if ( $notice = get_transient( "pys_{$slug}_license_notice" ) ) :
?>
<div class="row mt-3">
<div class="col">
<div class="alert alert-<?php esc_attr_e( $notice['class'] ); ?> mb-0" role="alert">
<?php echo $notice['msg']; ?>
</div>
</div>
</div>
<?php
delete_transient( "pys_{$slug}_license_notice" );
endif;
if ( $license_expires_soon ) :
?>
<div class="row mt-3">
<div class="col">
<div class="alert alert-warning mb-0">
<p>Your license key <strong>expires
on <?php echo date( get_option( 'date_format' ), $license_expires ); ?></strong>. Make sure
you keep everything updated and in order.</p>
<p>If you renewed your license but you still see this message, click on the "Reactivate License" button.</p>
<p class="mb-0"><a href="https://www.pixelyoursite.com/checkout/?edd_license_key=<?php esc_attr_e(
$license_key ); ?>&utm_campaign=admin&utm_source=licenses&utm_medium=renew" target="_blank"><strong>Click here to renew your license now for a 40% discount</strong></a></p>
</div>
</div>
</div>
<?php
endif;
if ( $license_expired ) :
?>
<div class="row mt-3">
<div class="col">
<div class="alert alert-danger mb-0">
<p><strong>Your license key is expired</strong>, so you no longer get any updates. Don't miss our
latest improvements and make sure that everything works smoothly.</p>
<p>If you renewed your license but you still see this message, click on the "Reactivate License" button.</p>
<p class="mb-0"><a href="https://www.pixelyoursite.com/checkout/?edd_license_key=<?php esc_attr_e(
$license_key ); ?>&utm_campaign=admin&utm_source=licenses&utm_medium=renew" target="_blank"><strong>Click here to renew your license now</strong></a></p>
</div>
</div>
</div>
<?php
endif;
}
function checkLicense()
{
$plugins = PYS()->getRegisteredPlugins();
if(!get_option(PYS()->getSlug().'_last_check_license') || get_option(PYS()->getSlug().'_last_check_license')['time'] == '' || get_option(PYS()->getSlug().'_last_check_license')['time'] < time() && PYS()->getOption('license_key') && !empty(PYS()->getOption('license_key')))
{
$license_data = singleCheckLicense(PYS()->getOption('license_key'), PYS());
update_option(PYS()->getSlug().'_last_check_license', array('name'=>PYS()->getPluginName(), 'time'=>time()));
if(!empty($license_data_single)) {
set_data_license(PYS(), $license_data);
}
}
foreach ($plugins as $plugin)
{
if ( $plugin->getSlug() == 'head_footer' ) { continue; }
if(!get_option($plugin->getSlug().'_last_check_license') || get_option($plugin->getSlug().'_last_check_license')['time'] == '' || get_option($plugin->getSlug().'_last_check_license')['time'] < time() && $plugin->getOption('license_key') && !empty($plugin->getOption('license_key')))
{
update_option($plugin->getSlug().'_last_check_license', array('name'=>$plugin->getPluginName(), 'time'=>time()));
$license_data_single = singleCheckLicense($plugin->getOption('license_key'), $plugin);
if(!empty($license_data_single)) {
set_data_license($plugin, $license_data_single);
}
}
}
}
function set_data_license($plugin, $license_data)
{
$license_status = $plugin->getOption( 'license_status' );
$license_expires = $plugin->getOption( 'license_expires' );
$license_key = $plugin->getOption( 'license_key' );
$slug = $plugin->getSlug();
$admin_notice = array();
if ( is_wp_error( $license_data ) ) {
$admin_notice = array(
'class' => 'danger',
'msg' => 'Something went wrong during license update request. [' . $license_data->get_error_message() . ']'
);
} else {
/**
* Overwrite empty license status only on successful activation.
* For existing status overwrite with any value except error.
*/
if ( empty( $license_status ) && $license_data->license == 'valid' ) {
$license_status = 'valid';
} elseif ( ! empty( $license_status ) ) {
$license_status = $license_data->license;
}
if ( $license_data->success ) {
switch ( $license_data->license ) {
case
'valid':
$admin_notice = array(
'class' => 'success',
'msg' => 'Your license is working fine. Good job!'
);
break;
case 'deactivated':
$admin_notice = array(
'class' => 'success',
'msg' => 'Your license was successfully deactivated for this site.'
);
break;
case 'expired': // license has expired
$admin_notice = array(
'class' => 'danger',
'msg' => 'Your License has expired. <a href="http://www.pixelyoursite.com/checkout/?edd_license_key=' . urlencode( $license_key ) . '&utm_campaign=admin&utm_source=licenses&utm_medium=renew" target="_blank">Renew it now.</a>'
);
break;
case 'inactive': // license is not active
$admin_notice = array(
'class' => 'danger',
'msg' => 'This license is not active. Activate it now.'
);
break;
case 'disabled': // license key disabled
$admin_notice = array(
'class' => 'danger',
'msg' => 'License key disabled.'
);
break;
case 'license_not_activable': // trying to activate bundle license
$admin_notice = array(
'class' => 'danger',
'msg' => 'If you have a bundle package, please use each individual license for your products.'
);
break;
case 'revoked': // license key revoked
$admin_notice = array(
'class' => 'danger',
'msg' => 'This license was revoked.'
);
break;
}
$license_expires = strtotime( $license_data->expires );
} else {
switch ( $license_data->license ) {
case 'invalid': // key do not exist
case 'missing':
case 'key_mismatch':
$admin_notice = array(
'class' => 'danger',
'msg' => "License keys don't match. Make sure you're using the correct license."
);
break;
case 'license_not_activable': // trying to activate bundle license
$admin_notice = array(
'class' => 'danger',
'msg' => 'If you have a bundle package, please use each individual license for your products.'
);
break;
case 'revoked': // license key revoked
$admin_notice = array(
'class' => 'danger',
'msg' => 'This license was revoked.'
);
break;
case 'no_activations_left': // no activations left
$admin_notice = array(
'class' => 'danger',
'msg' => 'No activations left. Log in to your account to extent your license.'
);
break;
case 'invalid_item_id':
$admin_notice = array(
'class' => 'danger',
'msg' => 'Invalid item ID.'
);
break;
case 'item_name_mismatch': // item names don't match
$admin_notice = array(
'class' => 'danger',
'msg' => "Item names don't match."
);
break;
case 'site_inactive':
$admin_notice = array(
'class' => 'danger',
'msg' => 'The license is not active for this site. Activate it now.'
);
break;
}
// add error code
$admin_notice['msg'] .= " [error: $license_data->license]";
}
}
if ( ! empty( $admin_notice ) ) {
set_transient( "pys_{$slug}_license_notice", $admin_notice, 60 * 5 );
}
$plugin->updateOptions(
array (
'license_key' => $license_key,
'license_status' => $license_status,
'license_expires' => $license_expires
)
);
}
function singleCheckLicense( $license_key, $plugin)
{
$api_params = array(
'edd_action' => 'check_license',
'license' => $license_key,
'item_name' => urlencode( $plugin->getPluginName() ),
'url' => home_url()
);
$response = wp_remote_post( 'https://www.pixelyoursite.com', array(
'timeout' => 120,
'sslverify' => false,
'body' => $api_params
) );
if ( is_wp_error( $response ) ) {
return $response;
}
// $license_data->license will be either "valid" or "invalid"
return json_decode( wp_remote_retrieve_body( $response ) );
}
/**
* @param Plugin|Settings $plugin
*/
function updateLicense( $plugin ) {
$slug = $plugin->getSlug();
$license_key_old = $plugin->getOption( 'license_key' );
// nothing to do...
if( ! isset( $_POST['pys'][ $slug ]['license_action'] ) ) {
return;
}
$last_check_license = time();
$license_action = $_POST['pys'][ $slug ]['license_action'];
if(isset( $_POST['pys'][ $slug ]['license_key'] )) {
$license_key = sanitize_text_field($_POST['pys'][ $slug ]['license_key']);
} else {
$license_key = '';
}
// activate/deactivate license
if ( $license_action == 'activate' ) {
$license_data = licenseActivate( $license_key, $plugin );
} else if ( $license_action == 'reactivate' ) {
if($license_key_old)
{
$license_key = $license_key_old;
}
$license_data = licenseActivate($license_key, $plugin);
}
else {
if($license_key_old)
{
$license_key = $license_key_old;
}
$license_data = licenseDeactivate( $license_key, $plugin );
}
if(!empty($license_data)) {
update_option($plugin->getSlug() . '_last_check_license', array('name' => $plugin->getPluginName(), 'time' => $last_check_license));
$license_status = $plugin->getOption('license_status');
$license_expires = $plugin->getOption('license_expires');
$admin_notice = array();
if (is_wp_error($license_data)) {
$admin_notice = array(
'class' => 'danger',
'msg' => 'Something went wrong during license update request. [' . $license_data->get_error_message() . ']'
);
} else {
/**
* Overwrite empty license status only on successful activation.
* For existing status overwrite with any value except error.
*/
if (empty($license_status) && $license_data->license == 'valid') {
$license_status = 'valid';
} elseif (!empty($license_status)) {
$license_status = $license_data->license;
}
if ($license_data->success) {
switch ($license_data->license) {
case
'valid':
$admin_notice = array(
'class' => 'success',
'msg' => 'Your license is working fine. Good job!'
);
break;
case 'deactivated':
$admin_notice = array(
'class' => 'success',
'msg' => 'Your license was successfully deactivated for this site.'
);
break;
}
$license_expires = strtotime($license_data->expires);
} else {
switch ($license_data->license) {
case 'invalid': // key do not exist
case 'missing':
case 'key_mismatch':
$admin_notice = array(
'class' => 'danger',
'msg' => "License keys don't match. Make sure you're using the correct license."
);
break;
case 'license_not_activable': // trying to activate bundle license
$admin_notice = array(
'class' => 'danger',
'msg' => 'If you have a bundle package, please use each individual license for your products.'
);
break;
case 'revoked': // license key revoked
$admin_notice = array(
'class' => 'danger',
'msg' => 'This license was revoked.'
);
break;
case 'no_activations_left': // no activations left
$admin_notice = array(
'class' => 'danger',
'msg' => 'No activations left. Log in to your account to extent your license.'
);
break;
case 'invalid_item_id':
$admin_notice = array(
'class' => 'danger',
'msg' => 'Invalid item ID.'
);
break;
case 'item_name_mismatch': // item names don't match
$admin_notice = array(
'class' => 'danger',
'msg' => "Item names don't match."
);
break;
case 'expired': // license has expired
$admin_notice = array(
'class' => 'danger',
'msg' => 'Your License has expired. <a href="http://www.pixelyoursite.com/checkout/?edd_license_key=' . urlencode($license_key) . '&utm_campaign=admin&utm_source=licenses&utm_medium=renew" target="_blank">Renew it now.</a>'
);
break;
case 'inactive': // license is not active
$admin_notice = array(
'class' => 'danger',
'msg' => 'This license is not active. Activate it now.'
);
break;
case 'disabled': // license key disabled
$admin_notice = array(
'class' => 'danger',
'msg' => 'License key disabled.'
);
break;
case 'site_inactive':
$admin_notice = array(
'class' => 'danger',
'msg' => 'The license is not active for this site. Activate it now.'
);
break;
}
// add error code
$admin_notice['msg'] .= " [error: $license_data->license]";
}
}
if (!empty($admin_notice)) {
set_transient("pys_{$slug}_license_notice", $admin_notice, 60 * 5);
}
$plugin->updateOptions(
array(
'license_key' => $license_key,
'license_status' => $license_status,
'license_expires' => $license_expires
)
);
}
}
/**
* @param string $license_key
* @param Plugin|Settings $plugin
*
* @return array|mixed|object|\WP_Error
*/
function licenseActivate( $license_key, $plugin ) {
$api_params = array(
'edd_action' => 'activate_license',
'license' => $license_key,
'item_name' => urlencode( $plugin->getPluginName() ),
'url' => home_url()
);
$response = wp_remote_post( 'https://www.pixelyoursite.com', array(
'timeout' => 120,
'sslverify' => false,
'body' => $api_params
) );
if ( is_wp_error( $response ) ) {
return $response;
}
// $license_data->license will be either "valid" or "invalid"
return json_decode( wp_remote_retrieve_body( $response ) );
}
/**
* @param string $license_key
* @param Plugin|Settings $plugin
*
* @return array|mixed|object|\WP_Error
*/
function licenseDeactivate( $license_key, $plugin ) {
$api_params = array(
'edd_action' => 'deactivate_license',
'license' => $license_key,
'item_name' => urlencode( $plugin->getPluginName() ),
'url' => home_url()
);
$response = wp_remote_post( 'https://www.pixelyoursite.com', array(
'timeout' => 120,
'sslverify' => false,
'body' => $api_params
) );
if ( is_wp_error( $response ) ) {
return $response;
}
// $license_data->license will be either "deactivated" or "failed"
return json_decode( wp_remote_retrieve_body( $response ) );
}

View File

@@ -0,0 +1,63 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function maybeMigrate() {
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
return;
}
if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) {
return;
}
$pys_free_7_version = get_option( 'pys_core_version', false );
if ($pys_free_7_version && version_compare($pys_free_7_version, '9.0.0', '<') ) {
migrate_9_0_0();
update_option( 'pys_core_version', PYS_FREE_VERSION );
update_option( 'pys_updated_at', time() );
} elseif ($pys_free_7_version && version_compare($pys_free_7_version, '7.1.0', '<')) {
migrate_7_1_0_bing_defaults();
update_option( 'pys_core_version', PYS_FREE_VERSION );
update_option( 'pys_updated_at', time() );
}
}
function migrate_9_0_0() {
$globalOptions = [
"automatic_events_enabled" => PYS()->getOption("signal_events_enabled") || PYS()->getOption("automatic_events_enabled"),
"automatic_event_form_enabled" => PYS()->getOption("signal_form_enabled"),
"automatic_event_download_enabled" => PYS()->getOption("signal_download_enabled"),
"automatic_event_comment_enabled" => PYS()->getOption("signal_comment_enabled"),
"automatic_event_scroll_enabled" => PYS()->getOption("signal_page_scroll_enabled"),
"automatic_event_time_on_page_enabled" => PYS()->getOption("signal_time_on_page_enabled"),
"automatic_event_scroll_value" => PYS()->getOption("signal_page_scroll_value"),
"automatic_event_time_on_page_value" => PYS()->getOption("signal_time_on_page_value"),
"automatic_event_download_extensions" => PYS()->getOption("download_event_extensions"),
];
PYS()->updateOptions($globalOptions);
}
function migrate_7_1_0_bing_defaults() {
$bing_defaults = array(
'gdpr_bing_prior_consent_enabled' => true,
'gdpr_cookiebot_bing_consent_category' => 'marketing',
);
// update settings
PYS()->updateOptions( $bing_defaults );
PYS()->reloadOptions();
}

View File

@@ -0,0 +1,199 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
add_action( 'admin_notices', 'PixelYourSite\adminRenderOptinNotices' );
function adminRenderOptinNotices() {
if ( ! current_user_can( 'manage_pys' ) ) {
return;
}
$user = wp_get_current_user();
$user_id = $user->ID;
// never show again for opted-in users
if ( get_user_meta( $user_id, 'pys_core_opted_in_dismissed_at', true ) ) {
return;
}
$second_time_dismissed_at = get_user_meta( $user_id, 'pys_core_optin_second_time_dismissed_at', true );
$first_time_dismissed_at = get_user_meta( $user_id, 'pys_core_optin_first_time_dismissed_at', true );
if ( get_user_meta( $user_id, 'pys_core_optin_third_time_dismissed_at', true ) ) {
return; // was dismissed 3 times
} elseif ( $second_time_dismissed_at ) {
$month_ago = time() - MONTH_IN_SECONDS;
if ( $month_ago < $second_time_dismissed_at ) {
return; // hide if dismissed less then month ago
}
$header = 'Free PIXELYOURSITE HACKS: Improve your ads return and website tracking - LAST CALL';
$dismiss_key = 'optin_third_time';
} elseif ( $first_time_dismissed_at ) {
$week_ago = time() - WEEK_IN_SECONDS;
if ( $week_ago < $first_time_dismissed_at ) {
return; // hide if dismissed less then week ago
}
$header = 'PIXELYOURSITE HACKS: Improve your ads return and website tracking with FREE Facebook, Google and Pinterest hacks';
$dismiss_key = 'optin_second_time';
} else { // was never dismissed
$header = 'Free PIXELYOURSITE HACKS: Improve your ads return and website tracking';
$dismiss_key = 'optin_first_time';
}
// hide close button on PYS pages
$dismissable = empty( $_REQUEST['page'] ) || $_REQUEST['page'] != 'pixelyoursite';
// on PYS pages message always same
if ( ! $dismissable ) {
$header = 'Free PIXELYOURSITE HACKS: Improve your ads return and website tracking';
$dismiss_key = '';
}
?>
<style type="text/css">
.notice.pys-notice-wrapper {
display: flex;
align-items: center;
padding-top: 15px;
padding-bottom: 15px;
}
.pys-notice-content h4 {
margin-bottom: 10px;
}
.pys-notice-logo {
margin-right: 15px;
width: 50px;
max-width: 50px;
height: auto;
}
.pys-notice-wrapper h4 {
margin-top: 0;
}
.pys-form-text,
.pys-notice-label {
display: block;
margin-top: 4px;
font-size: 12px;
font-weight: 400;
color: #495057 !important;
}
.pys-notice-form-group:not(:last-child) {
margin-right: 12px;
}
</style>
<div class="notice <?php echo $dismissable ? 'is-dismissible' : ''; ?> pys-optin-notice pys-notice-wrapper">
<img src="<?php echo PYS_FREE_URL . '/dist/images/pys-square-logo-small.png'; ?>" class="pys-notice-logo">
<div class="pys-notice-content">
<h4><?php echo $header; ?></h4>
<form style="display: flex;">
<div class="pys-notice-form-group">
<input type="text" name="name" placeholder="Your name"
value="<?php esc_attr_e( $user->first_name ); ?>">
</div>
<div class="pys-notice-form-group">
<input type="email" name="email" required
placeholder="Your e-mail" value="<?php esc_attr_e( $user->user_email ); ?>">
</div>
<?php if ( isWooCommerceActive() ) : ?>
<div class="pys-notice-form-group">
<label class="pys-notice-label">
<input type="checkbox" name="tag[]" value="with-woo" checked>I use WooCommerce
</label>
</div>
<?php endif; ?>
<?php if ( isEddActive() ) : ?>
<div class="pys-notice-form-group">
<label class="pys-notice-label">
<input type="checkbox" name="tag[]" value="with-edd" checked>I use Easy Digital Downloads
</label>
</div>
<?php endif; ?>
<div class="pys-notice-form-group">
<button class="button button-primary" style="margin-top: -2px;">SEND ME FREE HACKS</button>
</div>
<div class="pys-notice-form-group">
<small class="pys-form-text">No spam. You can unsubscribe at any time.</small>
</div>
</form>
</div>
</div>
<script type="application/javascript">
jQuery(document).on('click', '.pys-optin-notice .notice-dismiss', function () {
jQuery.ajax({
url: ajaxurl,
data: {
action: 'pys_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: 'core',
meta_key: '<?php esc_attr_e( $dismiss_key ); ?>'
}
})
});
jQuery(document).on('submit', '.pys-optin-notice form', function (e) {
e.preventDefault();
var $form = jQuery(this),
name = $form.find('input[name="name"]').val(),
email = $form.find('input[name="email"]').val(),
$tags = $form.find('input[name="tag[]"]:checked'),
tags = [];
$tags.each(function (i, elem) {
tags.push(jQuery(elem).val());
});
jQuery.ajax({
url: 'https://pixelyoursite.com/wp-admin/admin-ajax.php',
method: 'POST',
crossDomain: true,
data: {
action: 'pys_optin_add',
name: name,
email: email,
tags: tags
},
beforeSend: function () {
$form.find('input, button').attr('disabled', true);
},
success: function (resp) {
console.log(resp);
$form.closest('.pys-notice-wrapper').fadeOut();
if (resp.success) {
setOptedInMeta();
}
}
});
var setOptedInMeta = function () {
jQuery.ajax({
url: ajaxurl,
method: 'POST',
data: {
action: 'pys_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: 'core',
meta_key: 'opted_in'
}
});
};
});
</script>
<?php
}

View File

@@ -0,0 +1,195 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function adminRenderPromoNotice() {
if ( ! current_user_can( 'manage_pys' ) ) {
return;
}
$notice = adminGetCurrentPromoNotice();
if ( ! $notice ) {
return;
}
$user_id = get_current_user_id();
?>
<div class="notice notice-warning is-dismissible pys-promo-notice">
<p><?php echo $notice; ?></p>
</div>
<script type='application/javascript'>
jQuery(document).on('click', '.pys-promo-notice .notice-dismiss', function () {
jQuery.ajax({
url: ajaxurl,
data: {
action: 'pys_notice_dismiss',
nonce: '<?php esc_attr_e( wp_create_nonce( 'pys_notice_dismiss' ) ); ?>',
user_id: '<?php esc_attr_e( $user_id ); ?>',
addon_slug: 'free',
meta_key: 'promo_notice'
}
});
});
</script>
<?php
}
function adminGetCurrentPromoNotice() {
try {
$user_id = get_current_user_id();
/**
* Determine which promo notices set is currently in use.
* If meta is not present yet, it can be clean install or update from pre 7.x.
*/
$meta = get_user_meta( $user_id, 'pys_free_current_promo_notices_set', true );
if ( ! $meta ) {
$meta = get_option( 'pixel_your_site', [] );
if ( empty( $meta ) ) {
// clean installation
/** @noinspection PhpIncludeInspection */
} else {
// update from pre 7.x
/** @noinspection PhpIncludeInspection */
}
} else {
$path = PYS_FREE_PATH . '/notices/' . $meta . '.php';
if ( file_exists( $path) ) {
require_once $path;
} else {
return false;
}
}
/**
* Get promo notices start time or use current time if was not set before.
*/
$activation_time = (int) get_option( 'pys_free_promo_notices_start_time', 0 );
if ( ! $activation_time ) {
$activation_time = time();
update_option( 'pys_free_promo_notices_start_time', $activation_time );
}
// calc days passed since notices
$days_passed = daysPassedFromTime( $activation_time );
/**
* Load current notices set and select sub set depends on active plugins.
*/
$set = adminGetPromoNoticesContent();
if ( isWooCommerceActive() && array_key_exists( 'woo', $set ) ) {
$notices = $set['woo'];
} elseif ( isEddActive() && array_key_exists( 'edd', $set ) ) {
$notices = $set['edd'];
} elseif ( array_key_exists( 'no_woo_no_edd', $set ) ) {
$notices = $set['no_woo_no_edd'];
} else {
return false;
}
if (!is_array($notices) || empty($notices)) {
$next = isset($set['next']) ? $set['next'] : false;
if (!$next) {
return false;
}
$path = PYS_FREE_PATH . '/notices/' . $next . '.php';
if (file_exists($path)) {
update_user_meta( $user_id, 'pys_free_current_promo_notices_set', $next );
}
return false;
}
/**
* Get current notice.
*/
$current_notice_key = (int) get_user_meta( $user_id, 'pys_free_current_promo_notice_key', true );
if ( ! $current_notice_key ) {
$current_notice_key = 0;
update_user_meta( $user_id, 'pys_free_current_promo_notice_key', $current_notice_key );
}
return adminGetSinglePromoNoticeContent( $notices, $current_notice_key, $days_passed, $user_id );
} catch ( \Exception $e ) {
return false;
}
}
function adminGetSinglePromoNoticeContent($notices, $current_key, $days_passed, $user_id) {
// last notice reached in set
if ( ! array_key_exists( $current_key, $notices ) ) {
//@todo: load next set and reset "dismissed" meta
return false;
}
$notice = $notices[ $current_key ];
// if notice is disabled, use next one
if ( array_key_exists( 'disabled', $notice ) && $notice['disabled'] ) {
return adminGetSinglePromoNoticeContent( $notices, $current_key + 1, $days_passed, $user_id );
}
// check notice time frame
$from = array_key_exists( 'from', $notice ) ? (int) $notice['from'] : 0;
$to = array_key_exists( 'to', $notice ) ? (int) $notice['to'] : PHP_INT_MAX;
// if notice is time is not reached yet
if ( $days_passed < $from ) {
return false;
}
// notice time is passed already, use next one
if ( $days_passed > $to ) {
delete_user_meta( $user_id, 'pys_free_promo_notice_dismissed_at' );
return adminGetSinglePromoNoticeContent( $notices, $current_key + 1, $days_passed, $user_id );
}
$dismissed = get_user_meta( $user_id, 'pys_free_promo_notice_dismissed_at', true );
if ( $dismissed ) {
return false;
}
return array_key_exists( 'content', $notice ) ? $notice['content'] : false;
}
function daysPassedFromTime( $time_to_compare ) {
$now = time();
$time_passed = ( $now - $time_to_compare ) / DAY_IN_SECONDS;
$time_passed = floor( $time_passed );
return $time_passed;
}

View File

@@ -0,0 +1,221 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
const HTML_WARNING = '<i class="fa fa-exclamation-triangle text-warning" aria-hidden="true" style="color: #fa0;"></i> ';
const HTML_CRITICAL = '<i class="fa fa-exclamation-circle" aria-hidden="true" style="color: #d64d4d;"></i> ';
const TEXT_WARNING = '[warning] ';
const TEXT_CRITICAL = '[critical] ';
/**
* @return array
*/
function get_system_report_data( $for_download = false ) {
global $wpdb;
/**
* Wordpress
*/
$wordpress = array(
'Home URL' => get_option( 'home' ),
'Site URL' => get_option( 'siteurl' ),
'WP version' => get_bloginfo( 'version' ),
'WP multisite' => is_multisite() ? 'Yes' : 'No',
'Language' => get_locale(),
);
/**
* Server
*/
// check php version
if ( version_compare( phpversion(), '5.3.0', '<' ) ) {
$version_check = $for_download ? TEXT_CRITICAL : HTML_CRITICAL;
$version_check .= 'Ask your hosting company to upgrade you to at least PHP 5.6.15 or newer. ';
} elseif ( version_compare( phpversion(), '5.6.14', '<' ) ) {
$version_check = $for_download ? TEXT_WARNING : HTML_WARNING;
$version_check .= 'Ask your hosting company to upgrade you to at least PHP 5.6.15 or newer. ';
} else {
$version_check = '';
}
// check mb_string extension presence
if ( extension_loaded( 'mbstring' ) ) {
$mb_string_check = 'Yes';
} else {
$mb_string_check = $for_download ? TEXT_WARNING : HTML_WARNING;
$mb_string_check .= 'No. Ask your hosting company to upgrade to enable "mbstring" extension.';
}
$server = array(
'Server info' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : 'Unknown',
'PHP version' => phpversion() . $version_check,
'Multibyte string' => $mb_string_check,
'MySQL version' => ( ! empty( $wpdb->is_mysql ) ? $wpdb->db_version() : 'Unknown' ),
);
/**
* Plugins
*/
$plugins = array();
$conflict_plugins = array(
'sumodiscounts/sumodiscounts.php' => array(
'type' => 'warning',
),
'imagify/imagify.php' => array(
'type' => 'warning',
),
);
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
require_once( ABSPATH . 'wp-admin/includes/update.php' );
if ( function_exists( 'get_plugin_updates' ) ) {
// Get both site plugins and network plugins
$active_plugins = (array) get_option( 'active_plugins', array() );
if ( is_multisite() ) {
$network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
$active_plugins = array_merge( $active_plugins, $network_activated_plugins );
}
$available_updates = get_plugin_updates();
foreach ( $active_plugins as $plugin ) {
$data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
$name = $data['Name'];
$value = '';
// check for conflicts
if ( array_key_exists( $plugin, $conflict_plugins ) ) {
$conflict_data = $conflict_plugins[ $plugin ];
if ( $for_download ) {
$value .= $conflict_data['type'] == 'warning' ? TEXT_WARNING : TEXT_CRITICAL;
} else {
$value .= $conflict_data['type'] == 'warning' ? HTML_WARNING : HTML_CRITICAL;
}
}
// add plugin author name and URL
if ( $for_download ) {
$value .= 'by ' . $data['AuthorName'] . ' [' . esc_url_raw( $data['PluginURI'] ) . ']';
} else {
$value .= 'by <a href="' . esc_url_raw( $data['PluginURI'] ) . '" target="_blank">' .
$data['AuthorName'] . '</a> ';
}
// plugin version
$value .= '[' . $data['Version'] . '] ';
// available update version if any
if ( array_key_exists( $plugin, $available_updates ) ) {
$update = $available_updates[ $plugin ];
$value .= '[Update available: ' . $update->update->new_version . '] ';
}
// is network activated?
if ( $data['Network'] ) {
$value .= '[Network] ';
}
$plugins[ $name ] = trim( $value );
}
}
/**
* Theme
*/
$active_theme = wp_get_theme();
$theme = array(
'Name' => $active_theme->Name,
'Version' => $active_theme->Version,
'Author URL' => esc_url_raw( $active_theme->{'Author URI'} ),
'Child Theme' => is_child_theme() ? 'Yes' : 'No',
);
if ( is_child_theme() ) {
$parent_theme = wp_get_theme( $active_theme->Template );
$theme['Parent Theme Name'] = $parent_theme->Name;
$theme['Parent Theme Version'] = $parent_theme->Version;
$theme['Parent Author URL'] = $parent_theme->{'Author URI'};
}
$report = array(
'WordPress Environment' => $wordpress,
'Server Environment' => $server,
'Active Plugins' => $plugins,
'Theme' => $theme,
);
return apply_filters( 'pys_system_report', $report, $for_download );
}
/**
* Process a system report download.
*/
function download_system_report() {
if ( empty( $_POST['pys_action'] ) || 'download_system_report' !== $_POST['pys_action'] ) {
return;
}
if ( ! wp_verify_nonce( $_POST['_wpnonce'], 'pys_download_system_report_nonce' ) ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
// prepare human-readable system report
$output = "";
$report_data = get_system_report_data( true );
foreach ( $report_data as $section_name => $section_report ) {
$output .= "\r\n";
$output .= "### {$section_name } ###";
$output .= "\r\n";
$output .= "\r\n";
foreach ( $section_report as $name => $value ) {
$output .= "{$name}: $value";
$output .= "\r\n";
}
}
// send report to client browser
ignore_user_abort( true );
nocache_headers();
header( 'Content-Type: text/plain; charset=utf-8' );
header( 'Content-Disposition: attachment; filename=pys-system-report-' . date( 'm-d-Y' ) . '.txt' );
header( "Expires: 0" );
echo $output;
exit;
}
add_action( 'admin_init', 'PixelYourSite\download_system_report' );

View File

@@ -0,0 +1,33 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @param Plugin|Settings $plugin
*
* This is used strictly for add-on updates, NOT for updating the core plugin itself (PixelYourSite).
* If you decide to download and install free or paid add-ons from our site (Pinterest Tag, Bing Tag), we will perform checks for updates.
* If you hold a valid license for the add-on, we will download the update from our server.
*
*/
function updatePlugin( $plugin ) {
if ( ! class_exists( 'PixelYourSite\Plugin_Updater' ) ) {
require_once 'class-plugin-updater.php';
}
$license_key = $plugin->getOption( 'license_key' );
new Plugin_Updater( 'https://www.pixelyoursite.com', $plugin->getPluginFile(), array(
'version' => $plugin->getPluginVersion(),
'license' => $license_key,
'item_name' => $plugin->getPluginName(),
'author' => 'PixelYourSite'
)
);
}

View File

@@ -0,0 +1,241 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
function isWooCommerceVersionGte( $version ) {
if ( defined( 'WC_VERSION' ) && WC_VERSION ) {
return version_compare( WC_VERSION, $version, '>=' );
} else if ( defined( 'WOOCOMMERCE_VERSION' ) && WOOCOMMERCE_VERSION ) {
return version_compare( WOOCOMMERCE_VERSION, $version, '>=' );
} else {
return false;
}
}
/**
* @param \WC_Product|\WP_Post $product
*
* @return bool
*/
function wooProductIsType( $product, $type ) {
if ( isWooCommerceVersionGte( '2.7' ) ) {
return $type == $product->is_type( $type );
} else {
return $product->product_type == $type;
}
}
function wooIsRequestContainOrderId() {
return isset( $_REQUEST['key'] ) && $_REQUEST['key'] != ""
|| isset( $_REQUEST['referenceCode'] ) && $_REQUEST['referenceCode'] != ""
|| isset( $_REQUEST['ref_venta'] ) && $_REQUEST['ref_venta'] != ""
|| !empty( $_REQUEST['wcf-order'] );
}
function getWooProductPriceToDisplay( $product_id, $qty = 1 ) {
if ( ! $product = wc_get_product( $product_id ) ) {
return 0;
}
// for Woo Discount Rules
if(method_exists('\Wdr\App\Controllers\ManageDiscount','calculateInitialAndDiscountedPrice')) {
$salePrice = \Wdr\App\Controllers\ManageDiscount::calculateInitialAndDiscountedPrice($product,$qty);
if(is_array($salePrice) && isset($salePrice['discounted_price'])) {
return $salePrice['discounted_price'];
}
}
$productPrice = "";
// take min price for variable product
if($product->get_type() == "variable") {
$prices = $product->get_variation_prices( true );
if(!empty( $prices['price'] )) {
$productPrice = current( $prices['price'] );
}
}
return (float) wc_get_price_to_display( $product, array( 'qty' => $qty,'price'=>$productPrice ) );
}
function getWooCartSubtotal() {
// subtotal is always same value on front-end and depends on PYS options
$include_tax = get_option( 'woocommerce_tax_display_cart' ) == 'incl';
if ( $include_tax ) {
if ( isWooCommerceVersionGte( '3.2.0' ) ) {
$subtotal = (float) WC()->cart->get_subtotal() + (float) WC()->cart->get_subtotal_tax();
} else {
$subtotal = WC()->cart->subtotal;
}
} else {
if ( isWooCommerceVersionGte( '3.2.0' ) ) {
$subtotal = (float) WC()->cart->get_subtotal();
} else {
$subtotal = WC()->cart->subtotal_ex_tax;
}
}
return $subtotal;
}
function getWooEventValue( $valueOption, $global, $percent, $product_id,$qty ) {
$product = wc_get_product($product_id);
if(!$product) return 0;
if($valueOption == 'cog' && isPixelCogActive()) {
$args = array( 'qty' => $qty, 'price' => $product->get_price());
if(get_option( '_pixel_cog_tax_calculating') == 'no') {
$amount = wc_get_price_excluding_tax($product, $args);
} else {
$amount = wc_get_price_including_tax($product,$args);
}
$cog = getAvailableProductCog($product);
if ($cog['val']) {
if ($cog['type'] == 'fix') {
$value = round((float)$amount - (float)$cog['val'], 2);
} else {
$value = round((float)$amount - ((float)$amount * (float)$cog['val'] / 100), 2);
}
} else {
$value = (float)$amount;
}
return $value;
}
$amount = getWooProductPriceToDisplay( $product_id, $qty );
switch ( $valueOption ) {
case 'global': $value = $global; break;
case 'percent':
$percents = (float) $percent;
$percents = str_replace( '%', null, $percents );
$percents = (float) $percents / 100;
$value = (float) $amount * $percents;
break;
default:$value = (float)$amount;
}
return $value;
}
/**
* @param $valueOption
* @param \WC_Order $order
* @param $global
* @param $order_id
* @param $content_ids
* @param int $percent
* @return float|int
*/
function getWooEventValueOrder( $valueOption, $order, $global, $percent = 100 ) {
$amount = $order->get_total();
switch ( $valueOption ) {
case 'global':
$value = (float) $global;
break;
case 'cog':
$cog_value = getAvailableProductCogOrder($order);
($cog_value !== '') ? $value = (float) round($cog_value, 2) : $value = (float) $amount;
if ( !isPixelCogActive() ) $value = (float) $amount;
break;
case 'percent':
$percents = (float) $percent;
$percents = str_replace( '%', null, $percents );
$percents = (float) $percents / 100;
$value = (float) $amount * $percents;
break;
default: // "price" option
$value = (float) $amount;
}
return $value;
}
function getWooEventValueCart( $valueOption, $global, $percent = 100 ) {
if($valueOption == 'cog' && isPixelCogActive()) {
$cog_value = getAvailableProductCogCart();
if($cog_value !== '')
return (float) round($cog_value, 2) ;
if ( get_option( '_pixel_cog_tax_calculating') == 'no' ) {
return WC()->cart->cart_contents_total;
}
return WC()->cart->cart_contents_total + WC()->cart->tax_total;
}
$amount = $params['value'] = WC()->cart->subtotal;
switch ( $valueOption ) {
case 'global':
$value = (float) $global;
break;
case 'percent':
$percents = (float) $percent;
$percents = str_replace( '%', null, $percents );
$percents = (float) $percents / 100;
$value = (float) $amount * $percents;
break;
default: // "price" option
$value = (float) $amount;
}
return $value;
}
function wooGetOrderIdFromRequest() {
if(isset( $_REQUEST['key'] ) && $_REQUEST['key'] != "") {
$order_key = sanitize_key($_REQUEST['key']);
$order_id = (int) wc_get_order_id_by_order_key( $order_key );
return $order_id;
}
if(isset( $_REQUEST['referenceCode'] ) && $_REQUEST['referenceCode'] != "") {
return (int)$_REQUEST['referenceCode'];
}
if(isset( $_REQUEST['ref_venta'] ) && $_REQUEST['ref_venta'] != "") {
return (int)$_REQUEST['ref_venta'];
}
if(!empty($_REQUEST['wcf-order'])) {
return (int)$_REQUEST['wcf-order'];
}
return -1;
}
/**
* Check is Woo Supporting High-Performance Order Storage
* @return bool
*/
function isWooUseHPStorage() {
if(class_exists( \Automattic\WooCommerce\Utilities\OrderUtil::class )) {
return \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled();
}
return false;
}

View File

@@ -0,0 +1,201 @@
<?php
namespace PixelYourSite;
defined('ABSPATH') || exit;
/**
* PYS_Logger class.
*
*/
class PYS_Logger
{
protected $isEnabled = false;
/**
* Stores open file handles.
*/
protected $handle = null;
public function __construct( ) {
}
public function init() {
$this->isEnabled = PYS()->getOption('pys_logs_enable');
}
/**
* Destructor.
*
* Cleans up open file handles.
*/
public function __destruct() {
if ( is_resource( $this->handle ) ) {
fclose( $this->handle ); // @codingStandardsIgnoreLine.
}
}
public function debug($message,$args = null) {
$this->log('debug',$message,$args);
}
public function error($message,$args = null) {
$this->log('error',$message,$args);
}
private function log($level,$message,$args = null) {
if(!$this->isEnabled) return;
if($args) {
$message .= " \nArgs: ".print_r($args,true);
}
$this->handle(time(),$level,$message,[]);
}
/**
* Handle a log entry.
*
* @param int $timestamp Log timestamp.
* @param string $level emergency|alert|critical|error|warning|notice|info|debug.
* @param string $message Log message.
* @param array $context {
* Additional information for log handlers.
* }
*
* @return bool False if value was not handled and true if value was handled.
*/
private function handle( $timestamp, $level, $message, $context ) {
$time_string = date( 'c', $timestamp );
$entry = "{$time_string} {$level} {$message}";
return $this->add( $entry );
}
/**
* Open log file for writing.
*
* @param string $mode Optional. File mode. Default 'a'.
* @return bool Success.
*/
protected function open( $mode = 'a' ) {
if ( $this->is_open() ) {
return true;
}
$file = self::get_log_file_path( );
if ( $file ) {
if ( ! file_exists( $file ) ) {
if(!is_dir(trailingslashit( PYS_FREE_PATH ).'logs/')) {
mkdir(trailingslashit( PYS_FREE_PATH ).'logs/', 0777, true);
}
$temphandle = @fopen( $file, 'w+' ); // @codingStandardsIgnoreLine.
if ( is_resource( $temphandle ) ) {
@fclose( $temphandle ); // @codingStandardsIgnoreLine.
@chmod( $file, FS_CHMOD_FILE ); // @codingStandardsIgnoreLine.
}
}
$resource = @fopen( $file, $mode ); // @codingStandardsIgnoreLine.
if ( $resource ) {
$this->handle = $resource;
return true;
}
}
return false;
}
/**
* Get a log file path.
*
* @return string The log file path or false if path cannot be determined.
*/
public static function get_log_file_path( ) {
return trailingslashit( PYS_FREE_PATH ).'logs/' . self::get_log_file_name( );
}
public static function get_log_file_url( ) {
return trailingslashit( PYS_FREE_URL ) .'logs/'. self::get_log_file_name( );
}
/**
* Get a log file name.
*
* File names consist of the handle, followed by the date, followed by a hash, .log.
*
* @return string The log file name or false if cannot be determined.
*/
public static function get_log_file_name( ) {
return 'pys_debug.log';
}
/**
* Check if a handle is open.
*
* @return bool True if $handle is open.
*/
protected function is_open( ) {
return is_resource( $this->handle );
}
/**
* Close a handle.
*
* @return bool success
*/
protected function close() {
$result = false;
if ( $this->is_open() ) {
$result = fclose( $this->handle ); // @codingStandardsIgnoreLine.
$this->handle = null;
}
return $result;
}
/**
* Add a log entry to chosen file.
*
* @param string $entry Log entry text.
*
* @return bool True if write was successful.
*/
protected function add( $entry ) {
$result = false;
if ( $this->open() && is_resource( $this->handle ) ) {
$result = fwrite( $this->handle, $entry . PHP_EOL ); // @codingStandardsIgnoreLine.
}
return false !== $result;
}
public function getLogs( ) {
if(is_file( self::get_log_file_path() ))
return file_get_contents(self::get_log_file_path());
return "";
}
/**
* Remove/delete the chosen file.
*
* @return bool
*/
public function remove( )
{
$removed = false;
$file = realpath($this::get_log_file_path());
if (is_file($file) && is_writable($file)) { // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
$this->close(); // Close first to be certain no processes keep it alive after it is unlinked.
$removed = unlink($file); // phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_unlink
}
return $removed;
}
}

View File

@@ -0,0 +1,142 @@
{
"general_event_name": "GeneralEvent",
"general_event_delay": 0,
"general_event_on_posts_enabled": true,
"general_event_on_pages_enabled": true,
"general_event_on_tax_enabled": true,
"general_event_on_woo_enabled": true,
"general_event_on_edd_enabled": true,
"cookie_duration": 7,
"last_visit_duration": 60,
"debug_enabled": false,
"do_not_track_user_roles": [],
"admin_permissions": [
"administrator"
],
"block_robot_enabled": false,
"block_ip_enabled": false,
"blocked_ips": [],
"woo_add_to_cart_on_button_click": true,
"woo_add_to_cart_on_cart_page": false,
"woo_add_to_cart_on_checkout_page": false,
"woo_purchase_value_option": "price",
"woo_purchase_value_global": 0,
"woo_initiate_checkout_value_enabled": true,
"woo_initiate_checkout_value_option": "price",
"woo_initiate_checkout_value_global": 0,
"woo_add_to_cart_value_enabled": true,
"woo_add_to_cart_value_option": "price",
"woo_add_to_cart_value_global": 0,
"woo_view_content_delay": 0,
"woo_view_content_value_enabled": true,
"woo_view_content_value_option": "price",
"woo_view_content_value_global": 0,
"edd_add_to_cart_on_button_click": true,
"edd_add_to_cart_on_checkout_page": false,
"edd_purchase_value_option": "price",
"edd_purchase_value_global": 0,
"edd_initiate_checkout_value_enabled": true,
"edd_initiate_checkout_value_option": "price",
"edd_initiate_checkout_value_global": 0,
"edd_add_to_cart_value_enabled": true,
"edd_add_to_cart_value_option": "price",
"edd_add_to_cart_value_global": 0,
"edd_view_content_delay": 0,
"edd_view_content_value_enabled": true,
"edd_view_content_value_option": "price",
"edd_view_content_value_global": 0,
"edd_enabled_save_data_to_orders": true,
"custom_events_enabled": true,
"gdpr_facebook_prior_consent_enabled": true,
"gdpr_analytics_prior_consent_enabled": true,
"gdpr_pinterest_prior_consent_enabled": true,
"gdpr_bing_prior_consent_enabled": true,
"gdpr_cookiebot_integration_enabled": false,
"gdpr_cookiebot_facebook_consent_category": "marketing",
"gdpr_cookiebot_analytics_consent_category": "statistics",
"gdpr_cookiebot_pinterest_consent_category": "marketing",
"gdpr_cookiebot_bing_consent_category": "marketing",
"gdpr_cookie_notice_integration_enabled": false,
"gdpr_cookie_law_info_integration_enabled": false,
"gdpr_ajax_enabled": false,
"gdpr_real_cookie_banner_integration_enabled": false,
"consent_magic_integration_enabled": true,
"woo_purchase_value_cog": "",
"woo_content_value_cog": "",
"woo_add_to_cart_value_cog": "",
"woo_initiate_checkout_value_cog": "",
"fdp_enabled": false,
"edd_purchase_enabled": true,
"edd_initiate_checkout_enabled": true,
"edd_remove_from_cart_enabled": false,
"edd_add_to_cart_enabled": true,
"edd_view_content_enabled": true,
"edd_view_category_enabled": true,
"woo_complete_registration_enabled": false,
"woo_purchase_enabled": true,
"woo_initiate_checkout_enabled": true,
"woo_remove_from_cart_enabled": false,
"woo_add_to_cart_enabled": true,
"woo_view_content_enabled": true,
"woo_view_category_enabled": true,
"woo_enabled_save_data_to_orders": true,
"woo_add_enrich_to_admin_email": true,
"enable_event_url_param": true,
"enable_remove_source_url_params": true,
"enable_post_id_param": true,
"enable_content_name_param": true,
"enable_user_role_param":true,
"enable_page_title_param":true,
"enable_post_type_param": true,
"enable_post_category_param": true,
"enable_woo_category_name_param": true,
"enable_woo_num_items_param": true,
"enable_woo_tags_param":true,
"enable_edd_category_name_param": true,
"enable_edd_num_items_param": true,
"enable_edd_tags_param": true,
"enable_remove_download_url_param": true,
"pys_logs_enable": false,
"woo_add_to_cart_catch_method": "add_cart_hook",
"automatic_events_enabled": false,
"automatic_event_form_enabled": true,
"automatic_event_signup_enabled": true,
"automatic_event_login_enabled": true,
"automatic_event_download_enabled": true,
"automatic_event_comment_enabled": true,
"automatic_event_scroll_enabled": true,
"automatic_event_time_on_page_enabled": true,
"automatic_event_search_enabled": true,
"automatic_event_download_extensions": [
"doc",
"exe",
"js",
"pdf",
"ppt",
"tgz",
"zip",
"xls"
],
"automatic_event_scroll_value": 30,
"automatic_event_time_on_page_value": 30,
"compress_front_js": false,
"enable_success_send_form": false,
"hide_version_plugin_in_console": false
}

View File

@@ -0,0 +1,130 @@
{
"general_event_name": "text",
"general_event_delay": "number",
"general_event_on_posts_enabled": "checkbox",
"general_event_on_pages_enabled": "checkbox",
"general_event_on_tax_enabled": "checkbox",
"general_event_on_woo_enabled": "checkbox",
"general_event_on_edd_enabled": "checkbox",
"cookie_duration": "number",
"last_visit_duration": "number",
"debug_enabled": "checkbox",
"do_not_track_user_roles": "multi_select",
"admin_permissions": "multi_select",
"block_robot_enabled": "checkbox",
"block_ip_enabled": "checkbox",
"blocked_ips": "multi_select",
"woo_add_to_cart_on_button_click": "checkbox",
"woo_add_to_cart_on_cart_page": "checkbox",
"woo_add_to_cart_on_checkout_page": "checkbox",
"woo_purchase_value_option": "radio",
"woo_purchase_value_global": "number",
"woo_initiate_checkout_value_enabled": "checkbox",
"woo_initiate_checkout_value_option": "radio",
"woo_initiate_checkout_value_global": "number",
"woo_add_to_cart_value_enabled": "checkbox",
"woo_add_to_cart_value_option": "radio",
"woo_add_to_cart_value_global": "number",
"woo_view_content_delay": "number",
"woo_view_content_value_enabled": "checkbox",
"woo_view_content_value_option": "radio",
"woo_view_content_value_global": "number",
"woo_enabled_save_data_to_orders": "checkbox",
"woo_add_enrich_to_admin_email": "checkbox",
"edd_add_to_cart_on_button_click": "checkbox",
"edd_add_to_cart_on_checkout_page": "checkbox",
"edd_purchase_value_option": "radio",
"edd_purchase_value_global": "number",
"edd_initiate_checkout_value_enabled": "checkbox",
"edd_initiate_checkout_value_option": "radio",
"edd_initiate_checkout_value_global": "number",
"edd_add_to_cart_value_enabled": "checkbox",
"edd_add_to_cart_value_option": "radio",
"edd_add_to_cart_value_global": "number",
"edd_view_content_delay": "number",
"edd_view_content_value_enabled": "checkbox",
"edd_view_content_value_option": "radio",
"edd_view_content_value_global": "number",
"edd_enabled_save_data_to_orders": "checkbox",
"custom_events_enabled": "checkbox",
"gdpr_facebook_prior_consent_enabled": "checkbox",
"gdpr_analytics_prior_consent_enabled": "checkbox",
"gdpr_pinterest_prior_consent_enabled": "checkbox",
"gdpr_bing_prior_consent_enabled": "checkbox",
"gdpr_cookiebot_integration_enabled": "checkbox",
"gdpr_cookiebot_facebook_consent_category": "text",
"gdpr_cookiebot_analytics_consent_category": "text",
"gdpr_cookiebot_pinterest_consent_category": "text",
"gdpr_cookiebot_bing_consent_category": "text",
"gdpr_cookie_notice_integration_enabled": "checkbox",
"gdpr_cookie_law_info_integration_enabled": "checkbox",
"gdpr_ajax_enabled": "checkbox",
"gdpr_real_cookie_banner_integration_enabled": "checkbox",
"consent_magic_integration_enabled": "checkbox",
"woo_purchase_value_cog": "radio",
"woo_content_value_cog": "radio",
"woo_add_to_cart_value_cog": "radio",
"woo_initiate_checkout_value_cog": "radio",
"fdp_enabled": "checkbox",
"edd_purchase_enabled":"checkbox",
"edd_initiate_checkout_enabled":"checkbox",
"edd_remove_from_cart_enabled":"checkbox",
"edd_add_to_cart_enabled":"checkbox",
"edd_view_content_enabled":"checkbox",
"edd_view_category_enabled":"checkbox",
"woo_complete_registration_enabled": "checkbox",
"woo_purchase_enabled": "checkbox",
"woo_initiate_checkout_enabled": "checkbox",
"woo_remove_from_cart_enabled": "checkbox",
"woo_add_to_cart_enabled": "checkbox",
"woo_view_content_enabled": "checkbox",
"woo_view_category_enabled": "checkbox",
"enable_event_url_param":"checkbox",
"enable_remove_source_url_params":"checkbox",
"enable_post_id_param": "checkbox",
"enable_content_name_param": "checkbox",
"enable_user_role_param":"checkbox",
"enable_page_title_param":"checkbox",
"enable_post_type_param": "checkbox",
"enable_post_category_param": "checkbox",
"compress_front_js": "checkbox",
"enable_woo_category_name_param": "checkbox",
"enable_woo_num_items_param": "checkbox",
"enable_woo_tags_param":"checkbox",
"enable_edd_category_name_param": "checkbox",
"enable_edd_num_items_param": "checkbox",
"enable_edd_tags_param": "checkbox",
"enable_remove_download_url_param": "checkbox",
"pys_logs_enable": "checkbox",
"woo_add_to_cart_catch_method": "select",
"automatic_events_enabled": "checkbox",
"automatic_event_form_enabled": "checkbox",
"automatic_event_signup_enabled": "checkbox",
"automatic_event_login_enabled": "checkbox",
"automatic_event_download_enabled": "checkbox",
"automatic_event_comment_enabled": "checkbox",
"automatic_event_scroll_enabled": "checkbox",
"automatic_event_time_on_page_enabled": "checkbox",
"automatic_event_search_enabled": "checkbox",
"automatic_event_download_extensions": "tag_select",
"automatic_event_scroll_value": "number",
"automatic_event_time_on_page_value": "number",
"enable_success_send_form": "checkbox",
"hide_version_plugin_in_console": "checkbox"
}

View File

@@ -0,0 +1,303 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<!-- Consent Magic -->
<div class="card card-static">
<div class="card-header">
Consent Magic - Recommended
</div>
<div class="card-body">
<?php if (isConsentMagicPluginInstalled()) : ?>
<?php if (isConsentMagicPluginActivated()) : ?>
<div class="row">
<div class="col">
Manage your consent settings with
<?php if (isConsentMagicPluginLicenceActivated()) { ?>
<a href="<?=admin_url("admin.php?page=consent-magic")?>">Consent Magic.</a>
<?php } else { ?>
<a href="<?=admin_url("admin.php?page=cs-license")?>">Consent Magic.</a>
<?php } ?>
</div>
</div>
<?php else: ?>
<div class="row">
<div class="col">
You have Consent Magic installed, but its not activated yet. Go to the Plugins page and activate
<a href="<?=admin_url("plugins.php")?>">Consent Magic.</a>
</div>
</div>
<?php endif; ?>
<?php else: ?>
<div class="row">
<div class="col">
<p>Ask for consent the right way, block scripts and cookies when required.</p>
<p><strong>Manage different type of consent:</strong></p>
<ul class="pys_list">
<li><strong>Ask before tracking:</strong> show a consent message and block the tracking scripts before the
visitor expresses consent - ideal for GDPR.</li>
<li><strong>Inform and opt out:</strong> show a consent message, and block the tracking scripts if the visitor
doesnt agree to tracking - ideal for CCPA.</li>
<li><strong>Just inform:</strong> show a non-intrusive message informing your visitors about tracking.</li>
</ul>
<p><strong>Use geo-targeted rules:</strong></p>
<p>Target your visitors with the right rule based on their location. Rules can have different consent types
and different content. The plugin comes with the ready-made rules:</p>
<ul class="pys_list">
<li><strong>GDPR rule:</strong> targets visitors from GDPR countries, and uses Ask before tracking consent
type.</li>
<li><strong>CCPA rule:</strong> targets visitors from California, and uses Inform and opt-out consent type.</li>
<li><strong>Rest of the world rule:</strong> targets visitors from other locations and uses Just inform consent
type</li>
<li><strong>Your own rule:</strong> create any rules you need, target any countries, and use custom text for them.</li>
</ul>
</div>
</div>
<div class="row justify-content-center">
<div class="col-4">
<a href="https://www.pixelyoursite.com/plugins/consentmagic/?utm_source=pixelyoursite-free&utm_medium=pixelyoursite-free&utm_campaign=pixelyoursite-free&utm_content=pixelyoursite-free&utm_term=pixelyoursite-free" target="_blank" class="btn btn-sm pys_btn_orange">
Lean more about Consent Magic
</a>
</div>
</div>
<?php endif; ?>
</div>
</div>
<!-- Video -->
<div class="card card-static">
<div class="card-header">
Recommended Consent Videos:
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p><a href="https://www.youtube.com/watch?v=uXTpgFu2V-E" target="_blank">The biggest problem with consent messages (7:02 min) - watch now</a></p>
<p><a href="https://www.youtube.com/watch?v=ZOlNbIPS_Uc" target="_blank">Target your visitors with the right consent rule (12:29 min) - watch now</a></p>
<p><a href="https://www.youtube.com/watch?v=P8CLxslSPDk" target="_blank">The right to change your mind (2:46 min) - watch now</a></p>
<p><a href="https://www.youtube.com/watch?v=PsKdCkKNeLU" target="_blank">Facebook Conversion API and the Consent Problem (9:25 min) - watch now</a></p>
</div>
</div>
</div>
</div>
<h2 class="section-title">Other consent plugins:</h2>
<!-- Cookiebot -->
<div class="card">
<div class="card-header">
<?php if ( ! isCookiebotPluginActivated() ) : ?>
Cookiebot <span class="text-danger">[not detected]</span><?php cardCollapseBtn(); ?>
<?php else: ?>
Cookiebot <span class="text-success">[detected]</span><?php cardCollapseBtn(); ?>
<?php endif; ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>This is a complete premium solution that also offers a free plan for websites with under 100 pages.
For implementation, we suggest you follow their documentation.</p>
<p class="mb-0">Website: <a href="https://cookiebot.com" target="_blank">https://cookiebot.com</a></p>
<p class="mb-0">Plugin: <a href="https://wordpress.org/plugins/cookiebot/" target="_blank">https://wordpress.org/plugins/cookiebot/</a></p>
</div>
</div>
<div class="row mt-3">
<div class="col">
<?php PYS()->render_switcher_input( 'gdpr_cookiebot_integration_enabled', false,
! isCookiebotPluginActivated() ); ?>
<h4 class="switcher-label">Enable Cookiebot integration</h4>
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<label class="label-inline">Meta Pixel (formerly Facebook Pixel) consent category:</label>
</div>
<div class="col-4">
<?php PYS()->render_text_input( 'gdpr_cookiebot_facebook_consent_category',
'Enter consent category', ! isCookiebotPluginActivated() ); ?>
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<label class="label-inline">Google Analytics consent category:</label>
</div>
<div class="col-4">
<?php PYS()->render_text_input( 'gdpr_cookiebot_analytics_consent_category',
'Enter consent category', ! isCookiebotPluginActivated() ); ?>
</div>
<div class="col-4">
* If you have advertising features enabled, enter "marketing"
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<label class="label-inline">Google Ads consent category:</label>
</div>
<div class="col-4">
<?php PYS()->render_text_input( 'gdpr_cookiebot_google_ads_consent_category',
'Enter consent category', ! isCookiebotPluginActivated() ); ?>
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<label class="label-inline">Pinterest Tag consent category:</label>
</div>
<div class="col-4">
<?php PYS()->render_text_input( 'gdpr_cookiebot_pinterest_consent_category',
'Enter consent category', ! isCookiebotPluginActivated() ); ?>
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<label class="label-inline">Bing consent category:</label>
</div>
<div class="col-4">
<?php PYS()->render_text_input( 'gdpr_cookiebot_bing_consent_category',
'Enter consent category', ! isCookiebotPluginActivated() ); ?>
</div>
</div>
</div>
</div>
<!-- Cookie Notice -->
<div class="card ">
<div class="card-header">
<?php if ( ! isCookieNoticePluginActivated() ) : ?>
Cookie Notice <span class="text-danger">[not detected]</span><?php cardCollapseBtn(); ?>
<?php else: ?>
Cookie Notice <span class="text-success">[detected]</span><?php cardCollapseBtn(); ?>
<?php endif; ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>Free plugin with various features, including the option to store negative consent.</p>
<p class="mb-0">Plugin: <a href="https://wordpress.org/plugins/cookie-notice/" target="_blank">https://wordpress.org/plugins/cookie-notice/</a>
</p>
</div>
</div>
<div class="row mt-3">
<div class="col">
<?php PYS()->render_switcher_input( 'gdpr_cookie_notice_integration_enabled', false,
! isCookieNoticePluginActivated() ); ?>
<h4 class="switcher-label">Cookie Notice integration</h4>
</div>
</div>
</div>
</div>
<!-- Cookie Law Info -->
<div class="card">
<div class="card-header">
<?php if ( ! isCookieLawInfoPluginActivated() ) : ?>
GDPR Cookie Consent <span class="text-danger">[not detected]</span><?php cardCollapseBtn(); ?>
<?php else: ?>
GDPR Cookie Consent <span class="text-success">[detected]</span><?php cardCollapseBtn(); ?>
<?php endif; ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>Free plugin useful features, including the option to store negative consent.</p>
<p class="mb-0">Plugin: <a href="https://wordpress.org/plugins/cookie-law-info/" target="_blank">https://wordpress.org/plugins/cookie-law-info/</a>
</p>
</div>
</div>
<div class="row mt-3">
<div class="col">
<?php PYS()->render_switcher_input( 'gdpr_cookie_law_info_integration_enabled', false,
! isCookieLawInfoPluginActivated() ); ?>
<h4 class="switcher-label">GDPR Cookie Consent integration</h4>
</div>
</div>
</div>
</div>
<!-- Real Cookie Banner -->
<div class="card">
<div class="card-header">
<?php if ( ! isRealCookieBannerPluginActivated() ) : ?>
Real Cookie Banner <span class="text-danger">[not detected]</span><?php cardCollapseBtn(); ?>
<?php else: ?>
Real Cookie Banner <span class="text-success">[detected]</span><?php cardCollapseBtn(); ?>
<?php endif; ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>Real Cookie Banner is an opt-in cookie and consent management plugin</p>
<p class="mb-0">Plugin: <a href="https://wordpress.org/plugins/real-cookie-banner/" target="_blank">https://wordpress.org/plugins/real-cookie-banner/</a>
</p>
</div>
</div>
<div class="row mt-3">
<div class="col">
<?php PYS()->render_switcher_input( 'gdpr_real_cookie_banner_integration_enabled', false,
! isRealCookieBannerPluginActivated() ); ?>
<h4 class="switcher-label">GDPR Cookie Consent integration</h4>
</div>
</div>
</div>
</div>
<div class="card card-static">
<div class="card-header">
Note
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>These solutions are not perfect or easy to implement especially for a non-technical person. Contact
THEIR support if you need any help. The free plugins might not cover every aspect of the GDPR
legislation.</p>
<p class="mb-0">We are aware of the shortcomings and we try to offer more easy to use integrations in
the feature.</p>
</div>
</div>
</div>
</div>
<!-- API -->
<div class="card card-static">
<div class="card-header">
For Developers
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col">
<?php PYS()->render_switcher_input( 'gdpr_ajax_enabled' ); ?>
<h4 class="switcher-label">Enable AJAX filter values update</h4>
</div>
</div>
<div class="row">
<div class="col">
<p>Use <code>pys_gdpr_ajax_enabled</code>filter to by-pass option above.</p>
</div>
</div>
<div class="row">
<div class="col">
<p>Use following filters to control each pixel:
<code>pys_disable_by_gdpr</code>, <code>pys_disable_facebook_by_gdpr</code>,
<code>pys_disable_analytics_by_gdpr</code>, <code>pys_disable_google_ads_by_gdpr</code>,
<code>pys_disable_pinterest_by_gdpr</code> or <code>pys_disable_bing_by_gdpr</code>.
</p>
<p class="mb-0">First filter will disable all pixels, other can be used to disable particular pixel.
Simply pass <code>TRUE</code> value to disable a pixel.
</p>
</div>
</div>
</div>
</div>
<hr>
<div class="row justify-content-center">
<div class="col-4">
<button class="btn btn-block btn-save">Save Settings</button>
</div>
</div>

View File

@@ -0,0 +1,40 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<div class="wrap" id="pys">
<h1><?php _e( 'PixelYourSite', 'pys' ); ?></h1>
<div class="container">
<div class="row">
<div class="col">
<h2 class="section-title">Licenses</h2>
<form method="post" enctype="multipart/form-data">
<?php wp_nonce_field( 'pys_save_settings' ); ?>
<?php foreach ( PYS()->getRegisteredPlugins() as $plugin ) : /** @var Plugin|Settings $plugin */ ?>
<?php if ( $plugin->getSlug() == 'head_footer' ) { continue; } ?>
<div class="card card-static">
<div class="card-header">
<?php esc_html_e( $plugin->getPluginName() ); ?>
</div>
<div class="card-body">
<?php renderLicenseControls( $plugin ); ?>
</div>
</div>
<?php endforeach; ?>
</form>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,37 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if(isset($_GET['clear_logs'])) {
PYS()->getLog()->remove();
$actual_link = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
wp_redirect(remove_query_arg( 'clear_logs',$actual_link ));
exit;
}
?>
<div class="card card-static">
<div class="card-header ">
<?php PYS()->render_switcher_input('pys_logs_enable');?> Plugin Logs
<div style="float: right;margin-top: 10px;">
<a style="margin-right: 30px" href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite', 'logs' ) ); ?>&clear_logs=true">Clear Logs</a>
<a href="<?= PYS_Logger::get_log_file_url() ?>" target="_blank" download>Download Logs</a>
</div>
</div>
<div class="card-body">
<textarea style="white-space: nowrap;width: 100%;height: 500px;"><?php
echo PYS()->getLog()->getLogs();
?></textarea>
</div>
</div>
<div class="row justify-content-center">
<div class="col-4">
<button class="btn btn-block btn-sm btn-save">Save Settings</button>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,721 @@
<?php
namespace PixelYourSite;
use PixelYourSite\Events;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
if(isset( $_REQUEST['id'] )) {
$id = sanitize_key($_REQUEST['id']);
$event = CustomEventFactory::getById($id );
} else {
$event = new CustomEvent();
}
$serverUrl = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]";
?>
<div class="panel">
<div class="row">
<div class="col">
<div class="d-flex justify-content-between">
<span class="mt-2">With the pro version, you can fire events on clicks, mouse over and page
scroll:</span>
<a target="_blank" class="btn btn-sm btn-primary float-right" href="https://www.pixelyoursite.com/facebook-pixel-plugin/buy-pixelyoursite-pro?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-upgrade-blue">UPGRADE</a>
</div>
</div>
</div>
</div>
<?php wp_nonce_field( 'pys_update_event' ); ?>
<input type="hidden" name="action" value="update">
<?php Events\renderHiddenInput( $event, 'post_id' ); ?>
<div class="card card-static">
<div class="card-header">
General
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col">
<?php Events\renderSwitcherInput( $event, 'enabled' ); ?>
<h4 class="switcher-label">Enable event</h4>
</div>
</div>
<div class="row">
<div class="col">
<?php Events\renderTextInput( $event, 'title', 'Enter event title' ); ?>
<small class="form-text">For internal use only. Something that will help you remember the event.</small>
</div>
</div>
</div>
</div>
<div class="card card-static">
<div class="card-header">
Event Trigger
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col form-inline">
<label>Fire event when</label>
<?php Events\renderTriggerTypeInput( $event, 'trigger_type' ); ?>
<div class="triger_post_type form-inline" style="display: none">
<?php Events\renderPostTypeSelect( $event, 'post_type_value' ); ?>
</div>
<div class="event-delay form-inline">
<label>with delay</label>
<?php Events\renderNumberInput( $event, 'delay', '0' ); ?>
<label>seconds</label>
</div>
</div>
</div>
<div class="row">
<div class="col form-inline">
<?php Events\renderSwitcherInput( $event, 'enable_time_window',true ); ?>
<label>Fire this event only once in</label>
<?php Events\renderNumberInput( $event, 'time_window', '24' ); ?>
<label>hours</label>
<?php renderProBadge( 'https://www.pixelyoursite.com/?utm_source=pys-free-plugin&utm_medium=pro-badge&utm_campaign=pro-feature' ); ?>
</div>
</div>
<div id="page_visit_panel" class="event_triggers_panel" data-trigger_type="page_visit" style="display: none;">
<div class="row mt-3 event_trigger" data-trigger_id="0" style="display: none;">
<div class="col">
<div class="row">
<div class="col-4">
<select class="form-control-sm" name="" autocomplete="off" style="width: 100%;">
<option value="contains">URL Contains</option>
<option value="match">URL Match</option>
<option value="param_contains" disabled="disabled">URL Parameters Contains (PRO)</option>
<option value="param_match" disabled="disabled">URL Parameters Match (PRO)</option>
</select>
</div>
<div class="col-6">
<input name="" placeholder="Enter URL" class="form-control" type="text">
</div>
<div class="col-2">
<button type="button" class="btn btn-sm remove-row">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<?php foreach ( $event->getPageVisitTriggers() as $key => $trigger ) : ?>
<?php $trigger_id = $key + 1; ?>
<div class="row mt-3 event_trigger" data-trigger_id="<?php echo $trigger_id; ?>">
<div class="col">
<div class="row">
<div class="col-4">
<select class="form-control-sm"
name="pys[event][page_visit_triggers][<?php echo $trigger_id; ?>][rule]"
autocomplete="off" style="width: 100%;">
<option value="contains" <?php selected( $trigger['rule'], 'contains' ); ?>>URL Contains</option>
<option value="match" <?php selected( $trigger['rule'], 'match' ); ?>>URL Match</option>
<option value="param_contains" disabled="disabled">URL Parameters Contains (PRO)</option>
<option value="param_match" disabled="disabled">URL Parameters Match (PRO)</option>
</select>
</div>
<div class="col-6">
<input type="text" placeholder="Enter URL" class="form-control"
name="pys[event][page_visit_triggers][<?php echo $trigger_id; ?>][value]"
value="<?php esc_attr_e( $trigger['value'] ); ?>">
</div>
<div class="col-2">
<button type="button" class="btn btn-sm remove-row">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<div class="insert-marker"></div>
<div class="row mt-3">
<div class="col-4">
<button class="btn btn-sm btn-block btn-primary add-event-trigger" type="button">Add another
URL</button>
</div>
</div>
</div>
<div id="url_click_panel" class="event_triggers_panel" style="display: none;">
<div class="row mt-3">
<div class="col">
<div class="row">
<div class="col">
<p>This is a PRO trigger. <a
href="https://www.pixelyoursite.com/facebook-pixel-plugin/buy-pixelyoursite-pro?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-pro-trigger"
target="_blank">Upgrade to get all the benefits</a>.</p>
</div>
</div>
<div class="row">
<div class="col-4">
<?php renderDummySelectInput( 'URL Contains', true ); ?>
</div>
<div class="col-6">
<?php renderDummyTextInput( 'Enter URL' ); ?>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm btn-disabled">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<div class="row mt-3 mb-5">
<div class="col-4">
<button class="btn btn-sm btn-block btn-disabled" type="button">Add another
URL</button>
</div>
</div>
</div>
<div id="css_click_panel" class="event_triggers_panel" style="display: none;">
<div class="row mt-3">
<div class="col">
<div class="row">
<div class="col-10">
<?php renderDummyTextInput( 'Enter CSS selector' ); ?>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm btn-disabled">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<div class="row mt-3 mb-5">
<div class="col-4">
<button class="btn btn-sm btn-block btn-disabled" type="button">Add another
selector</button>
</div>
</div>
</div>
<div id="css_mouseover_panel" class="event_triggers_panel" style="display: none;">
<div class="row mt-3">
<div class="col">
<div class="row">
<div class="col-10">
<?php renderDummyTextInput( 'Enter CSS selector' ); ?>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm btn-disabled">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<div class="row mt-3 mb-5">
<div class="col-4">
<button class="btn btn-sm btn-block btn-disabled" type="button">Add another
selector</button>
</div>
</div>
</div>
<div id="scroll_pos_panel" class="event_triggers_panel" style="display: none;">
<div class="row mt-3">
<div class="col">
<div class="row">
<div class="col-3">
<?php renderDummyNumberInput(); ?>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm btn-disabled">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<div class="row mt-3 mb-5">
<div class="col-4">
<button class="btn btn-sm btn-block btn-disabled" type="button">Add another
threshold</button>
</div>
</div>
</div>
<?php $eventsFormFactory = apply_filters("pys_form_event_factory",[]);
foreach ($eventsFormFactory as $activeFormPlugin) : ?>
<div id="<?php echo $activeFormPlugin->getSlug();?>_panel" class="event_triggers_panel" data-trigger_type="<?php echo $activeFormPlugin->getSlug();?>" style="display: none;">
<div class="row mt-3 event_trigger" data-trigger_id="0">
<div class="col">
<?php renderDummySelectInput('Forms');?>
</div>
</div>
<small class="form-text">Select Forms to Trigger the Event.</small>
</div>
<?php
endforeach;
?>
<div id="url_filter_panel" class="event_triggers_panel" style="display: none;">
<div class="row mt-3">
<div class="col">
<div class="row">
<div class="col-10">
<?php renderDummyTextInput( 'Enter URL' ); ?>
</div>
<div class="col-2">
<button type="button" class="btn btn-sm btn-disabled">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col-4">
<button class="btn btn-sm btn-block btn-disabled" type="button">Add URL filter</button>
</div>
</div>
</div>
</div>
</div>
<?php if ( Facebook()->enabled() ) : ?>
<div class="card card-static">
<div class="card-header">
Facebook
</div>
<div class="card-body">
<div class="row">
<div class="col">
<?php Events\renderSwitcherInput( $event, 'facebook_enabled' ); ?>
<h4 class="switcher-label">Enable on Facebook</h4>
</div>
</div>
<div id="facebook_panel">
<div class="row mt-3">
<div class="col col-offset-left form-inline">
<label>Event type:</label>
<?php Events\renderFacebookEventTypeInput( $event, 'facebook_event_type' ); ?>
<div class="facebook-custom-event-type form-inline">
<?php Events\renderTextInput( $event, 'facebook_custom_event_type', 'Enter name' ); ?>
</div>
</div>
</div>
<div class="row mt-3">
<div class="col col-offset-left">
<?php Events\renderSwitcherInput( $event, 'facebook_params_enabled' ); ?>
<h4 class="indicator-label">Add Parameters</h4>
</div>
</div>
<div id="facebook_params_panel">
<div class="row mt-3">
<div class="col col-offset-left">
<div class="row mb-3 ViewContent Search AddToCart AddToWishlist InitiateCheckout AddPaymentInfo Purchase Lead CompleteRegistration Subscribe StartTrial">
<label class="col-5 control-label">value</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'value' ); ?>
</div>
</div>
<div class="row mb-3 ViewContent Search AddToCart AddToWishlist InitiateCheckout AddPaymentInfo Purchase Lead CompleteRegistration Subscribe StartTrial">
<label class="col-5 control-label">currency</label>
<div class="col-4">
<?php Events\renderCurrencyParamInput( $event, 'currency' ); ?>
</div>
<div class="col-2 facebook-custom-currency">
<?php Events\renderFacebookParamInput( $event, 'custom_currency' ); ?>
</div>
</div>
<div class="row mb-3 ViewContent AddToCart AddToWishlist InitiateCheckout Purchase Lead CompleteRegistration">
<label class="col-5 control-label">content_name</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'content_name' ); ?>
</div>
</div>
<div class="row mb-3 ViewContent AddToCart AddToWishlist InitiateCheckout Purchase Lead CompleteRegistration">
<label class="col-5 control-label">content_ids</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'content_ids' ); ?>
</div>
</div>
<div class="row mb-3 ViewContent AddToCart InitiateCheckout Purchase">
<label class="col-5 control-label">content_type</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'content_type' ); ?>
</div>
</div>
<div class="row mb-3 Search AddToWishlist InitiateCheckout AddPaymentInfo Lead">
<label class="col-5 control-label">content_category</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'content_category' ); ?>
</div>
</div>
<div class="row mb-3 InitiateCheckout Purchase">
<label class="col-5 control-label">num_items</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'num_items' ); ?>
</div>
</div>
<div class="row mb-3 Purchase">
<label class="col-5 control-label">order_id</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'order_id' ); ?>
</div>
</div>
<div class="row mb-3 Search">
<label class="col-5 control-label">search_string</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'search_string' ); ?>
</div>
</div>
<div class="row mb-3 CompleteRegistration">
<label class="col-5 control-label">status</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'status' ); ?>
</div>
</div>
<div class="row mb-3 Subscribe StartTrial">
<label class="col-5 control-label">predicted_ltv</label>
<div class="col-4">
<?php Events\renderFacebookParamInput( $event, 'predicted_ltv' ); ?>
</div>
</div>
<!-- Custom Facebook Params -->
<div class="row mt-3 facebook-custom-param" data-param_id="0" style="display: none;">
<div class="col-1"></div>
<div class="col-4">
<input name="" placeholder="Enter name" class="form-control custom-param-name" type="text">
</div>
<div class="col-4">
<input name="" placeholder="Enter value" class="form-control custom-param-value"
type="text">
</div>
<div class="col-2">
<button type="button" class="btn btn-sm remove-row">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
<?php foreach ( $event->getFacebookCustomParams() as $key => $custom_param ) : ?>
<?php $param_id = $key + 1; ?>
<div class="row mt-3 facebook-custom-param" data-param_id="<?php echo $param_id; ?>">
<div class="col">
<div class="row">
<div class="col-1"></div>
<div class="col-4">
<input type="text" placeholder="Enter name" class="form-control custom-param-name"
name="pys[event][facebook_custom_params][<?php echo $param_id; ?>][name]"
value="<?php esc_attr_e( $custom_param['name'] ); ?>">
</div>
<div class="col-4">
<input type="text" placeholder="Enter value" class="form-control custom-param-value"
name="pys[event][facebook_custom_params][<?php echo $param_id; ?>][value]"
value="<?php esc_attr_e( $custom_param['value'] ); ?>">
</div>
<div class="col-2">
<button type="button" class="btn btn-sm remove-row">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
<div class="insert-marker"></div>
<div class="row mt-3">
<div class="col-5"></div>
<div class="col-4">
<button class="btn btn-sm btn-block btn-primary add-facebook-parameter" type="button">Add
Custom Parameter</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php if ( GA()->enabled() ) : ?>
<div class="card card-static">
<div class="card-header">
Google Analytics
</div>
<div class="card-body">
<div class="row mb-2">
<div class="col">
<?php Events\renderSwitcherInput( $event, 'ga_enabled' ); ?>
<h4 class="switcher-label">Enable on Google Analytics</h4>
</div>
</div>
<div id="analytics_panel">
<div class="row mt-3">
<div class="col ">
<?php
if($event->isGaV4()) :
?>
<div class="row mb-3">
<div class="col col-offset-left form-inline" >
<script>
<?php
$fields = array();
foreach ($event->GAEvents as $group => $items) {
foreach ($items as $name => $elements) {
$fields[] = array("name"=>$name,'fields'=>$elements);
}
}
?>
var ga_fields = <?=json_encode($fields)?>
</script>
<label class=" control-label">Event</label>
<?php Events\renderGoogleAnalyticsV4ActionInput( $event, 'ga_event_action' ); ?>
<div id="ga-custom-action">
<?php Events\renderTextInput( $event, 'ga_custom_event_action', 'Enter name' ); ?>
</div>
</div>
</div>
<div class="ga-param-list">
<?php
foreach($event->getGaParams() as $key=>$val) : ?>
<div class="row mb-3 ga_param">
<label class="col-5 control-label"><?=$key?></label>
<div class="col-4">
<?php Events\renderGAParamInput( $key, $val ); ?>
</div>
</div>
<?php endforeach;?>
</div>
<div class="ga-custom-param-list">
<?php
foreach ( $event->getGACustomParams() as $key => $custom_param ) : ?>
<?php $param_id = $key + 1; ?>
<div class="row mt-3 ga-custom-param" data-param_id="<?php echo $param_id; ?>">
<div class="col">
<div class="row">
<div class="col-1"></div>
<div class="col-4">
<input type="text" placeholder="Enter name" class="form-control custom-param-name"
name="pys[event][ga_custom_params][<?php echo $param_id; ?>][name]"
value="<?php esc_attr_e( $custom_param['name'] ); ?>">
</div>
<div class="col-4">
<input type="text" placeholder="Enter value" class="form-control custom-param-value"
name="pys[event][ga_custom_params][<?php echo $param_id; ?>][value]"
value="<?php esc_attr_e( $custom_param['value'] ); ?>">
</div>
<div class="col-2">
<button type="button" class="btn btn-sm remove-row">
<i class="fa fa-trash-o" aria-hidden="true"></i>
</button>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<div class="row mt-3">
<div class="col-5"></div>
<div class="col-4">
<button class="btn btn-sm btn-block btn-primary add-ga-custom-parameter" type="button">Add
Custom Parameter</button>
</div>
</div>
<div class="row mb">
<label class="col-5 control-label">Non-interactive</label>
<div class="col-4">
<?php Events\renderSwitcherInput( $event, 'ga_non_interactive' ); ?>
</div>
</div>
<div class="row mt-3">
<div class="col-12">
The following parameters are automatically tracked: content_name, event_url, post_id, post_type. The paid version tracks the event_hour, event_month, and event_day.
</div>
</div>
<div class="row mt-3 ga_woo_info" style="display: none">
<div class="col-12">
<strong>ATTENTION</strong>: the plugin automatically tracks ecommerce specific events for WooCommerce and Easy Digital Downloads. Make sure you really need this event.
</div>
</div>
<?php else:?>
<div class="row mb-3">
<label class="col-5 control-label">Action</label>
<div class="col-4">
<?php Events\renderGoogleAnalyticsActionInput( $event, 'ga_event_action' ); ?>
</div>
<div class="col-3">
<div id="ga-custom-action">
<?php Events\renderTextInput( $event, 'ga_custom_event_action', 'Enter name' ); ?>
</div>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Category</label>
<div class="col-4">
<?php Events\renderTextInput( $event, 'ga_event_category' ); ?>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Label</label>
<div class="col-4">
<?php Events\renderTextInput( $event, 'ga_event_label' ); ?>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Value</label>
<div class="col-4">
<?php Events\renderTextInput( $event, 'ga_event_value' ); ?>
</div>
</div>
<div class="row mb">
<label class="col-5 control-label">Non-interactive</label>
<div class="col-4">
<?php Events\renderSwitcherInput( $event, 'ga_non_interactive' ); ?>
</div>
</div>
<?php endif?>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<div class="card card-disabled">
<div class="card-header">
Google Ads <?php renderProBadge('https://www.pixelyoursite.com/google-ads-tag/?utm_source=pys-free-plugin&utm_medium=pro-badge&utm_campaign=pro-feature'); ?><?php cardCollapseBtn(); ?>
</div>
<div class="card-body">
<div class="row mb-2">
<div class="col">
<?php renderDummySwitcher(); ?>
<h4 class="switcher-label">Enable on Google Ads</h4>
</div>
</div>
<div class="row mt-3">
<div class="col col-offset-left" id="google_ads_params_panel">
<div class="row mb-3">
<label class="col-5 control-label">Conversion ID</label>
<div class="col-4">
<?php renderDummySelectInput( 'All', true ); ?>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Conversion Label</label>
<div class="col-4">
<?php renderDummyTextInput( 'Enter name' ); ?>
<small class="form-text">Optional</small>
</div>
</div>
<!-- Default Params -->
<div class="row mb-3">
<label class="col-5 control-label">Action</label>
<div class="col-4">
<?php renderDummySelectInput( 'Custom Action', true ); ?>
</div>
<div class="col-3">
<div id="ga-custom-action">
<?php renderDummyTextInput( 'Enter name' ); ?>
</div>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Category</label>
<div class="col-4">
<?php renderDummyTextInput(); ?>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Label</label>
<div class="col-4">
<?php renderDummyTextInput(); ?>
</div>
</div>
<div class="row mb-3">
<label class="col-5 control-label">Value</label>
<div class="col-4">
<?php renderDummyTextInput(); ?>
</div>
</div>
<div class="row mt-3">
<div class="col-5"></div>
<div class="col-4">
<button class="btn btn-sm btn-block btn-secondary" type="button" disabled>Add Custom Parameter
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<?php if ( Pinterest()->enabled() ) : ?>
<?php Pinterest()->renderCustomEventOptions( $event ); ?>
<?php endif; ?>
<?php if ( Bing()->enabled() ) : ?>
<?php Bing()->renderCustomEventOptions( $event ); ?>
<?php endif; ?>
<div class="card card-static card-disabled">
<div class="card-header">
Dynamic Parameters Help <?php renderProBadge(); ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<ul class="text-secondary">
<li><code>[id]</code> - it will pull the WordPress post ID</li>
<li><code>[title]</code> - it will pull the content title</li>
<li><code>[content_type]</code> - it will pull the post type (post, product, page and so on)</li>
<li><code>[categories]</code> - it will pull the content categories</li>
<li><code>[tags]</code> - it will pull the content tags</li>
<li><code>[total]</code> - it will pull WooCommerce or EDD order's total when it exists</li>
<li><code>[subtotal]</code> - it will pull WooCommerce or EDD orders's subtotal when it exists</li>
</ul>
<p><strong class="text-secondary">Track URL parameters:</strong></p>
<p class="text-secondary"> Use <code>[url_ParameterName]</code> where ParameterName = the name of the parameter. <br/>
Example:<br/>
This is your URL: <?=$serverUrl?>?ParameterName=123<br/>
The parameter value will be 123.<br/>
</p>
<p class="text-secondary mb-0"><strong>Note:</strong> if a parameter is missing from a particular
page, the event won't include it.</p>
</div>
</div>
</div>
</div>
<hr>
<div class="row justify-content-center">
<div class="col-4">
<button class="btn btn-block btn-save">Save Event</button>
</div>
</div>

View File

@@ -0,0 +1,205 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$new_event_url = buildAdminUrl( 'pixelyoursite', 'events', 'edit' );
?>
<div class="panel">
<div class="row">
<div class="col">
<div class="d-flex justify-content-between">
<span class="mt-2">With the pro version, you can fire events on clicks, mouse over and page
scroll:</span>
<a target="_blank" class="btn btn-sm btn-primary float-right" href="https://www.pixelyoursite.com/facebook-pixel-plugin/buy-pixelyoursite-pro?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-upgrade-blue">UPGRADE</a>
</div>
</div>
</div>
</div>
<input type="hidden" name="pys[bulk_event_action_nonce]" value="<?php echo wp_create_nonce( 'bulk_event_action' ); ?>">
<h2 class="section-title">User Defined Events</h2>
<div class="card card-static">
<div class="card-header">
General
</div>
<div class="card-body">
<?php PYS()->render_switcher_input( 'custom_events_enabled' ); ?>
<h4 class="switcher-label">Enable Events</h4>
<div class="mt-3">
<a class="btn btn-sm btn-light btn-events-import">Import Events</a>
<a class="btn ml-3 btn-sm btn-light btn-events-export">Export Events</a>
<a class="ml-3 badge badge-pill badge-pro" href="https://www.pixelyoursite.com/?utm_source=pys-free-plugin&amp;utm_medium=pro-badge&amp;utm_campaign=pro-feature/?utm_source=pys-free-plugin&amp;utm_medium=pro-badge&amp;utm_campaign=pro-feature" target="_blank" >Pro Feature <i class="fa fa-external-link" aria-hidden="true"></i></a>
</div>
</div>
</div>
<div class="card card-static">
<div class="card-header">
Recommeded videos
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p><a href="https://www.youtube.com/watch?v=kEp5BDg7dP0" target="_blank">How to fire EVENTS with PixelYourSite (22:28) - watch now</a></p>
<p><a href="https://www.youtube.com/watch?v=PcXYYGOvahc" target="_blank">Track URL tags as event parameters (8:15) - watch now</a></p>
</div>
</div>
</div>
</div>
<div class="card card-static">
<div class="card-header">
About Parameters
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>All the events you configure here will automatically get the following parameters for all the tags:
<i>page_title, post_type, post_id, event_URL, user_role, plugin, landing_page (pro), event_time (pro), event_day (pro), event_month (pro), traffic_source (pro), UTMs (pro).</i></p>
<p>Exception: Google Analytics Universal will not get all these parameters. Only <i>event_time (pro), event_day (pro), event_month (pro), traffic_source (pro)</i> are sent as custom dimensions.</p>
<p>You can add other parameters when you configure the events.</p>
</div>
</div>
</div>
</div>
<div class="card card-static">
<div class="card-header">
Events List
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col">
<a href="<?php echo esc_url( $new_event_url ); ?>" class="btn btn-sm btn-primary mr-3">Add</a>
<button class="btn btn-sm btn-light" name="pys[bulk_event_action]" value="enable" type="submit">Enable</button>
<button class="btn btn-sm btn-light" name="pys[bulk_event_action]" value="disable" type="submit">Disable</button>
<button class="btn btn-sm btn-light" name="pys[bulk_event_action]" value="clone" type="submit">Duplicate</button>
<button class="btn btn-sm btn-danger ml-3" name="pys[bulk_event_action]" value="delete" type="submit">Delete</button>
</div>
</div>
<div class="row">
<div class="col">
<table class="table mb-0" id="table-custom-events">
<thead>
<tr>
<th style="width: 45px;">
<label class="custom-control custom-checkbox">
<input type="checkbox" id="pys_select_all_events" value="1" class="custom-control-input">
<span class="custom-control-indicator"></span>
</label>
</th>
<th>Name</th>
<th>Trigger</th>
<th>Networks</th>
</tr>
</thead>
<tbody>
<?php foreach ( CustomEventFactory::get() as $event ) : ?>
<?php
/** @var CustomEvent $event */
$event_edit_url = buildAdminUrl( 'pixelyoursite', 'events', 'edit', array(
'id' => $event->getPostId()
) );
$event_enable_url = buildAdminUrl( 'pixelyoursite', 'events', 'enable', array(
'pys' => array(
'event' => array(
'post_id' => $event->getPostId(),
)
),
'_wpnonce' => wp_create_nonce( 'pys_enable_event' ),
) );
$event_disable_url = buildAdminUrl( 'pixelyoursite', 'events', 'disable', array(
'pys' => array(
'event' => array(
'post_id' => $event->getPostId(),
)
),
'_wpnonce' => wp_create_nonce( 'pys_disable_event' ),
) );
$event_remove_url = buildAdminUrl( 'pixelyoursite', 'events', 'remove', array(
'pys' => array(
'event' => array(
'post_id' => $event->getPostId(),
)
),
'_wpnonce' => wp_create_nonce( 'pys_remove_event' ),
) );
?>
<tr data-post_id="<?php esc_attr_e( $event->getPostId() ); ?>"
class="<?php echo $event->isEnabled() ? '' : 'disabled'; ?>">
<td>
<label class="custom-control custom-checkbox">
<input type="checkbox" name="pys[selected_events][]"
value="<?php esc_attr_e( $event->getPostId() ); ?>"
class="custom-control-input pys-select-event">
<span class="custom-control-indicator"></span>
</label>
</td>
<td>
<a href="<?php echo esc_url( $event_edit_url ); ?>"><?php esc_html_e( $event->getTitle() ); ?></a>
<span class="event-actions">
<?php if ( $event->isEnabled() ) : ?>
<a href="<?php echo esc_url( $event_disable_url ); ?>">Disable</a>
<?php else : ?>
<a href="<?php echo esc_url( $event_enable_url ); ?>">Enable</a>
<?php endif; ?>
&nbsp;|&nbsp;
<a href="<?php echo esc_url( $event_remove_url ); ?>" class="
text-danger">Remove</a>
</span>
</td>
<td>Page Visit</td>
<td class="networks">
<?php if ( Facebook()->enabled() && $event->isFacebookEnabled() ) : ?>
<i class="fa fa-facebook-square"></i>
<?php else : ?>
<i class="fa fa-facebook-square" style="opacity: .25;"></i>
<?php endif; ?>
<?php if ( GA()->enabled() && $event->isGoogleAnalyticsEnabled() ) : ?>
<i class="fa fa-area-chart"></i>
<?php else : ?>
<i class="fa fa-area-chart" style="opacity: .25;"></i>
<?php endif; ?>
<i class="fa fa-google" style="opacity: .25;"></i>
<?php if ( Pinterest()->enabled() && $event->isPinterestEnabled() ) : ?>
<i class="fa fa-pinterest-square"></i>
<?php else : ?>
<i class="fa fa-pinterest-square" style="opacity: .25;"></i>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<hr>
<div class="row justify-content-center">
<div class="col-4">
<button class="btn btn-block btn-save">Save Settings</button>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,359 @@
<?php
namespace PixelYourSite;
use Cartflows_Helper;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<h2 class="section-title">CartFlows Settings</h2>
<!-- Enable CartFlows -->
<div class="card card-static">
<div class="card-header">
General
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>From here you can control the events and parameters fired by PixelYourSite Professional on CartFlos pages and actions.</p>
<p>To learn more <a href="https://www.pixelyoursite.com/cartflows-and-pixelyoursite" target="_blank">go to this dedicated page and watch the video</a></p>
<?php PYS()->render_switcher_input( "",false,true ); ?>
<h4 class="switcher-label">Enable CartFlows set-up</h4>
<?php renderProBadge(); ?>
</div>
</div>
</div>
</div>
<!-- Dedicated Tracking -->
<div class="card ">
<div class="card-header">
Dedicated Tracking IDs (optional) <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<?php if ( Facebook()->enabled() ) : ?>
<div class="plate">
<div class="row pt-3">
<div class="col">
<h4 class="mb-3">Meta Pixel (formerly Facebook Pixel)</h4>
<h4 class="label">Meta Pixel (formerly Facebook Pixel) ID:</h4>
<?php Facebook()->render_text_input( 'wcf_pixel_id', 'Add your pixel ID there',true ); ?>
</div>
</div>
<div class="row mt-3">
<div class="col">
<h4 class="label">Conversion API:</h4>
<?php Facebook()->render_text_area_input( 'wcf_server_access_api_token', 'Add your token there',true ); ?>
</div>
</div>
<div class="row mt-3">
<div class="col">
<h4 class="label">test_event_code:</h4>
<?php Facebook()->render_text_input( 'wcf_test_api_event_code', 'Add your test_event_code there',true ); ?>
</div>
</div>
<div class="row mt-3 pb-3">
<div class="col">
<h4 class="label">Verify your domain:</h4>
<?php Facebook()->render_text_input( 'wcf_verify_meta_tag', 'Add the verification meta-tag there' ,true); ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if ( GA()->enabled() ) : ?>
<hr>
<div class="plate">
<div class="row pt-3 mt-3 pb-3">
<div class="col">
<h4 class="mb-3">Google Analytics</h4>
<h4 class="label">Google Analytics ID:</h4>
<?php GA()->render_text_input( 'wcf_pixel_id', 'Add your ID there',true ); ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if ( Bing()->enabled() ) : ?>
<hr>
<div class="plate">
<div class="row pt-3 mt-3 pb-3">
<div class="col">
<h4 class="mb-3">Bing Tag</h4>
<h4 class="label">Bing Tag ID:</h4>
<?php Bing()->render_text_input( 'wcf_pixel_id', 'Add your ID there',true ); ?>
</div>
</div>
</div>
<?php endif; ?>
<?php if ( Pinterest()->enabled() ) : ?>
<hr>
<div class="plate">
<div class="row pt-3 mt-3">
<div class="col">
<h4 class="mb-3">Pinterest Pixel</h4>
<h4 class="label">Pinterest Pixel ID:</h4>
<?php Pinterest()->render_text_input( 'wcf_pixel_id', 'Add your ID there',true ); ?>
</div>
</div>
<div class="row mt-3 pb-3">
<div class="col">
<h4 class="label">Verify your domain:</h4>
<?php Pinterest()->render_text_input( 'wcf_verify_meta_tag', 'Add the verification meta-tag there',true ); ?>
</div>
</div>
</div>
<?php endif; ?>
</div>
</div>
<h2 class="section-title">Standard Events Settings</h2>
<!-- Purchase -->
<div class="card ">
<div class="card-header">
Purchase settings <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>You have additional options for this event on the plugins WooCommerce page</p>
<div class="custom-controls-stacked mb-3">
<?php PYS()->render_radio_input( 'wcf_purchase_on', 'all', 'Fire a Purchase event for each Upsale and Downsale step',true ); ?>
<?php PYS()->render_radio_input( 'wcf_purchase_on', 'last', 'Fire a single Purchase event for all Upsale or Downsale steps. <strong>Caution</strong>: if the client abandons a step, we wont\'t track the transaction ' ,true ); ?>
</div>
<?php PYS()->render_switcher_input( 'wcf_purchase_on_optin_enabled',false,true ); ?>
<h4 class="switcher-label">Fire the event Optin offers</h4>
</div>
</div>
</div>
</div>
<!-- AddToCart -->
<div class="card ">
<div class="card-header">
AddToCart settings <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>You have additional options for this event on the plugins WooCommerce page</p>
<?php PYS()->render_switcher_input( 'wcf_add_to_cart_on_bump_click_enabled',false,true ); ?>
<h4 class="switcher-label">Fire the event for order bumps</h4>
</div>
</div>
</div>
</div>
<!-- Lead -->
<div class="card ">
<div class="card-header has_switch">
<?php PYS()->render_switcher_input( 'wcf_lead_enabled',false,true ); ?> Lead <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
Fire a Lead event when a Optin offer is accepted
</div>
</div>
</div>
</div>
<!-- ViewContent -->
<div class="card ">
<div class="card-header">
ViewContent settings <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<p>You have additional options for this event on the plugins WooCommerce page</p>
<p>The event is always fired on page</p>
<?php PYS()->render_switcher_input( 'wcf_sell_step_view_content_enabled' ,false,true ); ?>
<h4 class="switcher-label">Fire the event on Upsale and Downsale steps</h4>
</div>
</div>
</div>
</div>
<h2 class="section-title">Custom Events</h2>
<!-- CartFlows -->
<div class="card ">
<div class="card-header has_switch">
<?php PYS()->render_switcher_input( 'wcf_cart_flows_event_enabled',false,true ); ?> CartFlows Event <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<?php if ( Facebook()->enabled() ) : ?>
<div class="row">
<div class="col">
<p>Fire this event for all CartFlows pages.</p>
<?php Facebook()->render_switcher_input( 'wcf_cart_flows_event_enabled',false,true ); ?>
<h4 class="switcher-label">Facebook</h4>
</div>
</div>
<?php endif; ?>
<?php if ( GA()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php GA()->render_switcher_input( 'wcf_cart_flows_event_enabled',false,true ); ?>
<h4 class="switcher-label">Google Analytics</h4>
</div>
</div>
<?php endif; ?>
<?php if ( Pinterest()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php Pinterest()->render_switcher_input( 'wcf_cart_flows_event_enabled',false,true ); ?>
<h4 class="switcher-label">Pinterest</h4>
</div>
</div>
<?php endif; ?>
<?php if ( Bing()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php Bing()->render_switcher_input( 'wcf_cart_flows_event_enabled',false,true ); ?>
<h4 class="switcher-label">Bing</h4>
</div>
</div>
<?php endif; ?>
</div>
</div>
<!-- step event -->
<div class="card ">
<div class="card-header has_switch">
<?php PYS()->render_switcher_input( 'wcf_step_event_enabled',false,true ); ?> Track Steps <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<?php if ( Facebook()->enabled() ) : ?>
<div class="row">
<div class="col">
<p>Fire CartFlows_Landing, CartFlows_Upsale, CartFlows_Downsale, CartFlows_Checkout, CartFlows_ThankYou,CartFlows_Optin</p>
<?php Facebook()->render_switcher_input( 'wcf_step_event_enabled',false,true ); ?>
<h4 class="switcher-label">Facebook</h4>
</div>
</div>
<?php endif; ?>
<?php if ( GA()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php GA()->render_switcher_input( 'wcf_step_event_enabled',false,true ); ?>
<h4 class="switcher-label">Google Analytics</h4>
</div>
</div>
<?php endif; ?>
<?php if ( Pinterest()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php Pinterest()->render_switcher_input( 'wcf_step_event_enabled',false,true ); ?>
<h4 class="switcher-label">Pinterest</h4>
</div>
</div>
<?php endif; ?>
<?php if ( Bing()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php Bing()->render_switcher_input( 'wcf_step_event_enabled',false,true ); ?>
<h4 class="switcher-label">Bing</h4>
</div>
</div>
<?php endif; ?>
</div>
</div>
<!-- step event -->
<div class="card ">
<div class="card-header has_switch">
<?php PYS()->render_switcher_input( 'wcf_bump_event_enabled',false,true ); ?> Track Order Bumps <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<?php if ( Facebook()->enabled() ) : ?>
<div class="row">
<div class="col">
<p>Fire CartFlows_order_bump, when an order bump is accepted</p>
<?php Facebook()->render_switcher_input( 'wcf_bump_event_enabled',false,true ); ?>
<h4 class="switcher-label">Facebook</h4>
</div>
</div>
<?php endif; ?>
<?php if ( GA()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php GA()->render_switcher_input( 'wcf_bump_event_enabled',false,true ); ?>
<h4 class="switcher-label">Google Analytics</h4>
</div>
</div>
<?php endif; ?>
<?php if ( Pinterest()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php Pinterest()->render_switcher_input( 'wcf_bump_event_enabled',false,true ); ?>
<h4 class="switcher-label">Pinterest</h4>
</div>
</div>
<?php endif; ?>
<?php if ( Bing()->enabled() ) : ?>
<div class="row">
<div class="col">
<?php Bing()->render_switcher_input( 'wcf_bump_event_enabled',false,true ); ?>
<h4 class="switcher-label">Bing</h4>
</div>
</div>
<?php endif; ?>
</div>
</div>
<h2 class="section-title">CartFlows Events Parameters</h2>
<div class="card ">
<div class="card-header">
Control the CartFlows Parameters <?php renderProBadge(); cardCollapseBtn(); ?>
</div>
<div class="card-body">
<div class="row">
<div class="col">
<?php PYS()->render_switcher_input( 'wcf_global_cartflows_parameter_enabled',false,true ); ?>
<h4 class="switcher-label">CartFlows</h4>
</div>
</div>
<div class="row">
<div class="col">
<?php PYS()->render_switcher_input( 'wcf_global_cartflows_flow_parameter_enabled',false,true ); ?>
<h4 class="switcher-label">CartFlows_flow</h4>
</div>
</div>
<div class="row">
<div class="col">
<?php PYS()->render_switcher_input( 'wcf_global_cartflows_step_parameter_enabled',false,true ); ?>
<h4 class="switcher-label">CartFlows_step</h4>
</div>
</div>
</div>
</div>
<div class="row justify-content-center">
<div class="col-4">
<button class="btn btn-block btn-sm btn-save">Save Settings</button>
</div>
</div>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,579 @@
<!-- GENERAL -->
<div id="pys-general_event" style="display: none; visibility: hidden">
<p>The GeneralEvent will track the following parameters:</p>
<ul>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>domain</li>
<li>user's role</li>
<li>domain</li>
<li>plugin's name</li>
<li>
<del>traffic_source</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>UTMs</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>Visitor's browser's time (hour, day, month)</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
</ul>
<p>Use it to create Custom Audiences, Custom Conversions, or for Facebook Analytics.</p>
</div>
<div id="pys-search_event" style="display: none; visibility: hidden">
<p>On Facebook and Pinterest, the event will send these parameters:</p>
<ul>
<li>search_string: the exact searched word or phrase</li>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>domain</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
<li>
<del>traffic_source</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>UTMs</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>Visitor's browser's time (hour, day, month)</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
</ul>
<p>On Google Analytics, the event will have the following structure:</p>
<ul>
<li>Event Category: WordPress Search or WooCommerce Search</li>
<li>Event Action: search</li>
<li>Event Label: the search string</li>
</ul>
</div>
<div id="pys-click_event" style="display: none; visibility: hidden">
<p>The ClickEvent will have the following parameters on Facebook and Pinterest:</p>
<ul>
<li>tag_text: the links text</li>
<li>tag_type: a (for HTML links) or button</li>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>domain</li>
<li>traffic_source</li>
<li>UTMs</li>
<li>Visitor's browser's time (hour, day, month)</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
</ul>
<p>Use it to create specific Custom Audiences or Custom Conversions.</p>
<p>On Google Analytics the event will have the following structure:</p>
<ul>
<li>Event Category: ClickEvent</li>
<li>Event Action: the URL link</li>
<li>Event Label: the link or button text</li>
</ul>
</div>
<div id="pys-watch_video_event" style="display: none; visibility: hidden">
<p>The event will have 5 separate triggers:</p>
<ul>
<li>play - when the video starts</li>
<li>10%</li>
<li>50%</li>
<li>90%</li>
<li>100%</li>
</ul>
<p>On Facebook and Pinterest it will have the following parameters:</p>
<ul>
<li>event_trigger: it can be play, 10%, 50%, 90% or 100%</li>
<li>video_title</li>
<li>video_id</li>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>traffic_source</li>
<li>UTMs</li>
<li>Visitor's browser's time (hour, day, month)</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
</ul>
<p>On Google Analytics it will have:</p>
<ul>
<li>Event Category: WatchVideo</li>
<li>Event Action: play, 10%, 50%, 90%, 100%</li>
<li>Event Label: the video title</li>
</ul>
</div>
<div id="pys-complete_registration_event" style="display: none; visibility: hidden">
<p>On Facebook and Pinterest the event will have the following parameters:</p>
<ul>
<li>traffic_source</li>
<li>UTMs</li>
<li>Visitor's browser's time (hour, day, month)</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
</ul>
<p>On Google Analytics it will have this structure:</p>
<ul>
<li>Event Category: engagement</li>
<li>Event Action: sign_up</li>
<li>Event Label: user's role</li>
</ul>
</div>
<div id="pys-form_event" style="display: none; visibility: hidden">
<p>This event will have the following parameters on Facebook and Pinterest:</p>
<ul>
<li>form_class: the CSS class identifying the form</li>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>traffic_source</li>
<li>UTMs</li>
<li>Visitor's browser's time (hour, day, month)</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
</ul>
<p>On Google Analytics it will have the following structure:</p>
<ul>
<li>Event Category: Form</li>
<li>Event Action: the form page URL</li>
<li>Event Label: the CSS class identifying the form</li>
</ul>
</div>
<div id="pys-comment_event" style="display: none; visibility: hidden">
<p>On Facebook and Pinterest, the event will have the following parameters:</p>
<ul>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
<li>
<del>traffic_source</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>UTMs</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>Visitor's browser's time (hour, day, month)</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
</ul>
<p>On Google Analytics, the event will have this structure:</p>
<ul>
<li>Event Category: Comment</li>
<li>Event Action: the URL where the comment was posted</li>
<li>Event Label: the page title</li>
</ul>
</div>
<div id="pys-download_docs_event" style="display: none; visibility: hidden">
<p>This event will have the following parameters on Facebook and Pinterest:</p>
<ul>
<li>download_name: the name of the downloaded file</li>
<li>download_type: the file format (jpg, png, zip, and so on)</li>
<li>download_url: the exact URL of the downloaded file</li>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
<li>
<del>traffic_source</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>UTMs</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
<li>
<del>Visitor's browser's time (hour, day, month)</del>
(<a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro</a>)
</li>
</ul>
<p>On Google Analytics it will have the next structure:</p>
<ul>
<li>Event Category: Download</li>
<li>Event Action: the downloaded file URL</li>
<li>Event Label: the downloaded file name</li>
</ul>
</div>
<div id="pys-adsense_event" style="display: none; visibility: hidden">
<p>This event will have the following parameters on Facebook and Pinterest:</p>
<ul>
<li>content_name</li>
<li>content_category</li>
<li>tag</li>
<li>post_type</li>
<li>post_id</li>
<li>traffic_source</li>
<li>UTMs</li>
<li>Visitor's browser's time (hour, day, month)</li>
<li>user's role</li>
<li>domain name</li>
<li>plugin's name</li>
</ul>
</div>
<!-- WOOCOMMERCE -->
<div id="pys-woo_facebook_am_params" style="display: none; visibility: hidden">
<p>All the e-commerce events are Dynamic Product Ads ready, having the two required parameters:</p>
<ul>
<li>content_type: product or product group</li>
<li>content_ids</li>
</ul>
<p>The following events are used for Dynamic Product Ads:</p>
<ul>
<li>ViewContent: on single product pages</li>
<li>ViewCategory: on WooCommerce category pages</li>
<li>AddToCart: when a product is added to cart</li>
<li>Purchase: when a transaction is completed</li>
</ul>
<p><strong>IMPORTANT:</strong> in order to run Dynamic Product ads you need a Product Catalog. You can create one
using our <a href="https://www.pixelyoursite.com/product-catalog-facebook?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup" target="_blank">dedicated
Product Catalog Feed plugin</a>.</p>
</div>
<div id="pys-woo_facebook_and_pinterest_params" style="display: none; visibility: hidden">
<p>Your WooCommerce events track a large number of parameters that you can use for Custom Audiences, Custom
Conversions, or inside Facebook Analytics.</p>
<ul>
<li>content_name: the name of the products</li>
<li>category_name: the product categories</li>
<li>tags: the product tags</li>
<li>num_items: the number of products in the cart</li>
<li>value: the event value</li>
<li>currency: your store currency</li>
<li>product_price: the price of the product</li>
<li>user_role: the type of user firing the event</li>
<li>domain: the domain name</li>
</ul>
</div>
<div id="pys-woo_facebook_and_pinterest_pro_params" style="display: none; visibility: hidden">
<p>The PRO version will track even more parameters, helping you to create even more Custom Conversions or Audiences.
The browser's time-related parameters will help you understand when your clients convert (their time).</p>
<ul>
<li>traffic_source</li>
<li>UTMs: the UTMs of the landing URL</li>
<li>month: the transaction's month, based on the visitor's browser's time</li>
<li>day: the transaction's day, based on the visitor's browser's time</li>
<li>hour: the hour interval, based on the visitor's browser's time</li>
</ul>
</div>
<div id="pys-woo_facebook_and_pinterest_purchase_params" style="display: none; visibility: hidden">
<p>Your Purchase event tracks important parameters. They can be used for Custom Audiences or Conversions.</p>
<ul>
<li>content_type: product</li>
<li>content_ids: the ids of the purchased events</li>
<li>value: the event value, as configured inside the plugin</li>
<li>currency: transaction's currency</li>
<li>transactions_count: the number of transactions made by the same client</li>
<li>content_name: the product's numbers</li>
<li>category_name: the products categories</li>
<li>num_items: the number of products</li>
<li>plugin: PixelYourSite</li>
<li>domain: your domain name</li>
<li>user_roles: the client user role</li>
<li>contents: A list of JSON object that contains the product IDs associated with the event as well as
additional information about the products
</li>
</ul>
</div>
<div id="pys-woo_facebook_and_pinterest_purchase_pro_params" style="display: none; visibility: hidden">
<p>The <a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">PRO version</a> Purchase event will track an extraordinary number of
extra useful parameters. Use them for your super-focus Custom Audiences or Custom Conversions, and for Facebook
Analytics reports.</p>
<ul>
<li>total: the transaction's total</li>
<li>lifetime_value: the client lifetime's value</li>
<li>average_order: the average order of the transactions made by the same client</li>
<li>payment: payment type</li>
<li>tax: the tax value</li>
<li>shipping: shipping option</li>
<li>shipping_cost: the shipping cost</li>
<li>coupon_used: use of coupons (yes/no)</li>
<li>coupon_name: the name of the coupon used</li>
<li>content_name: the product's numbers</li>
<li>order_id: the order's id</li>
<li>hour: the transaction's hour interval, based on the client's browser's time</li>
<li>day: the transaction's day, based on the client's browser's time</li>
<li>month: the transaction's month, based on the client's browser's time</li>
<li>traffic_source: direct</li>
<li>UTMs: the UMTs of the landing URL</li>
</ul>
</div>
<div id="pys-woo_ga_enhanced_ecommerce_params" style="display: none; visibility: hidden">
<p>In-depth e-commerce data will be sent to Google Analytics, like transaction value, tax, shipping, products, and
product categories. Product views, add to cart, remove from cart, checkout, and purchases are tracked
automatically and you can analyze and compare the stats inside Google Analytics E-commerce reports.</p>
</div>
<div id="pys-woo_google_ads_enhanced_ecommerce_params" style="display: none; visibility: hidden">
<p>The <a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro version</a> implements the Google Ads tag (former AdWords). All
the e-commerce events will be sent to Google Ads. These events can be used for audiences. You can also configure
"conversions" to track your transactions. The e-commerce events will be Dynamic Remarketing ready. You can
select between the "Retail" or "Custom" vertical, according to your needs.</p>
</div>
<div id="pys-woo_purchase_on_transaction" style="display: none; visibility: hidden">
<p>This will make sure that simple page refreshes or reloads won't affect your stats. Disable this option if you
plan to test the event.</p>
</div>
<div id="pys-woo_purchase_event_value" style="display: none; visibility: hidden">
<p><strong>Value is mandatory for this event.</strong></p>
<p>Your Purchase event value for your business might not be the exact value of the products or services, because you
have all sorts of costs included. You can use the order total, a percent of the total, or a fixed value.</p>
<p>We also added a "total" parameter for this event that will always reflect the full value of each purchase.</p>
<p>Note: Some experts think that Facebook will better optimize your ads when conversion value is smaller, making
sure that you don't overspend. It's a controversial theory, but one you can test yourself.</p>
</div>
<div id="pys-woo_initiate_checkout_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<div id="pys-woo_add_to_cart_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<div id="pys-woo_view_content_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<div id="pys-woo_affiliate_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<div id="pys-woo_paypal_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<!-- EDD -->
<div id="pys-edd_facebook_am_params" style="display: none; visibility: hidden">
<p>All the e-commerce events are Dynamic Product Ads ready, having the two required parameters:</p>
<ul>
<li>content_type: product or product group</li>
<li>content_ids</li>
</ul>
<p>The following events are used for Dynamic Product Ads:</p>
<ul>
<li>ViewContent: on single product pages</li>
<li>ViewCategory: on WooCommerce category pages</li>
<li>AddToCart: when a product is added to cart</li>
<li>Purchase: when a transaction is completed</li>
</ul>
<p><strong>IMPORTANT:</strong> in order to run Dynamic Product ads you need a Product Catalog. You can create one
using our <a href="https://www.pixelyoursite.com/easy-digital-downloads-product-catalog?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup"
target="_blank">dedicated
Product Catalog Feed plugin</a>.</p>
</div>
<div id="pys-edd_facebook_and_pinterest_params" style="display: none; visibility: hidden">
<p>Your Easy Digital Downloads events track a large number of parameters that you can use for Custom Audiences, Custom
Conversions, or inside Facebook Analytics.</p>
<ul>
<li>content_name: the name of the products</li>
<li>category_name: the product categories</li>
<li>tags: the product tags</li>
<li>num_items: the number of products in the cart</li>
<li>value: the event value</li>
<li>currency: your store currency</li>
<li>product_price: the price of the product</li>
<li>user_role: the type of user firing the event</li>
<li>domain: the domain name</li>
</ul>
</div>
<div id="pys-edd_facebook_and_pinterest_pro_params" style="display: none; visibility: hidden">
<p>The PRO version will track even more parameters, helping you to create even more Custom Conversions or Audiences.
The browser's time-related parameters will help you understand when your clients convert (their time).</p>
<ul>
<li>traffic_source</li>
<li>UTMs: the UTMs of the landing URL</li>
<li>month: the transaction's month, based on the visitor's browser's time</li>
<li>day: the transaction's day, based on the visitor's browser's time</li>
<li>hour: the hour interval, based on the visitor's browser's time</li>
</ul>
</div>
<div id="pys-edd_facebook_and_pinterest_purchase_params" style="display: none; visibility: hidden">
<p>Your Purchase event tracks important parameters. They can be used for Custom Audiences or Conversions.</p>
<ul>
<li>content_type: product</li>
<li>content_ids: the ids of the purchased events</li>
<li>value: the event value, as configured inside the plugin</li>
<li>currency: transaction's currency</li>
<li>content_name: the product's numbers</li>
<li>category_name: the products categories</li>
<li>num_items: the number of products</li>
<li>plugin: PixelYourSite</li>
<li>domain: your domain name</li>
<li>user_roles: the client user role</li>
<li>contents: A list of JSON object that contains the product IDs associated with the event as well as
additional information about the products
</li>
</ul>
</div>
<div id="pys-edd_facebook_and_pinterest_purchase_pro_params" style="display: none; visibility: hidden">
<p>The <a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">PRO version</a> Purchase event will track an extraordinary number of
extra useful parameters. Use them for your super-focus Custom Audiences or Custom Conversions, and for Facebook
Analytics reports.</p>
<ul>
<li>total: the transaction's total</li>
<li>lifetime_value: the client lifetime's value</li>
<li>average_order: the average order of the transactions made by the same client</li>
<li>payment: payment type</li>
<li>tax: the tax value</li>
<li>shipping: shipping option</li>
<li>shipping_cost: the shipping cost</li>
<li>coupon_used: use of coupons (yes/no)</li>
<li>coupon_name: the name of the coupon used</li>
<li>content_name: the product's numbers</li>
<li>transaction_id: the order's id</li>
<li>hour: the transaction's hour interval, based on the client's browser's time</li>
<li>day: the transaction's day, based on the client's browser's time</li>
<li>month: the transaction's month, based on the client's browser's time</li>
<li>traffic_source: direct</li>
<li>UTMs: the UMTs of the landing URL</li>
</ul>
</div>
<div id="pys-edd_ga_enhanced_ecommerce_params" style="display: none; visibility: hidden">
<p>In-depth e-commerce data will be sent to Google Analytics, like transaction value, tax, shipping, products, and
product categories. Product views, add to cart, remove from cart, checkout, and purchases are tracked
automatically and you can analyze and compare the stats inside Google Analytics E-commerce reports.</p>
</div>
<div id="pys-edd_google_ads_enhanced_ecommerce_params" style="display: none; visibility: hidden">
<p>The <a href="https://www.pixelyoursite.com/?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-info-popup">pro version</a> implements the Google Ads tag (former AdWords). All
the e-commerce events will be sent to Google Ads. These events can be used for audiences. You can also configure
"conversions" to track your transactions. The e-commerce events will be Dynamic Remarketing ready. You can
select between the "Retail" or "Custom" vertical, according to your needs.</p>
</div>
<!-- @fixme: update texts -->
<div id="pys-edd_google_ads_enhanced_ecommerce_params" style="display: none; visibility: hidden">
<p>In-depth e-commerce data will be sent to Google Ads, like transaction value, tax, shipping, products, and
product categories. Product views, add to cart, remove from cart, checkout, and purchases are tracked
automatically and you can analyze and compare the stats inside Google Ads E-commerce reports.</p>
</div>
<div id="pys-edd_purchase_on_transaction" style="display: none; visibility: hidden">
<p>This will make sure that simple page refreshes or reloads won't affect your stats. Disable this option if you
plan to test the event.</p>
</div>
<div id="pys-edd_purchase_event_value" style="display: none; visibility: hidden">
<p><strong>Value is mandatory for this event.</strong></p>
<p>Your Purchase event value for your business might not be the exact value of the products or services, because you
have all sorts of costs included. You can use the order total, a percent of the total, or a fixed value.</p>
<p>We also added a "total" parameter for this event that will always reflect the full value of each purchase.</p>
<p>Note: Some experts think that Facebook will better optimize your ads when conversion value is smaller, making
sure that you don't overspend. It's a controversial theory, but one you can test yourself.</p>
</div>
<div id="pys-edd_initiate_checkout_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<div id="pys-edd_add_to_cart_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<div id="pys-edd_view_content_event_value" style="display: none; visibility: hidden">
<p>Value is not mandatory for this event. If you want, you can enable and configure it to reflect the value this
event has for your business.</p>
</div>
<!-- COMMON -->
<div id="pys-google_dynamic_remarketing_vertical" style="display: none; visibility: hidden">
<p>All the e-commerce events will have the required parameters for Google Ads Dynamic Remarketing.</p>
<p><strong>If you have access to Google Merchant</strong>, select the Retail vertical. In this case, the
following parameters will be added:</p>
<ul>
<li>ecomm_prodid</li>
<li>ecomm_pagetype</li>
<li>ecomm_totalvalue</li>
</ul>
<p>Dynamic Remarketing will be done through Google Merchant.</p>
<p><strong>If you don't have access to Google Merchant</strong>, select the Custom vertical. In this case,
the following parameters will be added:</p>
<ul>
<li>dynx_itemid</li>
<li>dynx_pagetype</li>
<li>dynx_totalvalue</li>
</ul>
<p>Dynamic Remarketing will be done using a Custom feed.</p>
</div>
<div id="pys-ads_woo_item_id_prefix" style="display: none; visibility: hidden">
<p>You can use this option to match the product ID that Google Ads Tag will use for the Dynamic Remarketing
parameters. The ID should be identical to the one used by your Google Merchant or Custom feed.</p>
</div>
<div id="pys-google_ads_conversion_label" style="display: none; visibility: hidden">
<p>Transform this event into a Google Ads conversion:</p>
<p>Create a conversion inside your Google Ads account, copy its label and paste it here.</p>
<p>If you have more than one Google Tags installed, select the same one where the conversion was created.</p>
<p><a href="https://www.pixelyoursite.com/documentation/track-google-ads-conversion-on-woocommerce"
target="_blank">Click here for details</a></p>
</div>
<div id="pys-ga_cross_domain_tracking" style="display: none; visibility: hidden">
<p>Cross-domain measurement makes it possible for Analytics to see sessions on two related sites (such as an
ecommerce site and a separate shopping cart site) as a single session.</p>
<p><a href="https://www.pixelyoursite.com/pixelyoursite-free-version/google-analytics-cross-domain-tracking"
target="_blank">Click here for help</a></p>
</div>

View File

@@ -0,0 +1,34 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<div class="wrap" id="pys">
<h1><?php _e( 'PixelYourSite', 'pys' ); ?></h1>
<div class="pys_stat">
<div class="row">
<div class="col">
<h2 class="section-title">EDD Reports <?php renderProBadge(); ?></h2>
</div>
</div>
<div class="container">
<div class="row" style="padding:40px">
<div class="col text-center">
<p >With PixelYourSite Professional you can find out what ads generate your Easy Digital Downloads orders using UTMs, discover your traffic sources and landing pages.
</p>
<h3 class="text-center" style="margin-top:40px">Get detailed info about products sold by each campaign, ad set, or ad</h3>
<a href="https://www.pixelyoursite.com/easy-digital-downloads-first-party-reports/?utm_source=free-plugin-reports-page-edd&utm_medium=free-plugin-reports-page-edd&utm_campaign=free-plugin-reports-edd&utm_content=free-plugin-reports-page-edd&utm_term=free-plugin-reports-page-edd"
target="_blank" class="btn btn-save" style="margin-top:30px">Click to find more</a>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,34 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<div class="wrap" id="pys">
<h1><?php _e( 'PixelYourSite', 'pys' ); ?></h1>
<div class="pys_stat">
<div class="row">
<div class="col">
<h2 class="section-title">WooCommerce Reports <?php renderProBadge(); ?></h2>
</div>
</div>
<div class="container">
<div class="row" style="padding:40px">
<div class="col text-center">
<p >Find out what ads generate your WooCommerce orders using UTMs, discover your traffic sources and landing pages.
Visualize your data inside the plugin, or download it as CSV. </p>
<h3 class="text-center" style="margin-top:40px">Get detailed info about products sold by each campaign, ad set, or ad</h3>
<a href="https://www.pixelyoursite.com/woocommerce-first-party-reports?utm_source=free-plugin-reports-page-woo&utm_medium=free-plugin-reports-page-woo&utm_campaign=free-plugin-reports-page-woo&utm_content=free-plugin-reports-page-woo&utm_term=free-plugin-reports-page-woo"
target="_blank" class="btn btn-save" style="margin-top:30px">Click to find more</a>
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,59 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<div class="wrap" id="pys">
<h1><?php _e( 'PixelYourSite', 'pys' ); ?></h1>
<div class="container">
<div class="row">
<div class="col">
<h2 class="section-title">System Report</h2>
<?php foreach ( get_system_report_data() as $section_name => $section_report ) : ?>
<div class="card card-static">
<div class="card-header">
<?php esc_html_e( $section_name ); ?>
</div>
<div class="card-body">
<table class="table system-report">
<tbody>
<?php foreach ( $section_report as $name => $value ) : ?>
<tr>
<td style="width: 50%;"><?php echo $name; ?></td>
<td style="width: 50%;"><?php echo $value; ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<hr>
<div class="row justify-content-center">
<div class="col-4">
<form method="post">
<?php wp_nonce_field( 'pys_download_system_report_nonce' ); ?>
<input type="hidden" name="pys_action" value="download_system_report"/>
<button type="submit" class="btn btn-block btn-sm btn-primary">Download System Report</button>
</form>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,25 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
?>
<div class="card card-static border-danger">
<div class="card-header bg-danger text-white">
Reset All Settings To Defaults
</div>
<div class="card-body">
<p><strong>If you continue, all your custom settings will be lost and the plugin will go back to the default
configuration.</strong> If you use any add-ons, like the Pinterest add-on or the Super Pack, their
settings will be affected too. Custom events and scripts added with the Head & Footer option won't be
affected.</p>
<button type="submit" name="pys[reset_settings]" value="1"
class="btn btn-sm btn-danger">Yes, reset settings</button>
<a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite' ) ); ?>"
class="btn btn-sm btn-light ml-3">No, go back</a>
</div>
</div>

View File

@@ -0,0 +1,87 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
$utms = [
"utm_source",
"utm_medium",
"utm_campaign",
"utm_content",
"utm_term",
];
?>
<div class="wrap" id="pys">
<h1><?php _e( 'UTM Templates', 'pys' ); ?></h1>
<div class="pys_utm_templates container">
<div class="row">
<div class="col">
<div class="mb-2" >Meta (Facebook) - <a target="_blank" href="https://www.youtube.com/watch?v=aAJcjurzp-Q">watch video:</a></div>
<div class="utm_template mt-2 copy_text">utm_source=facebook&utm_medium=paid&utm_campaign={{campaign.name}}&utm_term={{adset.name}}&utm_content={{ad.name}}&fbadid={{ad.id}}</div>
</div>
</div>
<div class="row mt-4">
<div class="col">
<div class="mb-2" >Google Ads - <a target="_blank" href="https://www.youtube.com/watch?v=j1TlbKYNZk4">watch video:</a></div>
<div class="utm_template mt-2 copy_text">{lpurl}?utm_source=google&utm_medium=paid&utm_campaign={campaignid}&utm_content={adgroupid}&utm_term={keyword}&gadid={creative}</div>
</div>
</div>
<div class="row mt-4">
<div class="col">
<div class="mb-2" >TikTok - <a target="_blank" href="https://www.youtube.com/watch?v=bB2OVtlpQ5g">watch video:</a></div>
<div class="utm_template mt-2 copy_text">?utm_source=tiktok&utm_medium=paid&utm_campaign=__CAMPAIGN_NAME__&utm_term=__AID_NAME__&utm_content=__CID_NAME__&ttadid=__CID__</div>
</div>
</div>
<div class="row mt-4">
<div class="col">
<div class="mb-2" >Pinterest - <a target="_blank" href="https://www.youtube.com/watch?v=MKdS0PiND7M">watch video:</a></div>
<div class="utm_template mt-2 copy_text">?utm_source=pinterest&utm_medium=paid&utm_campaign={campaign_name}&utm_term={adgroup_name}&utm_content={creative_id}&padid={adid}</div>
</div>
</div>
<div class="row mt-4">
<div class="col">
<div class="mb-2" >Bing - <a target="_blank" href="https://www.youtube.com/watch?v=lC6c-Pt5fxM">watch video:</a></div>
<div class="utm_template mt-2 copy_text">{lpurl}?utm_source=bing&utm_medium=paid&utm_campaign={campaign}&utm_content={AdGroupId}&utm_term={AdGroup}&bingid={CampaignId}</div>
</div>
</div>
</div>
<h1><?php _e( 'UTM Builder', 'pys' ); ?></h1>
<div class="pys_utm_builder container">
<div class="bg-gray">
<h4 class="label">Your URL:</h4>
<input type="text" class="site_url form-control mt-2" value="<?=get_site_url();?>"/>
</div>
<?php
foreach ($utms as $utm) : ?>
<div >
<h4 class="label"><?=$utm?>:</h4>
<input type="text" class="utm form-control mt-2 <?=$utm?>" value="" data-type="<?=$utm?>"/>
</div>
<?php endforeach; ?>
<div class="">
<h4 class="label">URL with UTMs:</h4>
<div class="copy_text build_utms_with_url mt-2 bg-gray" ></div>
</div>
<div class="">
<h4 class="label">UTMs:</h4>
<div class="copy_text build_utms mt-2 bg-gray" ></div>
</div>
</div>
</div>

View File

@@ -0,0 +1,261 @@
<?php
namespace PixelYourSite;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/** @var PYS $this */
include "html-popovers.php";
?>
<div class="wrap">
<h1><?php _e( 'PixelYourSite', 'pys' ); ?></h1>
<div id="pys">
<div class="container">
<form method="post" enctype="multipart/form-data">
<?php wp_nonce_field( 'pys_save_settings' ); ?>
<div class="row mb-3">
<div class="col">
<nav class="nav nav-tabs">
<?php foreach ( getAdminPrimaryNavTabs() as $tab_key => $tab_data ) : ?>
<?php
$classes = array(
'nav-item',
'nav-link',
);
if ( $tab_key == getCurrentAdminTab() ) {
$classes[] = 'active';
}
$classes = implode( ' ', $classes );
if(isset($tab_data['class']) ) {
$classes .= ' '.$tab_data['class'];
}
?>
<a class="<?php esc_attr_e( $classes ); ?>"
href="<?php echo esc_url( $tab_data['url'] ); ?>">
<?php esc_html_e( $tab_data['name'] ); ?>
</a>
<?php endforeach; ?>
</nav>
</div>
</div>
<div class="row">
<div class="col-9">
<?php
switch ( getCurrentAdminTab() ) {
case 'general':
include "html-main-general.php";
break;
case 'events':
if ( getCurrentAdminAction() == 'edit' ) {
include "html-main-events-edit.php";
} else {
include "html-main-events.php";
}
break;
case 'woo':
include "html-main-woo.php";
break;
case 'edd':
include "html-main-edd.php";
break;
case 'wcf':
include "html-main-wcf.php";
break;
case 'head_footer':
/** @noinspection PhpIncludeInspection */
include PYS_FREE_PATH . '/modules/head_footer/views/html-admin-page.php';
break;
case 'facebook_settings':
/** @noinspection PhpIncludeInspection */
include PYS_FREE_PATH . '/modules/facebook/views/html-settings.php';
break;
case 'ga_settings':
/** @noinspection PhpIncludeInspection */
include PYS_FREE_PATH . '/modules/google_analytics/views/html-settings.php';
break;
case 'superpack_settings':
/** @noinspection PhpIncludeInspection */
include PYS_FREE_PATH . '/modules/superpack/views/html-settings.php';
break;
case 'gdpr':
include "html-gdpr.php";
break;
case 'reset_settings':
include "html-reset.php";
break;
case 'logs':
include "html-logs.php";
break;
default:
do_action( 'pys_admin_' . getCurrentAdminTab() );
}
?>
<p class="text-center mt-3 mb-0">
<a href="https://wordpress.org/support/plugin/pixelyoursite/reviews/?filter=5#new-post" target="_blank">Click here to give us a 5 stars review.</a> A huge thanks from the PixelYourSite team!
</p>
</div>
<div class="col-3">
<div class="card card-static border-primary">
<div class="card-body">
<p class="card-text">Track every key action and improve your ads return with the PRO
version:</p>
<a href="https://www.pixelyoursite.com/facebook-pixel-plugin/buy-pixelyoursite-pro?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-upgrade-orange"
target="_blank" class="btn btn-block btn-save">UPGRADE</a>
</div>
</div>
<nav class="nav nav-pills flex-column mb-3">
<?php foreach ( getAdminSecondaryNavTabs() as $tab_key => $tab_data ) : ?>
<?php
$classes = array(
'nav-item',
'nav-link',
);
if ( $tab_key == getCurrentAdminTab() ) {
$classes[] = 'active';
}
$classes = implode( ' ', $classes );
?>
<a class="<?php esc_attr_e( $classes ); ?>"
href="<?php echo esc_url( $tab_data['url'] ); ?>">
<?php esc_html_e( $tab_data['name'] ); ?>
</a>
<?php endforeach; ?>
<a class="nav-item nav-link" href="https://www.pixelyoursite.com/pixelyoursite-free-version?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-right-menu"
target="_blank" style="font-weight: bold;">HELP</a>
<a class="nav-item nav-link" href="https://www.pixelyoursite.com/video?utm_source=pixelyoursite-free-plugin&utm_medium=plugin&utm_campaign=free-plugin-right-menu"
target="_blank" style="font-weight: bold;">VIDEO TIPS</a>
<a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite', 'logs' ) ); ?>"
class="nav-item nav-link">Logs</a>
</nav>
<?php if ( 'woo' == getCurrentAdminTab() ) : ?>
<div class="card card-static border-disabled mb-5">
<div class="card-body" style="border-top: 0;">
<h4 class="card-title">Custom Audience File Export</h4>
<p class="card-text">Export a customer file with lifetime value. Use it to create a
Custom Audience and a Value-Based Lookalike Audience. More details
<a href="https://www.pixelyoursite.com/value-based-facebook-lookalike-audiences?utm_source=free&utm_medium=plugin&utm_campaign=right-column-free"
target="_blank">here</a>.</p>
<p style="text-align: center;"><?php renderProBadge(); ?></p>
<button type="submit" disabled="disabled" class="btn btn-sm btn-block btn-disabled">
Export clients LTV file
</button>
</div>
</div>
<?php endif; ?>
<?php if ( 'edd' == getCurrentAdminTab() ) : ?>
<div class="card card-static border-disabled mb-5">
<div class="card-body" style="border-top: 0;">
<h4 class="card-title">Custom Audience File Export</h4>
<p class="card-text">Export a customer file with lifetime value. Use it to create a
Custom Audience and a Value-Based Lookalike Audience. More details
<a href="https://www.pixelyoursite.com/value-based-facebook-lookalike-audiences?utm_source=free&utm_medium=plugin&utm_campaign=right-column-free"
target="_blank">here</a>.</p>
<p style="text-align: center;"><?php renderProBadge(); ?></p>
<button type="submit" disabled="disabled" class="btn btn-sm btn-block btn-disabled">
Export clients LTV file
</button>
</div>
</div>
<?php endif; ?>
<?php if ( ! isProductCatalogFeedProActive() ) : ?>
<div class="card card-static border-primary">
<div class="card-body">
<h4 class="card-title">WooCommerce Product Catalog Feeds</h4>
<p class="card-text">Generate auto-updating WooCommerce XML feeds for Facebook Product
Catalog, Google Merchant, and Google Ads (custom type).</p>
<a href="https://www.pixelyoursite.com/product-catalog-facebook?utm_source=free&utm_medium=plugin&utm_campaign=right-column-free" target="_blank"
class="btn btn-sm btn-block btn-primary">Click for details</a>
</div>
</div>
<?php endif; ?>
<?php if ( ! isEddProductsFeedProActive() ) : ?>
<div class="card card-static border-primary">
<div class="card-body">
<h4 class="card-title">Easy Digital Downloads Product Catalog Feeds</h4>
<p class="card-text">Generate auto-updating EDD XML feeds for Facebook Product Catalog.</p>
<a href="https://www.pixelyoursite.com/easy-digital-downloads-product-catalog?utm_source=free&utm_medium=plugin&utm_campaign=right-column-free"
target="_blank" class="btn btn-sm btn-block btn-primary">Click for details</a>
</div>
</div>
<?php endif; ?>
<?php if ( !isConsentMagicPluginActivated() ) : ?>
<div class="card card-static border-primary">
<div class="card-body">
<h4 class="card-title">ConsentMagic</h4>
<p class="card-text">Persuade your visitors to agree to tracking, while respecting the legal requirements. Inform, opt-out, or block tracking when needed.</p>
<a href="https://www.pixelyoursite.com/plugins/consentmagic?utm_source=free&utm_medium=plugin&utm_campaign=right-column-free" target="_blank"
class="btn btn-sm btn-block btn-primary">Click for details</a>
</div>
</div>
<?php endif; ?>
<?php if ( !isPixelCogActive() ) : ?>
<div class="card card-static border-primary">
<div class="card-body">
<h4 class="card-title">WooCommerce Cost of Goods</h4>
<p class="card-text">Add the cost of your products, calculate profit for each order, track the profit with PixelYourSite WooCommerce first-party reports.</p>
<a href="https://www.pixelyoursite.com/plugins/woocommerce-cost-of-goods?utm_source=free&utm_medium=plugin&utm_campaign=right-column-free" target="_blank"
class="btn btn-sm btn-block btn-primary">Click for details</a>
</div>
</div>
<?php endif; ?>
<?php if ( getCurrentAdminTab() !== 'reset_settings' ) : ?>
<a href="<?php echo esc_url( buildAdminUrl( 'pixelyoursite', 'reset_settings' ) ); ?>"
class="btn btn-sm btn-block btn-light mt-5">Reset all settings to defaults</a>
<?php endif; ?>
</div>
</div>
</form>
</div>
</div>
</div>