setup_constants();
if ( ! has_action( 'plugins_loaded', array( self::$instance, 'include_deprecated_files' ) ) ) {
add_action( 'plugins_loaded', array( self::$instance, 'include_deprecated_files' ), 20 );
}
}
return self::$instance;
}
/**
* Sets up constants for file paths, folders, URLs and directory names related to the plugin.
*
* @since 1.0.0
*/
public function setup_constants() {
// Set the core file path
define( 'SEG_FILE_PATH', dirname( __FILE__ ) );
// Define the path to the plugin folder
define( 'SEG_DIR_NAME', basename( SEG_FILE_PATH ) );
// Define the URL to the plugin folder
define( 'SEG_FOLDER', dirname( plugin_basename( __FILE__ ) ) );
define( 'SEG_URL' , plugins_url( '', __FILE__ ) );
}
/**
* Includes deprecated files, specifically our old class names.
* They simply extend their replacement classes and are only includes if other plugins do not define those classes.
*
* @since 1.0.0
*/
public function include_deprecated_files() {
// Include old files for back compat
include_once( SEG_FILE_PATH . '/includes/class.analytics.php' );
include_once( SEG_FILE_PATH . '/includes/class.analytics-wordpress.php' );
}
/**
* Render the Segment.io Javascript snippet.
*
* @since 1.0.0
*
* @param array $settings Settings options array.
* @param bool $ignore Whether or not to ignore the call and avoid outputting the API key snippet.
*/
public static function initialize( $settings, $ignore = false ) {
if ( ! isset( $settings['api_key'] ) || $settings['api_key'] == '' ) {
return;
}
include_once( SEG_FILE_PATH . '/templates/snippet.php' );
}
/**
* Render a Javascript `identify` call
*
* @since 1.0.0
*
* @param int|string $user_id Current User ID.
* Generated via get_current_user_id() if logged in, anonymous user ID if not.
* @param array $traits Array of traits to pass to Segment.
* @param array $options Array of options to pass to Segment.
*/
public static function identify( $user_id, $traits = array(), $options = array() ) {
// Set the proper `library` option so we know where the API calls come from.
$options['library'] = 'analytics-wordpress';
include_once( SEG_FILE_PATH. '/templates/identify.php' );
}
/**
* Render a Javascript `track` call
*
* @since 1.0.0
*
* @param string $event The name of the event to pass to Segment.
* @param array $properties An array of properties to pass to Segment.
* @param array $options An array of options to pass to Segment.
* @param boolean $http_event Whether or not the event is occurring over HTTP, as opposed to on page load.
* This is helpful to track events that occur between page loads, like commenting.
*
*/
public static function track( $event, $properties = array(), $options = array(), $http_event = false ) {
// Set the proper `library` option so we know where the API calls come from.
$options['library'] = 'analytics-wordpress';
include_once( SEG_FILE_PATH . '/templates/track.php' );
}
/**
* Render a Javascript `track` call
*
* @since 1.0.0
*
* @param string $category Category (or name) of event
* @param string $name Optional, but if set, category must be set as well.
* @param array $properties An array of properties to pass to Segment.
* @param array $options An array of options to pass to Segment.
* @param boolean $http_event Whether or not the event is occurring over HTTP, as opposed to on page load.
* This is helpful to track events that occur between page loads, like commenting.
*/
public static function page( $category = '', $name = '', $properties = array(), $options = array(), $http_event = false ) {
include_once( SEG_FILE_PATH . '/templates/page.php' );
}
/**
* Creates an alias between an anonymous ID and a newly created user ID.
* Primarily used for MixPanel.
*
* @since 1.0.0
*
* @param int|string $from The anonymous ID that we're aliasing from.
* @param int|string $to The newly created User ID we are aliasing to.
* @param string $context Optional context parameter to be passed to Segment.
*/
public static function alias( $from, $to, $context = '' ) {
include_once( SEG_FILE_PATH . '/templates/alias.php' );
}
}
class Segment_Analytics_WordPress {
/**
* Slug used in page and menu names
*/
const SLUG = 'analytics';
/**
* Current plugin version.
*/
const VERSION = '1.0.3';
/**
* The singleton instance of Segment_Analytics_WordPress.
*
* @access private
* @var Segment_Analytics_WordPress
* @since 1.0.0
*/
private static $instance;
/**
* The singleton instance of Segment_Analytics, for use in our class.
*
* @access private
* @var Segment_Analytics
* @since 1.0.0
*/
private $analytics;
/**
* The name of our options array.
*
* @access private
* @var string
* @since 1.0.0
*/
private $option = 'analytics_wordpress_options';
/**
* The default values for our options array.
*
* Not used since 1.0.0, outside of activation hooks, with our move to the Settings API.
* See Segment_Analytics_WordPress::register_settings().
*
* @access public
* @var array
* @since 1.0.0
*/
public $defaults = array(
// Your Segment.io API key that we'll use to initialize analytics.js.
'api_key' => '',
// Whether or not we should ignore users of above a certain permissions
// level. (eg. `11` ignores nobody and `8` ignores Administrators)
'ignore_user_level' => 11,
// Whether or not we should track events for posts. This also includes
// custom post types, for example a Product post type.
'track_posts' => 1,
// Whether or not we should track events for pages. This includes the
// Home page and things like the About page, Contact page, etc.
'track_pages' => 1,
// Whether or not we should track custom events for archive pages like
// the Category archive or the Author archive.
'track_archives' => 1,
// Whether or not we should track custom events for comments
'track_comments' => 1,
// Whether or not we should track custom events for users logging in
'track_logins' => 1,
// Whether or not we should track custom events for viewing the logged in page.
'track_login_page' => false,
// Whether or not we should track custom events for the Search page.
'exclude_custom_post_types' => array(),
);
/**
* Retrieves the one true instance of Segment_Analytics_WordPress
*
* @since 1.0.0
* @return object Singleton instance of Segment_Analytics_WordPress
*/
public static function get_instance() {
if ( ! isset( self::$instance ) && ! ( self::$instance instanceof Segment_Analytics_WordPress ) ) {
self::$instance = new Segment_Analytics_WordPress;
self::$instance->load_textdomain();
self::$instance->admin_hooks();
self::$instance->frontend_hooks();
self::$instance->analytics = Segment_Analytics::get_instance();
self::$instance->include_files();
}
return self::$instance;
}
/**
* Returns Settings option name.
*
* @since 1.0.0
*
* @return string Settings option name
*/
public function get_option_name() {
return $this->option;
}
/**
* Hooks into actions and filters that affect the administration areas.
*
* @since 1.0.0
*/
public function admin_hooks() {
if ( is_admin() && ! ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) {
add_action( 'admin_menu' , array( $this, 'admin_menu' ) );
add_filter( 'plugin_action_links', array( $this, 'plugin_action_links' ), 10, 2 );
add_filter( 'plugin_row_meta' , array( $this, 'plugin_row_meta' ) , 10, 2 );
add_action( 'admin_init' , array( $this, 'register_settings' ) );
}
}
/**
* Includes core classes.
* Currently includes Segment_Cookie and eCommerce bootstrap.
*
* @uses do_action() Allows other plugins to hook in before or after everything is bootstrapped.
*
* @since 1.0.0
*/
public function include_files() {
do_action( 'segment_pre_include_files', self::$instance );
include_once( SEG_FILE_PATH . '/includes/class.segment-settings.php' );
include_once( SEG_FILE_PATH . '/includes/class.segment-cookie.php' );
include_once( SEG_FILE_PATH . '/integrations/ecommerce.php' );
include_once( SEG_FILE_PATH . '/integrations/intercom.php' );
do_action( 'segment_include_files', self::$instance );
}
/**
* Hooks into actions and filters that affect the front-end.
* That is to say, this is where the magic happens.
*
* @since 1.0.0
*/
public function frontend_hooks() {
add_action( 'wp_head' , array( $this, 'wp_head' ) , 9 );
add_action( 'admin_head' , array( $this, 'wp_head' ) , 9 );
add_action( 'login_head' , array( $this, 'wp_head' ) , 9 );
add_action( 'wp_footer' , array( $this, 'wp_footer' ) , 9 );
add_action( 'login_footer' , array( $this, 'wp_footer' ) , 9 );
add_action( 'admin_footer' , array( $this, 'wp_footer' ) , 9 );
add_action( 'wp_insert_comment', array( $this, 'insert_comment' ), 9, 2 );
add_action( 'wp_login' , array( $this, 'login_event' ), 9, 2 );
add_action( 'user_register' , array( $this, 'user_register' ), 9 );
}
/**
* Registers our settings, fields and sections using the WordPress Settings API.
*
* Developers should use the `segment_default_settings` filter to add settings.
* They should also use the `segm.ent_settings_core_validation` filter to validate
* any settings they add.
*
* @since 1.0.0
* @return void
*/
public function register_settings() {
$settings = apply_filters( 'segment_default_settings', array(
'general' => array(
'title' => __( 'General', 'segment' ),
'callback' => array( 'Segment_Settings', 'general_section_callback' ),
'fields' => array(
array(
'name' => 'api_key',
'title' => __( 'Segment API Write Key', 'segment' ),
'callback' => array( 'Segment_Settings', 'api_key_callback' ),
)
)
),
'advanced' => array(
'title' => __( 'Advanced Settings', 'segment' ),
'callback' => array( 'Segment_Settings', 'advanced_section_callback' ),
'fields' => array(
array(
'name' => 'ignore_user_level',
'title' => __( 'Users to Ignore', 'segment' ),
'callback' => array( 'Segment_Settings', 'ignore_user_level_callback' ),
),
array(
'name' => 'track_posts',
'title' => __( 'Track Posts', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_posts_callback' ),
),
array(
'name' => 'exclude_post_types',
'title' => __( 'Exclude Post Types', 'segment' ),
'callback' => array( 'Segment_Settings', 'exclude_custom_post_types' ),
),
array(
'name' => 'track_pages',
'title' => __( 'Track Pages', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_pages_callback' ),
),
array(
'name' => 'track_archives',
'title' => __( 'Track Archives', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_archives_callback' ),
),
array(
'name' => 'track_archives',
'title' => __( 'Track Archives', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_archives_callback' ),
),
array(
'name' => 'track_comments',
'title' => __( 'Track Comments', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_comments_callback' ),
),
array(
'name' => 'track_logins',
'title' => __( 'Track Logins', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_logins_callback' ),
),
array(
'name' => 'track_login_page',
'title' => __( 'Track Login Page Views', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_login_page_callback' ),
),
array(
'name' => 'track_searches',
'title' => __( 'Track Searches', 'segment' ),
'callback' => array( 'Segment_Settings', 'track_search_callback' ),
)/*,
array(
'name' => 'use_intercom_secure_mode',
'title' => __( 'Intercom API Secret', 'segment' ),
'callback' => array( 'Segment_Settings', 'use_intercom_secure_mode' ),
)*/,
)
),
)
);
register_setting( self::SLUG, $this->get_option_name(), array( 'Segment_Settings', 'core_validation' ) );
foreach ( $settings as $section_name => $section ) {
add_settings_section(
$section_name,
$section['title'],
$section['callback'],
self::SLUG
);
foreach ( $section['fields'] as $field ) {
add_settings_field(
$field['name'],
$field['title'],
$field['callback'],
self::SLUG,
$section_name
);
}
}
}
/**
* Empty constructor, as we prefer to get_instance().
*
* @since 1.0.0
*
*/
public function __construct() {}
/**
* Loads the properly localized PO/MO files
*
* @since 1.0.0
*/
public function load_textdomain() {
// Set filter for plugin's languages directory
$segment_lang_dir = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
$segment_lang_dir = apply_filters( 'segment_languages_directory', $segment_lang_dir );
// Traditional WordPress plugin locale filter
$locale = apply_filters( 'plugin_locale', get_locale(), 'segment' );
$mofile = sprintf( '%1$s-%2$s.mo', 'segment', $locale );
// Setup paths to current locale file
$mofile_local = $segment_lang_dir . $mofile;
$mofile_global = WP_LANG_DIR . '/segment/' . $mofile;
if ( file_exists( $mofile_global ) ) {
// Look in global /wp-content/languages/segment folder
load_textdomain( 'segment', $mofile_global );
} elseif ( file_exists( $mofile_local ) ) {
// Look in local /wp-content/plugins/analytics-wordpress/languages/ folder
load_textdomain( 'segment', $mofile_local );
} else {
// Load the default language files
load_plugin_textdomain( 'segment', false, $segment_lang_dir );
}
}
/**
* Outputs analytics javascript and analytics.identify() snippet in head for admin, login page and wp_head.
*
* @since 1.0.0
*/
public function wp_head() {
// Figure out whether the user should be ignored or not.
$ignore = false;
$settings = $this->get_settings();
$user = wp_get_current_user();
if ( $user->user_level >= $settings['ignore_user_level'] ) {
$ignore = true;
}
// Render the snippet.
self::$instance->analytics->initialize( $settings, $ignore );
}
/**
* Outputs analytics.track()/.page()/ snippet in head for admin, login page and wp_footer.
*
* @since 1.0.0
*/
public function wp_footer() {
// Identify the user if the current user merits it.
$identify = $this->get_current_user_identify();
if ( $identify ) {
if ( ! isset( $identify['options'] ) ) {
$identify['options'] = array();
}
self::$instance->analytics->identify( $identify['user_id'], $identify['traits'], $identify['options'] );
}
// Track a custom page view event if the current page merits it.
$track = $this->get_current_page_track();
$page = $this->get_current_page();
if ( $track ) {
$http_event = isset( $track['http_event'] ) ? $track['http_event'] : false;
self::$instance->analytics->track( $track['event'], $track['properties'], array(), $http_event );
}
if ( $page ) {
self::$instance->analytics->page( $page['page'], $page['properties'] );
}
}
/**
* Uses Segment_Cookie::set_cookie() to notify Segment that a comment has been left.
*
* @param int $id Comment ID. Unused.
* @param object $comment WP_Comment object Unused.
*
* @since 1.0.0
*/
public function insert_comment( $id, $comment ) {
Segment_Cookie::set_cookie( 'left_comment', md5( json_encode( wp_get_current_commenter() ) ) );
}
/**
* Uses Segment_Cookie::set_cookie() to notify Segment that a user has logged in.
*
* @since 1.0.0
*
* @param string $login Username of logged in user.
* @param WP_User $user User object of logged in user.
*
*/
public function login_event( $login, $user ) {
Segment_Cookie::set_cookie( 'logged_in', md5( json_encode( $user ) ) );
}
/**
* Uses Segment_Cookie::set_cookie() to notify Segment that a user has signed up.
*
* @since 1.0.0
*
* @param int $user_id Username of new user.
*
*/
public function user_register( $user_id ) {
Segment_Cookie::set_cookie( 'signed_up', json_encode( $user_id ) );
}
/**
* Adds "Settings" link to plugin row.
*
* @param array $links Array of links on plugin action row.
* @param string $file Basename of file.
* @return array $links Modified array of links on plugin action row.
*/
public function plugin_action_links( $links, $file ) {
// Not for other plugins, silly. NOTE: This doesn't work properly when
// the plugin for testing is a symlink!! If you change this, test it.
// Note: Works fine as of 3.9, see @link: https://core.trac.wordpress.org/ticket/16953
if ( $file != plugin_basename( __FILE__ ) ) {
return $links;
}
// Add settings link to the beginning of the row of links.
$settings_link = sprintf( '%s', __( 'Settings' ) );
array_unshift( $links, $settings_link );
return $links;
}
/**
* Adds Settings and Documentation links to plugin row meta.
*
* @since 1.0.0
*
* @param array $plugin_meta An array of the plugin's metadata,
* including the version, author,
* author URI, and plugin URI.
* @param string $plugin_file Path to the plugin file, relative to the plugins directory.
*
* @return array Modified array of plugin metadata.
*/
public function plugin_row_meta( $plugin_meta, $plugin_file ) {
// Not for other plugins, silly. NOTE: This doesn't work properly when
// the plugin for testing is a symlink!! If you change this, test it.
// Note: Works fine as of 3.9, see @link: https://core.trac.wordpress.org/ticket/16953
if ( $plugin_file != plugin_basename( __FILE__ ) ) {
return $plugin_meta;
}
// Add a settings and docs link to the end of the row of links row of links.
$settings_link = sprintf( '%s', __( 'Settings' ) );
$docs_link = sprintf( '%s', __( 'Docs', 'segment' ) );
array_push( $plugin_meta, $settings_link, $docs_link );
return $plugin_meta;
}
/**
* Adds "Analytics" Menu item to admin area.
*
* @since 1.0.0
*/
public function admin_menu() {
add_options_page(
apply_filters( 'segment_admin_menu_page_title', __( '7SEGMENTS', 'segment' ) ), // Page Title
apply_filters( 'segment_admin_menu_menu_title', __( '7SEGMENTS', 'segment' ) ), // Menu Title
apply_filters( 'segment_admin_settings_capability', 'manage_options' ), // Capability Required
self::SLUG, // Menu Slug
array( $this, 'admin_page' ) // Function
);
}
/**
* The callback used to build out the admin settings area.
*
* @since 1.0.0
*/
public function admin_page() {
// Make sure the user has the required permissions to view the settings.
if ( ! current_user_can( 'manage_options' ) ) {
wp_die( __( 'Sorry, you don\'t have the permissions to access this page.', 'segment' ) );
}
include_once( SEG_FILE_PATH . '/templates/settings.php');
}
/**
* Retrieves settings array.
*
* @since 1.0.0
*
* @uses apply_filters() Applies 'segment_get_settings' filter to allow other developers to override.
*
* @return array Array of settings.
*/
public function get_settings() {
return apply_filters( 'segment_get_settings', get_option( $this->option ), $this );
}
/**
* Updates settings array.
*
* @since 1.0.0
*
* @param array $settings Array of settings
* @uses apply_filters() Applies 'segment_get_settings' filter to allow other developers to override.
*
* @deprecated Deprecated in 1.0.0
*
* @return array Array of settings.
*/
private function set_settings( $settings ) {
return update_option( $this->option, $settings );
}
/**
* Based on the current user or commenter, see if we have enough information
* to record an `identify` call. Since commenters don't have IDs, we
* identify everyone by their email address.
*
* @since 1.0.0
*
* @return bool|array Returns false if there is no commenter or logged in user
* An array of the user ID and traits if there is an authenticated user.
*/
private function get_current_user_identify() {
$settings = $this->get_settings();
$user = wp_get_current_user();
$commenter = wp_get_current_commenter();
$identify = false;
// We've got a logged-in user.
// http://codex.wordpress.org/Function_Reference/wp_get_current_user
if ( is_user_logged_in() && $user ) {
$identify = array(
'user_id' => $user->user_email,
'traits' => array(
'username' => $user->user_login,
'email' => $user->user_email,
'first_name' => $user->user_firstname,
'last_name' => $user->user_lastname,
'url' => $user->user_url
)
);
}
// We've got a commenter.
// http://codex.wordpress.org/Function_Reference/wp_get_current_commenter
else if ( $commenter ) {
$identify = array(
'user_id' => $commenter['comment_author_email'],
'traits' => array(
'email' => $commenter['comment_author_email'],
'name' => $commenter['comment_author'],
'url' => $commenter['comment_author_url']
)
);
}
if ( $identify ) {
// Clean out empty traits before sending it back.
$identify['traits'] = array_filter( $identify['traits'] );
}
/**
* Allows developers to modify the entire $identify call.
*
* @since 1.0.0
*/
return apply_filters( 'segment_get_current_user_identify', $identify, $settings, $this );
}
/**
* Used to track the current event. Used for analytics.track().
*
* @since 1.0.0
*
* @return array Array containing the page being tracked along with any additional properties.
*/
private function get_current_page_track() {
$settings = $this->get_settings();
// Login Event
// --------
if ( $settings['track_logins'] ) {
$user = wp_get_current_user();
$hash = md5( json_encode( $user ) );
if ( Segment_Cookie::get_cookie( 'logged_in', $hash ) ) {
$track = array(
'event' => 'Logged In',
'properties' => array(
'username' => $user->user_login,
'email' => $user->user_email,
'name' => $user->display_name,
'first_name' => $user->user_firstname,
'last_name' => $user->user_lastname,
'url' => $user->user_url
),
'http_event' => 'logged_in'
);
}
}
// Posts
// -----
if ( $settings['track_posts'] ) {
// A post or a custom post. `is_single` also returns attachments, so
// we filter those out. The event name is based on the post's type,
// and is uppercased.
if ( is_single() && ! is_attachment() ) {
if ( ! self::is_excluded_post_type() ) {
$categories = implode( ', ', wp_list_pluck( get_categories( get_the_ID() ), 'name' ) );
$track = array(
'event' => "Visited",
'properties' => array(
'post_type' => ucfirst( get_post_type() ),
'title' => single_post_title( '', false ),
'category' => $categories
)
);
}
}
}
// Pages
// -----
if ( $settings['track_pages'] ) {
// The front page of their site, whether it's a page or a list of
// recent blog entries. `is_home` only works if it's not a page,
// that's why we don't use it.
if ( is_front_page() ) {
$track = array(
'event' => 'Visited',
'properties' => array(
'post_type' => 'Homepage',
'title' => 'Homepage'
)
);
}
// A normal WordPress page.
else if ( is_page() ) {
$track = array(
'event' => 'Visited',
'properties' => array(
'post_type' => 'Page',
'title' => single_post_title( '', false )
)
);
}
}
// Archives
// --------
if ( $settings['track_archives'] ) {
// An author archive page. Check the `wp_title` docs to see how they
// get the title of the page, cuz it's weird.
// http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/general-template.php#L0
if ( is_author() ) {
$author = get_queried_object();
$track = array(
'event' => 'Visited',
'properties' => array(
'post_type' => 'Author Page',
'author' => $author->display_name,
'category' => 'Wordpress'
)
);
}
// A tag archive page. Use `single_tag_title` to get the name.
// http://codex.wordpress.org/Function_Reference/single_tag_title
else if ( is_tag() ) {
$track = array(
'event' => 'Visited',
'properties' => array(
'post_type' => 'Tag Page',
'tag' => single_tag_title( '', false ),
'category' => 'Wordpress'
)
);
}
// A category archive page. Use `single_cat_title` to get the name.
// http://codex.wordpress.org/Function_Reference/single_cat_title
else if ( is_category() ) {
$track = array(
'event' => 'Visited',
'properties' => array(
'post_type' => 'Category Page',
'category' => single_cat_title( '', false )
)
);
}
}
// Comments
// --------
if ( $settings['track_comments'] ) {
$commenter = wp_get_current_commenter();
$hash = md5( json_encode( $commenter ) );
if ( Segment_Cookie::get_cookie( 'left_comment', $hash ) ) {
$track = array(
'event' => __( 'Commented', 'segment' ),
'properties' => array(
'commenter' => $commenter
),
'http_event' => 'left_comment'
);
}
}
// Login Page
// --------
if ( $settings['track_login_page'] ) {
if ( did_action( 'login_init' ) ) {
$track = array(
'event' => 'Visited',
'properties' => array(
'post_type' => 'Login Page',
'category' => 'Wordpress'
)
);
}
}
// Searches
// --------
if ( $settings['track_searches'] ) {
// The search page.
if ( is_search() ) {
$track = array(
'event' => 'Visited',
'properties' => array(
'query' => get_query_var( 's' ),
'post_type' => 'Search',
'category' => 'Wordpress'
)
);
}
}
if ( Segment_Cookie::get_cookie( 'signed_up' ) ) {
$user_id = json_decode( Segment_Cookie::get_cookie( 'signed_up' ) );
$user = get_user_by( 'id', $user_id );
add_filter( 'segment_get_current_user_identify', array( self::$instance, 'new_user_identify' ) );
$track = array(
'event' => __( 'Registration', 'segment' ),
'properties' => array(
'username' => $user->user_login,
'email' => $user->user_email,
'name' => $user->display_name,
'first_name' => $user->user_firstname,
'last_name' => $user->user_lastname,
'url' => $user->user_url
),
'http_event' => 'signed_up'
);
}
// We don't have a page we want to track.
if ( ! isset( $track ) ) {
$track = false;
}
if ( $track ) {
// All of these are checking for pages, and we don't want that to throw
// off Google Analytics's bounce rate, so mark them `noninteraction`.
$track['properties']['noninteraction'] = true;
// Clean out empty properties before sending it back.
$track['properties'] = array_filter( $track['properties'] );
}
return apply_filters( 'segment_get_current_page_track', $track, $settings, $this );
}
/**
* Filters the .identify() call with the newly signed up user.
* This is helpful, as the user will often times not be authenticated after signing up.
*
* @since 1.0.0
*
* @param mixed $identify False if no user is found, array of traits and ID if a user is found.
* @return array $identify Array of traits for newly signed up user.
*/
public function new_user_identify( $identify ) {
if ( Segment_Cookie::get_cookie( 'signed_up' ) ) {
$user_id = json_decode( Segment_Cookie::get_cookie( 'signed_up' ) );
$user = get_user_by( 'id', $user_id );
$identify = array(
'user_id' => $user->user_email,
'traits' => array(
'username' => $user->user_login,
'email' => $user->user_email,
'first_name' => $user->user_firstname,
'last_name' => $user->user_lastname,
'url' => $user->user_url
)
);
}
return $identify;
}
/**
* Used to track the current page. Used for analytics.page().
* Unlike get_current_page_track(), we use this primarily as a pub-sub observer for other core events.
* This makes it much more manageable for other developers to hook and unhook from it as needed.
*
* @since 1.0.0
*
* @return array Array containing the page being tracked along with any additional properties.
*/
private function get_current_page() {
$page = apply_filters( 'segment_get_current_page', false, $this->get_settings(), $this );
if ( $page ) {
$page['properties'] = is_array( $page['properties'] ) ? $page['properties'] : array();
// All of these are checking for pages, and we don't want that to throw
// off Google Analytics's bounce rate, so mark them `noninteraction`.
$page['properties']['noninteraction'] = true;
// Clean out empty properties before sending it back.
$page['properties'] = array_filter( $page['properties'] );
}
return $page;
}
/**
* Kept for backwards compatibility, as clean_array() used to be, essentially, a round-about to array_filter().
*
* @since 1.0.0
*
* @deprecated
*
* @param array $array Array to clean.
* @return array Filtered array.
*/
private function clean_array( $array ) {
return array_filter( $array );
}
/**
* Used in our activation hook to set up our default settings.
*
* @since 1.0.0
*
* @return void
*/
public static function setup_settings() {
$settings = get_option( Segment_Analytics_WordPress::get_instance()->get_option_name() );
if ( ! empty( $settings ) ) {
return;
}
update_option( Segment_Analytics_WordPress::get_instance()->get_option_name(), Segment_Analytics_WordPress::get_instance()->defaults );
}
/**
* Helper function, essentially a replica of stripslashes_deep, but for esc_js.
*
* @since 1.0.0
*
* @param mixed $value Handles arrays, strings and objects that we are trying to escape for JS.
* @return mixed $value esc_js()'d value.
*/
public static function esc_js_deep( $value ) {
if ( is_array( $value ) ) {
$value = array_map( array( __CLASS__, 'esc_js_deep' ), $value );
} elseif ( is_object( $value ) ) {
$vars = get_object_vars( $value );
foreach ( $vars as $key => $data ) {
$value->{$key} = self::esc_js_deep( $data );
}
} elseif ( is_string( $value ) ) {
$value = esc_js( $value );
}
return $value;
}
/**
* Checks if current post type is excluded or not.
* Intended to be used on singular views.
*
* @since 1.0.0
*
* @return boolean Whether or not post type is excluded
*/
public static function is_excluded_post_type() {
$settings = self::get_instance()->get_settings();
$cpts = isset( $settings['exclude_custom_post_types'] ) ? $settings['exclude_custom_post_types'] : array();
return in_array( get_post_type(), $cpts );
}
}
register_activation_hook( __FILE__, array( 'Segment_Analytics_WordPress', 'setup_settings' ) );
add_action( 'plugins_loaded', 'Segment_Analytics_WordPress::get_instance' );