Completed
Push — add/beta-plugin ( d1204d )
by
unknown
189:46 queued 179:34
created

get_latest_prerelease()   B

Complexity

Conditions 8
Paths 10

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
nc 10
nop 0
dl 0
loc 25
rs 8.4444
c 0
b 0
f 0
1
<?php
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	exit;
5
}
6
7
/**
8
 * Allow the Jetpack Beta to autoupdate itself.
9
 */
10
class Jetpack_Beta_Autoupdate_Self {
11
	protected static $_instance = null;
12
13
	const TRANSIENT_NAME = 'JETPACK_BETA_LATEST_TAG';
14
15
	/**
16
	 * Main Instance
17
	 */
18
	public static function instance() {
19
		return self::$_instance = is_null( self::$_instance ) ? new self() : self::$_instance;
20
	}
21
22
	/**
23
	 * Constructor
24
	 */
25
	public function __construct() {
26
		if ( ! empty( self::$_instance ) ) {
27
			return;
28
		}
29
30
		$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...
31
			'plugin_file'        => JPBETA__PLUGIN_FOLDER . '/jetpack-beta.php',
32
			'slug'               => JPBETA__PLUGIN_FOLDER,
33
			'proper_folder_name' => JPBETA__PLUGIN_FOLDER,
34
			'api_url'            => 'https://api.github.com/repos/Automattic/jetpack-beta',
35
			'github_url'         => 'https://github.com/Automattic/jetpack-beta',
36
			'requires'           => '4.7',
37
			'tested'             => '4.7'
38
		);
39
40
41
42
		add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'api_check' ) );
43
		add_filter( 'plugins_api', array( $this, 'get_plugin_info' ), 10, 3 );
44
		add_filter( 'upgrader_source_selection', array( $this, 'upgrader_source_selection' ), 10, 3 );
45
46
	}
47
48
	public function set_update_args() {
49
		$plugin_data                    = $this->get_plugin_data();
50
		$this->config[ 'plugin_name' ]  = $plugin_data['Name'];
51
		$this->config[ 'version' ]      = $plugin_data['Version'];
52
		$this->config[ 'author' ]       = $plugin_data['Author'];
53
		$this->config[ 'homepage' ]     = $plugin_data['PluginURI'];
54
		$this->config[ 'new_version' ]  = $this->get_latest_prerelease();
55
		$this->config[ 'last_updated' ] = $this->get_date();
56
		$this->config[ 'description' ]  = $this->get_description();
57
		$this->config[ 'zip_url' ]      = 'https://github.com/Automattic/jetpack-beta/zipball/' . $this->config[ 'new_version' ];
58
	}
59
60
	public function get_latest_prerelease() {
61
		$tagged_version = get_site_transient( self::TRANSIENT_NAME );
62
		if ( $this->overrule_transients() || empty( $tagged_version ) ) {
63
			$raw_response = wp_remote_get( trailingslashit( $this->config['api_url'] ) . 'releases' );
64
			if ( is_wp_error( $raw_response ) ) {
65
				return false;
66
			}
67
			$releases       = json_decode( $raw_response['body'] );
68
			$tagged_version = false;
69
			if ( is_array( $releases ) ) {
70
				foreach ( $releases as $release ) {
71
					// Since 2.2, So that we don't have to maker the Jetpack Beta 2.0.3 as prerelease
72
					if ( ! $release->prerelease ) {
73
						$tagged_version = $release->tag_name;
74
						break;
75
					}
76
				}
77
			}
78
			// refresh every 6 hours
79
			if ( ! empty( $tagged_version ) ) {
80
				set_site_transient( self::TRANSIENT_NAME, $tagged_version, 60*60*6 );
81
			}
82
		}
83
		return $tagged_version;
84
	}
85
86
	public function overrule_transients() {
87
		return ( defined( 'Jetpack_Beta_FORCE_UPDATE' ) && Jetpack_Beta_FORCE_UPDATE );
88
	}
89
90
	public function get_github_data() {
91
		if ( ! empty( $this->github_data ) ) {
92
			$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...
93
		} else {
94
			$github_data = get_site_transient( md5( $this->config['slug'] ) . '_github_data' );
95
			if ( $this->overrule_transients() || ( ! isset( $github_data ) || ! $github_data || '' == $github_data ) ) {
96
				$github_data = wp_remote_get( $this->config['api_url'] );
97
				if ( is_wp_error( $github_data ) ) {
98
					return false;
99
				}
100
				$github_data = json_decode( $github_data['body'] );
101
				// refresh every 6 hours
102
				set_site_transient( md5( $this->config['slug'] ) . '_github_data', $github_data, 60*60*6 );
103
			}
104
			// Store the data in this class instance for future calls
105
			$this->github_data = $github_data;
106
		}
107
		return $github_data;
108
	}
109
110
	public function get_date() {
111
		$_date = $this->get_github_data();
112
		return ! empty( $_date->updated_at ) ? date( 'Y-m-d', strtotime( $_date->updated_at ) ) : false;
113
	}
114
115
	public function get_description() {
116
		$_description = $this->get_github_data();
117
		return ! empty( $_description->description ) ? $_description->description : false;
118
	}
119
120
121
	public function get_plugin_data() {
122
		return get_plugin_data( WP_PLUGIN_DIR . '/' . $this->config['plugin_file'] );
123
	}
124
125
	public function has_never_version() {
126
		if ( ! isset( $this->config['new_version'] ) ) {
127
			$this->set_update_args();
128
		}
129
		return version_compare( $this->config['new_version'], $this->config['version'], '>' );
130
131
	}
132
133
	public function api_check( $transient ) {
134
		// Check if the transient contains the 'checked' information
135
		// If not, just return its value without hacking it
136
		if ( ! isset( $transient->no_update ) ) {
137
			return $transient;
138
		}
139
		// get the latest version
140
		delete_site_transient( self::TRANSIENT_NAME );
141
142
		if ( $this->has_never_version() ) {
143
			$response              = new stdClass;
144
			$response->plugin      = $this->config['slug'];
145
			$response->new_version = $this->config['new_version'];
146
			$response->slug        = $this->config['slug'];
147
			$response->url         = $this->config['github_url'];
148
			$response->package     = $this->config['zip_url'];
149
			// If response is false, don't alter the transient
150
			if ( false !== $response ) {
151
				$transient->response[ $this->config['plugin_file'] ] = $response;
152
			}
153
		}
154
		return $transient;
155
	}
156
157
	public function get_plugin_info( $false, $action, $response ) {
158
		// Check if this call API is for the right plugin
159
		if ( ! isset( $response->slug ) || $response->slug != $this->config['slug'] ) {
160
			return false;
161
		}
162
		// Update tags
163
		$this->set_update_args();
164
		$response->slug          = $this->config['slug'];
165
		$response->plugin        = $this->config['slug'];
166
		$response->name          = $this->config['plugin_name'];
167
		$response->plugin_name   = $this->config['plugin_name'];
168
		$response->version       = $this->config['new_version'];
169
		$response->author        = $this->config['author'];
170
		$response->homepage      = $this->config['homepage'];
171
		$response->requires      = $this->config['requires'];
172
		$response->tested        = $this->config['tested'];
173
		$response->downloaded    = 0;
174
		$response->last_updated  = $this->config['last_updated'];
175
		$response->sections      = array( 'description' => $this->config['description'] );
176
		$response->download_link = $this->config['zip_url'];
177
		return $response;
178
	}
179
180
	public function upgrader_source_selection( $source, $remote_source, $upgrader ) {
181
		global $wp_filesystem;
182
		if ( strstr( $source, '/Automattic-jetpack-beta-' ) ) {
183
			$corrected_source = trailingslashit( $remote_source ) . trailingslashit( $this->config[ 'proper_folder_name' ] );
184
			if ( $wp_filesystem->move( $source, $corrected_source, true ) ) {
185
				return $corrected_source;
186
			} else {
187
				return new WP_Error();
188
			}
189
		}
190
		return $source;
191
	}
192
}
193