Completed
Push — add/jetpack-assistant-ui ( a6f776...33ce41 )
by Jeremy
202:03 queued 191:10
created

Jetpack_Beta_Autoupdate_Self::get_plugin_data()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Primary class file for the Jetpack Beta plugin.
4
 *
5
 * @package Jetpack Beta
6
 */
7
8
// Check that the file is not accessed directly.
9
if ( ! defined( 'ABSPATH' ) ) {
10
	exit;
11
}
12
13
/**
14
 * Allow the Jetpack Beta to autoupdate itself.
15
 */
16
class Jetpack_Beta_Autoupdate_Self {
17
18
	/**
19
	 * Singleton Jetpack_Beta class instance.
20
	 *
21
	 * @var Jetpack_Beta_Autoupdate_Self
22
	 */
23
	protected static $instance = null;
24
25
	const TRANSIENT_NAME = 'JETPACK_BETA_LATEST_TAG';
26
27
	/**
28
	 * Main Instance
29
	 */
30
	public static function instance() {
31
		if ( null === self::$instance ) {
32
			self::$instance = new self();
33
		}
34
35
		return self::$instance;
36
	}
37
38
	/**
39
	 * Constructor
40
	 */
41
	public function __construct() {
42
		if ( ! empty( self::$instance ) ) {
43
			return;
44
		}
45
46
		$this->config = array(
0 ignored issues
show
Bug introduced by
The property config does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
47
			'plugin_file'        => JPBETA__PLUGIN_FOLDER . '/jetpack-beta.php',
48
			'slug'               => JPBETA__PLUGIN_FOLDER,
49
			'proper_folder_name' => JPBETA__PLUGIN_FOLDER,
50
			'api_url'            => 'https://api.github.com/repos/Automattic/jetpack-beta',
51
			'github_url'         => 'https://github.com/Automattic/jetpack-beta',
52
			'requires'           => '4.7',
53
			'tested'             => '4.7',
54
		);
55
56
		add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'api_check' ) );
57
		add_filter( 'plugins_api', array( $this, 'get_plugin_info' ), 10, 3 );
58
		add_filter( 'upgrader_source_selection', array( $this, 'upgrader_source_selection' ), 10, 3 );
59
60
	}
61
62
	/** Set update arguments */
63
	public function set_update_args() {
64
		$plugin_data                  = $this->get_plugin_data();
65
		$this->config['plugin_name']  = $plugin_data['Name'];
66
		$this->config['version']      = $plugin_data['Version'];
67
		$this->config['author']       = $plugin_data['Author'];
68
		$this->config['homepage']     = $plugin_data['PluginURI'];
69
		$this->config['new_version']  = $this->get_latest_prerelease();
70
		$this->config['last_updated'] = $this->get_date();
71
		$this->config['description']  = $this->get_description();
72
		$this->config['zip_url']      = 'https://github.com/Automattic/jetpack-beta/zipball/' . $this->config['new_version'];
73
	}
74
75
	/** Check for latest pre-release plugin every six hours and update */
76
	public function get_latest_prerelease() {
77
		$tagged_version = get_site_transient( self::TRANSIENT_NAME );
78
		if ( $this->overrule_transients() || empty( $tagged_version ) ) {
79
			$raw_response = wp_remote_get( trailingslashit( $this->config['api_url'] ) . 'releases' );
80
			if ( is_wp_error( $raw_response ) ) {
81
				return false;
82
			}
83
			$releases       = json_decode( $raw_response['body'] );
84
			$tagged_version = false;
85
			if ( is_array( $releases ) ) {
86
				foreach ( $releases as $release ) {
87
					// Since 2.2, so that we don't have to maker the Jetpack Beta 2.0.3 as prerelease.
88
					if ( ! $release->prerelease ) {
89
						$tagged_version = $release->tag_name;
90
						break;
91
					}
92
				}
93
			}
94
			// Refresh every 6 hours.
95
			if ( ! empty( $tagged_version ) ) {
96
				set_site_transient( self::TRANSIENT_NAME, $tagged_version, 60 * 60 * 6 );
97
			}
98
		}
99
		return $tagged_version;
100
	}
101
102
	/** Override transients to force update */
103
	public function overrule_transients() {
104
		return ( defined( 'Jetpack_Beta_FORCE_UPDATE' ) && Jetpack_Beta_FORCE_UPDATE );
105
	}
106
107
	/** Get update data from Github */
108
	public function get_github_data() {
109
		if ( ! empty( $this->github_data ) ) {
110
			$github_data = $this->github_data;
0 ignored issues
show
Bug introduced by
The property github_data does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
111
		} else {
112
			$github_data = get_site_transient( md5( $this->config['slug'] ) . '_github_data' );
113
			if ( $this->overrule_transients() || ( ! isset( $github_data ) || ! $github_data || '' === $github_data ) ) {
114
				$github_data = wp_remote_get( $this->config['api_url'] );
115
				if ( is_wp_error( $github_data ) ) {
116
					return false;
117
				}
118
				$github_data = json_decode( $github_data['body'] );
119
				// Refresh every 6 hours.
120
				set_site_transient( md5( $this->config['slug'] ) . '_github_data', $github_data, 60 * 60 * 6 );
121
			}
122
			// Store the data in this class instance for future calls.
123
			$this->github_data = $github_data;
124
		}
125
		return $github_data;
126
	}
127
128
	/** Get date of update in GMT*/
129
	public function get_date() {
130
		$_date = $this->get_github_data();
131
		return ! empty( $_date->updated_at ) ? gmdate( 'Y-m-d', strtotime( $_date->updated_at ) ) : false;
132
	}
133
134
	/** Get latest update's description */
135
	public function get_description() {
136
		$_description = $this->get_github_data();
137
		return ! empty( $_description->description ) ? $_description->description : false;
138
	}
139
140
	/** Get plugin update data */
141
	public function get_plugin_data() {
142
		return get_plugin_data( WP_PLUGIN_DIR . '/' . $this->config['plugin_file'] );
143
	}
144
145
	/** Check if there's a newer version */
146
	public function has_never_version() {
147
		if ( ! isset( $this->config['new_version'] ) ) {
148
			$this->set_update_args();
149
		}
150
		return version_compare( $this->config['new_version'], $this->config['version'], '>' );
151
152
	}
153
154
	/**
155
	 * Check the latest transient data and update if necessary.
156
	 *
157
	 * @param string $transient - the transient we're checking.
158
	 */
159
	public function api_check( $transient ) {
160
		// Check if the transient contains the 'checked' information.
161
		// If not, just return its value without hacking it.
162
		if ( ! isset( $transient->no_update ) ) {
163
			return $transient;
164
		}
165
		// Get the latest version.
166
		delete_site_transient( self::TRANSIENT_NAME );
167
168
		if ( $this->has_never_version() ) {
169
			$response              = new stdClass();
170
			$response->plugin      = $this->config['slug'];
171
			$response->new_version = $this->config['new_version'];
172
			$response->slug        = $this->config['slug'];
173
			$response->url         = $this->config['github_url'];
174
			$response->package     = $this->config['zip_url'];
175
			// If response is false, don't alter the transient.
176
			if ( false !== $response ) {
177
				$transient->response[ $this->config['plugin_file'] ] = $response;
178
			}
179
		}
180
		return $transient;
181
	}
182
183
	/**
184
	 * Get latest plugin information
185
	 *
186
	 * @param string $false Result from plugins_api.
187
	 * @param string $action The type of information being requested from the Plugin Installation API.
188
	 * @param object $response The response from plugins_api.
189
	 */
190
	public function get_plugin_info( $false, $action, $response ) {
191
		// Check if this call API is for the right plugin.
192
		if ( ! isset( $response->slug ) || $response->slug !== $this->config['slug'] ) {
193
			return false;
194
		}
195
		// Update tags.
196
		$this->set_update_args();
197
		$response->slug          = $this->config['slug'];
198
		$response->plugin        = $this->config['slug'];
199
		$response->name          = $this->config['plugin_name'];
200
		$response->plugin_name   = $this->config['plugin_name'];
201
		$response->version       = $this->config['new_version'];
202
		$response->author        = $this->config['author'];
203
		$response->homepage      = $this->config['homepage'];
204
		$response->requires      = $this->config['requires'];
205
		$response->tested        = $this->config['tested'];
206
		$response->downloaded    = 0;
207
		$response->last_updated  = $this->config['last_updated'];
208
		$response->sections      = array( 'description' => $this->config['description'] );
209
		$response->download_link = $this->config['zip_url'];
210
		return $response;
211
	}
212
213
	/**
214
	 * Updates the source file location for the upgrade package.
215
	 *
216
	 * @param string $source - File source location..
217
	 * @param string $remote_source - Remote file source location.
218
	 */
219
	public function upgrader_source_selection( $source, $remote_source ) {
220
		global $wp_filesystem;
221
		if ( strstr( $source, '/Automattic-jetpack-beta-' ) ) {
222
			$corrected_source = trailingslashit( $remote_source ) . trailingslashit( $this->config['proper_folder_name'] );
223
			if ( $wp_filesystem->move( $source, $corrected_source, true ) ) {
224
				return $corrected_source;
225
			} else {
226
				return new WP_Error();
227
			}
228
		}
229
		return $source;
230
	}
231
}
232