client = $client;
}
}
/**
* Don't show the notice
*
* @return \self
*/
public function hide_notice()
{
$this->show_notice = false;
return $this;
}
/**
* Add plugin data if needed
*
* @return \self
*/
public function add_plugin_data()
{
$this->plugin_data = true;
return $this;
}
/**
* Add extra data if needed
*
* @param array $data
*
* @return \self
*/
public function add_extra($data = [])
{
$this->extra_data = $data;
return $this;
}
/**
* Set custom notice text
*
* @param string $text
*
* @return \self
*/
public function notice($text = '')
{
$this->notice = $text;
return $this;
}
/**
* Initialize insights
*
* @return void
*/
public function init()
{
if ($this->client->type === 'plugin') {
$this->init_plugin();
} elseif ($this->client->type === 'theme') {
$this->init_theme();
}
}
/**
* Initialize theme hooks
*
* @return void
*/
public function init_theme()
{
$this->init_common();
add_action('switch_theme', [$this, 'deactivation_cleanup']);
add_action('switch_theme', [$this, 'theme_deactivated'], 12, 3);
}
/**
* Initialize plugin hooks
*
* @return void
*/
public function init_plugin()
{
// plugin deactivate popup
// if ( ! $this->is_local_server() ) {
// add_filter( 'plugin_action_links_' . $this->client->basename, [ $this, 'plugin_action_links' ] );
// add_action( 'admin_footer', [ $this, 'deactivate_scripts' ] );
// }
add_filter('plugin_action_links_' . $this->client->basename, [$this, 'plugin_action_links']);
add_action('admin_footer', [$this, 'deactivate_scripts']);
$this->init_common();
register_activation_hook($this->client->file, [$this, 'activate_plugin']);
register_deactivation_hook($this->client->file, [$this, 'deactivation_cleanup']);
}
/**
* Initialize common hooks
*
* @return void
*/
protected function init_common()
{
if ($this->show_notice) {
// tracking notice
add_action('admin_notices', [$this, 'admin_notice']);
}
add_action('admin_init', [$this, 'handle_optin_optout']);
// uninstall reason
add_action('wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', [$this, 'uninstall_reason_submission']);
// cron events
add_filter('cron_schedules', [$this, 'add_weekly_schedule']);
add_action($this->client->slug . '_tracker_send_event', [$this, 'send_tracking_data']);
// add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
}
/**
* Send tracking data to AppSero server
*
* @param bool $override
*
* @return void
*/
public function send_tracking_data($override = false)
{
if (!$this->tracking_allowed() && !$override) {
return;
}
// Send a maximum of once per week
$last_send = $this->get_last_send();
if ($last_send && $last_send > strtotime('-1 week')) {
return;
}
$tracking_data = $this->get_tracking_data();
$response = $this->client->send_request($tracking_data, 'track');
update_option($this->client->slug . '_tracking_last_send', time());
}
/**
* Get the tracking data points
*
* @return array
*/
protected function get_tracking_data()
{
$all_plugins = $this->get_all_plugins();
$users = get_users(
[
'role' => 'administrator',
'orderby' => 'ID',
'order' => 'ASC',
'number' => 1,
'paged' => 1,
]
);
$admin_user = (is_array($users) && !empty($users)) ? $users[0] : false;
$first_name = '';
$last_name = '';
if ($admin_user) {
$first_name = $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name;
$last_name = $admin_user->last_name;
}
$data = [
'url' => esc_url(home_url()),
'site' => $this->get_site_name(),
'admin_email' => get_option('admin_email'),
'first_name' => $first_name,
'last_name' => $last_name,
'hash' => $this->client->hash,
'server' => $this->get_server_info(),
'wp' => $this->get_wp_info(),
'users' => $this->get_user_counts(),
'active_plugins' => count($all_plugins['active_plugins']),
'inactive_plugins' => count($all_plugins['inactive_plugins']),
'ip_address' => $this->get_user_ip_address(),
'project_version' => $this->client->project_version,
'tracking_skipped' => false,
'is_local' => $this->is_local_server(),
];
// Add Plugins
if ($this->plugin_data) {
$plugins_data = [];
foreach ($all_plugins['active_plugins'] as $slug => $plugin) {
$slug = strstr($slug, '/', true);
if (!$slug) {
continue;
}
$plugins_data[$slug] = [
'name' => isset($plugin['name']) ? $plugin['name'] : '',
'version' => isset($plugin['version']) ? $plugin['version'] : '',
];
}
if (array_key_exists($this->client->slug, $plugins_data)) {
unset($plugins_data[$this->client->slug]);
}
$data['plugins'] = $plugins_data;
}
// Add Metadata
$extra = $this->get_extra_data();
if ($extra) {
$data['extra'] = $extra;
}
// Check this has previously skipped tracking
$skipped = get_option($this->client->slug . '_tracking_skipped');
if ($skipped === 'yes') {
delete_option($this->client->slug . '_tracking_skipped');
$data['tracking_skipped'] = true;
}
return apply_filters($this->client->slug . '_tracker_data', $data);
}
/**
* If a child class wants to send extra data
*
* @return mixed
*/
protected function get_extra_data()
{
if (is_callable($this->extra_data)) {
return call_user_func($this->extra_data);
}
if (is_array($this->extra_data)) {
return $this->extra_data;
}
return [];
}
/**
* Explain the user which data we collect
*
* @return array
*/
protected function data_we_collect()
{
$data = [
'Server environment details (php, mysql, server, WordPress versions)',
'Number of users in your site',
'Site language',
'Number of active and inactive plugins',
'Site name and URL',
'Your name and email address',
];
if ($this->plugin_data) {
array_splice($data, 4, 0, ["active plugins' name"]);
}
return $data;
}
/**
* Check if the user has opted into tracking
*
* @return bool
*/
public function tracking_allowed()
{
$allow_tracking = get_option($this->client->slug . '_allow_tracking', 'no');
return $allow_tracking === 'yes';
}
/**
* Get the last time a tracking was sent
*
* @return false|string
*/
private function get_last_send()
{
return get_option($this->client->slug . '_tracking_last_send', false);
}
/**
* Check if the notice has been dismissed or enabled
*
* @return bool
*/
public function notice_dismissed()
{
$hide_notice = get_option($this->client->slug . '_tracking_notice', null);
if ('hide' === $hide_notice) {
return true;
}
return false;
}
/**
* Check if the current server is localhost
*
* @return bool
*/
private function is_local_server()
{
$host = isset($_SERVER['HTTP_HOST']) ? sanitize_text_field(wp_unslash($_SERVER['HTTP_HOST'])) : 'localhost';
$ip = isset($_SERVER['SERVER_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['SERVER_ADDR'])) : '127.0.0.1';
$is_local = false;
if (
in_array($ip, ['127.0.0.1', '::1'], true)
|| !strpos($host, '.')
|| in_array(strrchr($host, '.'), ['.test', '.testing', '.local', '.localhost', '.localdomain'], true)
) {
$is_local = true;
}
return apply_filters('appsero_is_local', $is_local);
}
/**
* Schedule the event weekly
*
* @return void
*/
private function schedule_event()
{
$hook_name = wp_unslash($this->client->slug . '_tracker_send_event');
if (!wp_next_scheduled($hook_name)) {
wp_schedule_event(time(), 'weekly', $hook_name);
}
}
/**
* Clear any scheduled hook
*
* @return void
*/
private function clear_schedule_event()
{
wp_clear_scheduled_hook($this->client->slug . '_tracker_send_event');
}
/**
* Display the admin notice to users that have not opted-in or out
*
* @return void
*/
public function admin_notice()
{
if ($this->notice_dismissed()) {
return;
}
if ($this->tracking_allowed()) {
return;
}
if (!current_user_can('manage_options')) {
return;
}
// don't show tracking if a local server
// if ( $this->is_local_server() ) {
// return;
// }
$optin_url = wp_nonce_url(add_query_arg($this->client->slug . '_tracker_optin', 'true'), '_wpnonce');
$optout_url = wp_nonce_url(add_query_arg($this->client->slug . '_tracker_optout', 'true'), '_wpnonce');
if (empty($this->notice)) {
$notice = sprintf($this->client->__trans('Want to help make %1$s even more awesome? Allow %1$s to collect diagnostic data and usage information.'), $this->client->name);
} else {
$notice = $this->notice;
}
$policy_url = 'https://appsero.com/privacy-policy/';
$notice .= ' (' . $this->client->__trans('what we collect') . ')';
$notice .= '
' . implode(', ', $this->data_we_collect()) . '. ';
$notice .= 'We are using Appsero to collect your data. Learn more about how Appsero collects and handle your data.
client->__trans('We share your data with Appsero to troubleshoot problems & make product improvements. Learn more about how Appsero handles your data.'),
esc_url('https://appsero.com/'),
esc_url('https://appsero.com/privacy-policy')
);
?>
get_template() === $this->client->slug) {
$this->client->send_request($this->get_tracking_data(), 'deactivate');
}
}
/**
* Get user IP Address
*/
private function get_user_ip_address()
{
$response = wp_remote_get('https://icanhazip.com/');
if (is_wp_error($response)) {
return '';
}
$ip = trim(wp_remote_retrieve_body($response));
if (!filter_var($ip, FILTER_VALIDATE_IP)) {
return '';
}
return $ip;
}
/**
* Get site name
*/
private function get_site_name()
{
$site_name = get_bloginfo('name');
if (empty($site_name)) {
$site_name = get_bloginfo('description');
$site_name = wp_trim_words($site_name, 3, '');
}
if (empty($site_name)) {
$site_name = esc_url(home_url());
}
return $site_name;
}
/**
* Send request to appsero if user skip to send tracking data
*/
private function send_tracking_skipped_request()
{
$skipped = get_option($this->client->slug . '_tracking_skipped');
$data = [
'hash' => $this->client->hash,
'previously_skipped' => false,
];
if ($skipped === 'yes') {
$data['previously_skipped'] = true;
} else {
update_option($this->client->slug . '_tracking_skipped', 'yes');
}
$this->client->send_request($data, 'tracking-skipped');
}
/**
* Deactivation modal styles
*/
private function deactivation_modal_styles()
{
?>