Completed
Pull Request — add/heartbeat-package (#16012)
by
unknown
42:29 queued 22:45
created

class.jetpack-heartbeat.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
use Automattic\Jetpack\Connection\Manager;
4
5
class Jetpack_Heartbeat {
6
7
	/**
8
	 * Holds the singleton instance of this class
9
	 *
10
	 * @since 2.3.3
11
	 * @var Jetpack_Heartbeat
12
	 */
13
	private static $instance = false;
14
15
	private $cron_name = 'jetpack_v2_heartbeat';
16
17
	/**
18
	 * Singleton
19
	 *
20
	 * @since 2.3.3
21
	 * @static
22
	 * @return Jetpack_Heartbeat
23
	 */
24
	public static function init() {
25
		if ( ! self::$instance ) {
26
			self::$instance = new Jetpack_Heartbeat();
27
		}
28
29
		return self::$instance;
30
	}
31
32
	/**
33
	 * Constructor for singleton
34
	 *
35
	 * @since 2.3.3
36
	 * @return Jetpack_Heartbeat
37
	 */
38 View Code Duplication
	private function __construct() {
39
		if ( ! Jetpack::is_active() ) {
40
			return;
41
		}
42
43
		// Schedule the task
44
		add_action( $this->cron_name, array( $this, 'cron_exec' ) );
45
46
		if ( ! wp_next_scheduled( $this->cron_name ) ) {
47
			// Deal with the old pre-3.0 weekly one.
48
			if ( $timestamp = wp_next_scheduled( 'jetpack_heartbeat' ) ) {
49
				wp_unschedule_event( $timestamp, 'jetpack_heartbeat' );
50
			}
51
52
			wp_schedule_event( time(), 'daily', $this->cron_name );
53
		}
54
55
		add_filter( 'jetpack_xmlrpc_methods', array( __CLASS__, 'jetpack_xmlrpc_methods' ) );
56
	}
57
58
	/**
59
	 * Method that gets executed on the wp-cron call
60
	 *
61
	 * @since 2.3.3
62
	 * @global string $wp_version
63
	 */
64 View Code Duplication
	public function cron_exec() {
65
66
		$jetpack = Jetpack::init();
67
68
		/*
69
		 * This should run daily.  Figuring in for variances in
70
		 * WP_CRON, don't let it run more than every 23 hours at most.
71
		 *
72
		 * i.e. if it ran less than 23 hours ago, fail out.
73
		 */
74
		$last = (int) Jetpack_Options::get_option( 'last_heartbeat' );
75
		if ( $last && ( $last + DAY_IN_SECONDS - HOUR_IN_SECONDS > time() ) ) {
76
			return;
77
		}
78
79
		/*
80
		 * Check for an identity crisis
81
		 *
82
		 * If one exists:
83
		 * - Bump stat for ID crisis
84
		 * - Email site admin about potential ID crisis
85
		 */
86
87
		// Coming Soon!
88
89
		foreach ( self::generate_stats_array( 'v2-' ) as $key => $value ) {
90
			$jetpack->stat( $key, $value );
91
		}
92
93
		Jetpack_Options::update_option( 'last_heartbeat', time() );
94
95
		$jetpack->do_stats( 'server_side' );
96
97
		/**
98
		 * Fires when we synchronize all registered options on heartbeat.
99
		 *
100
		 * @since 3.3.0
101
		 */
102
		do_action( 'jetpack_heartbeat' );
103
	}
104
105
	/**
106
	 * Generates heartbeat stats data.
107
	 *
108
	 * @param string $prefix Prefix to add before stats identifier.
109
	 *
110
	 * @return array The stats array.
111
	 */
112
	public static function generate_stats_array( $prefix = '' ) {
113
		$return = array();
114
115
		$return[ "{$prefix}version" ]        = JETPACK__VERSION;
116
		$return[ "{$prefix}wp-version" ]     = get_bloginfo( 'version' );
117
		$return[ "{$prefix}php-version" ]    = PHP_VERSION;
118
		$return[ "{$prefix}branch" ]         = floatval( JETPACK__VERSION );
119
		$return[ "{$prefix}wp-branch" ]      = floatval( get_bloginfo( 'version' ) );
120
		$return[ "{$prefix}php-branch" ]     = floatval( PHP_VERSION );
121
		$return[ "{$prefix}public" ]         = Jetpack_Options::get_option( 'public' );
122
		$return[ "{$prefix}ssl" ]            = Jetpack::permit_ssl();
123
		$return[ "{$prefix}is-https" ]       = is_ssl() ? 'https' : 'http';
124
		$return[ "{$prefix}language" ]       = get_bloginfo( 'language' );
125
		$return[ "{$prefix}charset" ]        = get_bloginfo( 'charset' );
126
		$return[ "{$prefix}is-multisite" ]   = is_multisite() ? 'multisite' : 'singlesite';
127
		$return[ "{$prefix}identitycrisis" ] = Jetpack::check_identity_crisis() ? 'yes' : 'no';
128
		$return[ "{$prefix}plugins" ]        = implode( ',', Jetpack::get_active_plugins() );
129
		if ( function_exists( 'get_mu_plugins' ) ) {
130
			$return[ "{$prefix}mu-plugins" ] = implode( ',', array_keys( get_mu_plugins() ) );
131
		}
132
		$return[ "{$prefix}manage-enabled" ] = true;
133
134
		$xmlrpc_errors = Jetpack_Options::get_option( 'xmlrpc_errors', array() );
135
		if ( $xmlrpc_errors ) {
136
			$return[ "{$prefix}xmlrpc-errors" ] = implode( ',', array_keys( $xmlrpc_errors ) );
137
			Jetpack_Options::delete_option( 'xmlrpc_errors' );
138
		}
139
140
		// Missing the connection owner?
141
		$connection_manager                 = new Manager();
142
		$return[ "{$prefix}missing-owner" ] = $connection_manager->is_missing_connection_owner();
143
144
		// is-multi-network can have three values, `single-site`, `single-network`, and `multi-network`.
145
		$return[ "{$prefix}is-multi-network" ] = 'single-site';
146
		if ( is_multisite() ) {
147
			$return[ "{$prefix}is-multi-network" ] = Jetpack::is_multi_network() ? 'multi-network' : 'single-network';
148
		}
149
150
		if ( ! empty( $_SERVER['SERVER_ADDR'] ) || ! empty( $_SERVER['LOCAL_ADDR'] ) ) {
151
			$ip     = ! empty( $_SERVER['SERVER_ADDR'] ) ? $_SERVER['SERVER_ADDR'] : $_SERVER['LOCAL_ADDR'];
152
			$ip_arr = array_map( 'intval', explode( '.', $ip ) );
153
			if ( 4 === count( $ip_arr ) ) {
154
				$return[ "{$prefix}ip-2-octets" ] = implode( '.', array_slice( $ip_arr, 0, 2 ) );
155
			}
156
		}
157
158
		foreach ( Jetpack::get_available_modules() as $slug ) {
159
			$return[ "{$prefix}module-{$slug}" ] = Jetpack::is_module_active( $slug ) ? 'on' : 'off';
160
		}
161
162
		return $return;
163
	}
164
165
	public static function jetpack_xmlrpc_methods( $methods ) {
166
		$methods['jetpack.getHeartbeatData'] = array( __CLASS__, 'xmlrpc_data_response' );
167
		return $methods;
168
	}
169
170
	public static function xmlrpc_data_response( $params = array() ) {
171
		// The WordPress XML-RPC server sets a default param of array()
172
		// if no argument is passed on the request and the method handlers get this array in $params.
173
		// generate_stats_array() needs a string as first argument.
174
		$params = empty( $params ) ? '' : $params;
175
		return self::generate_stats_array( $params );
0 ignored issues
show
It seems like $params defined by empty($params) ? '' : $params on line 174 can also be of type array; however, Jetpack_Heartbeat::generate_stats_array() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
176
	}
177
178 View Code Duplication
	public function deactivate() {
179
		// Deal with the old pre-3.0 weekly one.
180
		if ( $timestamp = wp_next_scheduled( 'jetpack_heartbeat' ) ) {
181
			wp_unschedule_event( $timestamp, 'jetpack_heartbeat' );
182
		}
183
184
		$timestamp = wp_next_scheduled( $this->cron_name );
185
		wp_unschedule_event( $timestamp, $this->cron_name );
186
	}
187
188
}
189