plugin install

This commit is contained in:
Tony Volpe
2024-06-18 17:29:05 -04:00
parent e1aaedd1ae
commit 41f50eacc4
5880 changed files with 1057631 additions and 39681 deletions

View File

@@ -0,0 +1,139 @@
<?php
namespace Gravity_Forms\Gravity_Forms\Telemetry;
use GFCommon;
use GFFormsModel;
/**
* Class GF_Telemetry_Data
*
* Base class for telemetry data.
*
* @package Gravity_Forms\Gravity_Forms\Telemetry
*/
abstract class GF_Telemetry_Data {
/**
* @var array $data Data to be sent.
*/
public $data = array();
/**
* @var string $key Unique identifier for this data object.
*/
public $key = '';
/**
* @var bool $data_collection Whether data collection is allowed.
*/
public $data_collection = '';
/**
* @var string
*/
const TELEMETRY_ENDPOINT = 'https://in.gravity.io/';
public function __construct() {
$this->data_collection = $this->is_data_collection_allowed();
}
/**
* Determine if the user has allowed data collection.
*
* @since 2.8.3
*
* @return false|mixed|null
*/
public function is_data_collection_allowed() {
return get_option( 'rg_gforms_dataCollection', false );
}
/**
* Get the current telemetry data.
*
* @since 2.8
*
* @return array
*/
public static function get_data() {
$existing_data = get_option( 'gf_telemetry_data', [] );
return $existing_data;
}
/**
* Save telemetry data.
*
* @since 2.8
*
* @param GF_Telemetry_Data $data The data to save.
*
* @return void
*/
public static function save_data( GF_Telemetry_Data $data ) {
$existing_data = self::get_data();
if ( ! $existing_data ) {
$existing_data = array(
'snapshot' => array(),
'events' => array(),
);
}
if ( $data->key == 'snapshot' ) {
$existing_data[ $data->key ] = $data;
} else {
$existing_data['events'][] = $data;
}
update_option( 'gf_telemetry_data', $existing_data, false );
}
/**
* Take a snapshot of the current site data.
*
* @since 2.8
*
* @return void
*/
public static function take_snapshot() {
$snapshot = new GF_Telemetry_Snapshot_Data();
self::save_data( $snapshot );
}
/**
* Send data to the telemetry endpoint.
*
* @since 2.8
*
* @param array $entries The data to send.
*
* @return array|WP_Error
*/
public static function send_data( $entries ) {
// allow overriding the endpoint to use the local or staging environment for testing purposes.
$endpoint = defined( 'GF_TELEMETRY_ENDPOINT' ) ? GF_TELEMETRY_ENDPOINT : self::TELEMETRY_ENDPOINT;
$site_url = get_site_url();
$data = array(
'license_key_md5' => md5( get_option( 'rg_gforms_key', '' ) ),
'site_url' => $site_url,
'product' => 'gravityforms',
'tag' => 'system_report',
'data' => $entries,
);
return wp_remote_post(
$endpoint . 'api/telemetry_data_bulk',
array(
'headers' => array(
'Content-Type' => 'application/json',
'Authorization' => sha1( $site_url ),
),
'method' => 'POST',
'data_format' => 'body',
'body' => json_encode( $data ),
)
);
}
}

View File

@@ -0,0 +1,73 @@
<?php
namespace Gravity_Forms\Gravity_Forms\Telemetry;
use GFCommon;
use function tad\WPBrowser\debug;
if ( ! class_exists( 'GFForms' ) ) {
die();
}
if ( ! class_exists( 'GF_Background_Process' ) ) {
require_once GF_PLUGIN_DIR_PATH . 'includes/libraries/gf-background-process.php';
}
/**
* GF_Telemetry_Processor Class.
*/
class GF_Telemetry_Processor extends \GF_Background_Process {
/**
* @var string
*/
protected $action = 'gf_telemetry_processor';
/**
* Task
*
* Process a single batch of telemetry data.
*
* @param mixed $batch
* @return mixed
*/
protected function task( $batch ) {
if ( ! is_array( $batch ) ) {
$batch = array( $batch );
}
$raw_response = null;
\GFCommon::log_debug( __METHOD__ . sprintf( '(): Processing a batch of %d telemetry data.', count( $batch ) ) );
$data = array();
foreach ( $batch as $item ) {
if ( ! is_object( $item ) || ! property_exists( $item, 'data' ) ) {
continue;
}
// attach type & tag, required by the telemetry API.
$item->data['type'] = $item->key === 'snapshot' ? 'snapshot' : 'event';
$item->data['tag'] = $item->key;
$data[] = $item->data;
}
$raw_response = GF_Telemetry_Data::send_data( $data );
if ( is_wp_error( $raw_response ) ) {
\GFCommon::log_debug( __METHOD__ . sprintf( '(): Failed sending telemetry data. Code: %s; Message: %s.', $raw_response->get_error_code(), $raw_response->get_error_message() ) );
return false;
}
foreach ( $batch as $item ) {
if ( ! is_object( $item ) ) {
\GFCommon::log_debug( __METHOD__ . sprintf( '(): Telemetry data is missing. Aborting running data_sent method on this entry.' ) );
continue;
}
$classname = get_class( $item );
if ( method_exists( $classname, 'data_sent' ) ) {
$classname::data_sent( $raw_response );
}
}
return false;
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Gravity_Forms\Gravity_Forms\Telemetry;
use Gravity_Forms\Gravity_Forms\GF_Service_Container;
use Gravity_Forms\Gravity_Forms\GF_Service_Provider;
use GFCommon;
use GFFormsModel;
/**
* Class GF_Telemetry_Service_Provider
*
* Service provider for the telemetry Service.
*
* @package Gravity_Forms\Gravity_Forms\Telemetry;
*/
class GF_Telemetry_Service_Provider extends GF_Service_Provider {
const TELEMETRY_SCHEDULED_TASK = 'gravityforms_telemetry_dispatcher';
const BATCH_SIZE = 10;
/**
* Register services to the container.
*
* @since
*
* @param GF_Service_Container $container
*/
public function register( GF_Service_Container $container ) {
require_once GF_PLUGIN_DIR_PATH . 'includes/telemetry/class-gf-telemetry-data.php';
require_once GF_PLUGIN_DIR_PATH . 'includes/telemetry/class-gf-telemetry-snapshot-data.php';
}
/**
* Initialize the scheduler.
*
* @since
*
* @param GF_Service_Container $container
*
* @return void
*/
public function init( GF_Service_Container $container ) {
add_action( self::TELEMETRY_SCHEDULED_TASK, array( $this, 'enqueue_telemetry_batches' ) );
}
/**
* Enqueue batches of telemetry events to be processed in the background.
*
* @since
*
* @return void
*/
public function enqueue_telemetry_batches() {
// Only run once a week.
$last_run = get_option( 'gf_last_telemetry_run', 0 );
$current_time = time();
if ( $current_time - $last_run < 60 * 60 * 24 * 7 ) {
return;
}
update_option( 'gf_last_telemetry_run', $current_time );
\GFCommon::log_debug( __METHOD__ . sprintf( '(): Enqueuing telemetry batches' ) );
GF_Telemetry_Data::take_snapshot();
$processor = $this->container->get( \Gravity_Forms\Gravity_Forms\Async\GF_Background_Process_Service_Provider::TELEMETRY );
$full_telemetry_data = GF_Telemetry_Data::get_data();
$snapshot = $full_telemetry_data['snapshot'];
// Enqueue the snapshot first, alone, to be sent to its own endpoint.
$processor->push_to_queue( $snapshot );
$processor->save()->dispatch();
$full_telemetry_data = array_chunk( $full_telemetry_data['events'], self::BATCH_SIZE, true );
foreach ( $full_telemetry_data as $batch ) {
$processor->push_to_queue( $batch );
$processor->save()->dispatch();
}
// Clear saved telemetry data except the snapshot.
update_option(
'gf_telemetry_data',
array(
'snapshot' => $snapshot,
'events' => array(),
),
false
);
}
}

View File

@@ -0,0 +1,242 @@
<?php
namespace Gravity_Forms\Gravity_Forms\Telemetry;
use GFCommon;
use GFForms;
use GFFormsModel;
use \Gravity_Forms\Gravity_Forms\Setup_Wizard\GF_Setup_Wizard_Service_Provider;
use \Gravity_Forms\Gravity_Forms\Setup_Wizard\Endpoints\GF_Setup_Wizard_Endpoint_Save_Prefs;
class GF_Telemetry_Snapshot_Data extends GF_Telemetry_Data {
/**
* @var string $key Identifier for this data object.
*/
public $key = 'snapshot';
public function __construct() {
parent::__construct();
/**
* Array of callback functions returning an array of data to be included in the telemetry snapshot.
*
* @since 2.8
*/
$callbacks = array(
array( $this, 'get_site_basic_info' ),
array( $this, 'get_gf_settings' ),
array( $this, 'get_legacy_forms' ),
);
// Merges the default callbacks with any additional callbacks added via the gform_telemetry_snapshot_data filter. Default callbacks are added last so they can't be overridden.
$callbacks = array_merge( $this->get_callbacks(), $callbacks );
foreach ( $callbacks as $callback ) {
if ( is_callable( $callback ) ) {
$this->data = array_merge( $this->data, call_user_func( $callback ) );
}
}
}
/**
* Get additional callbacks that return data to be included in the telemetry snapshot.
*
* @since 2.8
*
* @return array
*/
public function get_callbacks() {
/**
* Filters the non-default data to be included in the telemetry snapshot.
*
* @since 2.8
*
* @param array $new_callbacks An array of callbacks returning an array of data to be included in the telemetry snapshot. Default empty array.
*/
return apply_filters( 'gform_telemetry_snapshot_data', array() );
}
/**
* Get basic site info for telemetry.
*
* @since 2.8
*
* @return array
*/
public function get_site_basic_info() {
if ( ! function_exists( 'get_plugins' ) ) {
require_once ABSPATH . 'wp-admin/includes/plugin.php';
}
$plugin_list = get_plugins();
$plugins = array();
$active_plugins = get_option( 'active_plugins' );
foreach ( $plugin_list as $key => $plugin ) {
$is_active = in_array( $key, $active_plugins );
$slug = substr( $key, 0, strpos( $key, '/' ) );
if ( empty( $slug ) ) {
$slug = str_replace( '.php', '', $key );
}
$plugins[] = array(
'name' => str_replace( 'phpinfo()', 'PHP Info', $plugin['Name'] ),
'slug' => $slug,
'version' => $plugin['Version'],
'is_active' => $is_active,
);
}
$theme = wp_get_theme();
$theme_name = $theme->get( 'Name' );
$theme_uri = $theme->get( 'ThemeURI' );
$theme_version = $theme->get( 'Version' );
$theme_author = $theme->get( 'Author' );
$theme_author_uri = $theme->get( 'AuthorURI' );
$form_counts = GFFormsModel::get_form_count();
$active_count = $form_counts['active'];
$inactive_count = $form_counts['inactive'];
$fc = abs( $active_count ) + abs( $inactive_count );
$entry_count = GFFormsModel::get_entry_count_all_forms( 'active' );
$meta_counts = GFFormsModel::get_entry_meta_counts();
$im = is_multisite();
$lang = get_locale();
$db = GFCommon::get_dbms_type();
$post = array(
'key' => GFCommon::get_key(),
'wp_version' => get_bloginfo( 'version' ),
'php_version' => phpversion(),
'mysql_version' => GFCommon::get_db_version(),
'plugins' => $plugins,
'theme_name' => $theme_name,
'theme_uri' => $theme_uri,
'theme_version' => $theme_version,
'theme_author' => $theme_author,
'theme_author_uri' => $theme_author_uri,
'is_multisite' => $im,
'total_forms' => $fc,
'total_entries' => $entry_count,
'emails_sent' => GFCommon::get_emails_sent(),
'api_calls' => GFCommon::get_api_calls(),
'entry_meta_count' => $meta_counts['meta'],
'entry_details_count' => $meta_counts['details'],
'entry_notes_count' => $meta_counts['notes'],
'lang' => $lang,
'db' => $db,
);
$installation_telemetry = array(
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_AUTO_UPDATE,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_CURRENCY,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_DATA_COLLECTION,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_EMAIL,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_FORM_TYPES,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_FORM_TYPES_OTHER,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_HIDE_LICENSE,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_ORGANIZATION,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_ORGANIZATION_OTHER,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_SERVICES,
GF_Setup_Wizard_Endpoint_Save_Prefs::PARAM_SERVICES_OTHER,
);
$wizard_endpoint = GFForms::get_service_container()->get( GF_Setup_Wizard_Service_Provider::SAVE_PREFS_ENDPOINT );
foreach ( $installation_telemetry as $telem ) {
$post[ $telem ] = $wizard_endpoint->get_value( $telem );
}
return $post;
}
/**
* Collect the data from the Gravity Forms settings page
*
* @since 2.8.3
*
* @return array
*/
public function get_gf_settings() {
if ( ! $this->data_collection ) {
return array();
}
$gform_settings = array();
$settings_keys = array(
'gform_enable_logging',
'rg_gforms_default_theme',
'gform_enable_toolbar_menu',
'gform_enable_noconflict',
);
foreach ( $settings_keys as $key ) {
$gform_settings[ $key ] = get_option( $key );
}
return $gform_settings;
}
/**
* Count the number of forms with legacy mode enabled.
*
* @since 2.8.3
*
* @return array
*/
public function get_legacy_forms() {
if ( ! $this->data_collection ) {
return array();
}
$legacy_forms = 0;
$forms = GFFormsModel::get_forms();
foreach ( $forms as $form ) {
// if form has legacy mode enabled, add it to the total
if ( GFCommon::is_legacy_markup_enabled( $form->id ) ) {
$legacy_forms++;
}
}
return array( 'legacy_forms' => $legacy_forms );
}
/**
* Stores the response from the version.php endpoint, to be used by the license service.
*
* @since 2.8
*
* @param array $response Raw response from the API endpoint.
*/
public static function data_sent( $response ) {
$version_info = array(
'is_valid_key' => '1',
'version' => '',
'url' => '',
'is_error' => '1',
);
if ( is_wp_error( $response ) || rgars( $response, 'response/code' ) != 200 ) {
$version_info['timestamp'] = time();
return $version_info;
}
$decoded = json_decode( $response['body'], true );
if ( empty( $decoded ) ) {
$version_info['timestamp'] = time();
return $version_info;
}
$decoded['timestamp'] = time();
update_option( 'gform_version_info', $decoded, false );
\GFCommon::log_debug( __METHOD__ . sprintf( '(): Version info cached.' ) );
}
}