Completed
Push — master ( 47861b...8b73ea )
by Stephanie
04:23
created

FrmAddon::manually_queue_update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
if ( ! defined( 'ABSPATH' ) ) {
4
	die( 'You are not allowed to call this page directly.' );
5
}
6
7
class FrmAddon {
8
	public $store_url = 'https://formidablepro.com';
9
	public $download_id;
10
	public $plugin_file;
11
	public $plugin_folder;
12
	public $plugin_name;
13
	public $plugin_slug;
14
	public $option_name;
15
	public $version;
16
	public $author = 'Strategy11';
17
	private $license;
18
19
	public function __construct() {
20
21
		if ( empty( $this->plugin_slug ) ) {
22
			$this->plugin_slug = preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->plugin_name ) ) );
23
		}
24
		if ( empty( $this->option_name ) ) {
25
			$this->option_name = 'edd_' . $this->plugin_slug . '_license_';
26
		}
27
28
		$this->plugin_folder = plugin_basename( $this->plugin_file );
29
		$this->license = $this->get_license();
30
31
		add_filter( 'frm_installed_addons', array( &$this, 'insert_installed_addon' ) );
32
		$this->edd_plugin_updater();
33
	}
34
35
	public static function load_hooks() {
36
		add_filter( 'frm_include_addon_page', '__return_true' );
37
		//new static();
38
	}
39
40
	public function insert_installed_addon( $plugins ) {
41
		$plugins[ $this->plugin_slug ] = $this;
42
		return $plugins;
43
	}
44
45
	public static function get_addon( $plugin_slug ) {
46
		$plugins = apply_filters( 'frm_installed_addons', array() );
47
		$plugin = false;
48
		if ( isset( $plugins[ $plugin_slug ] ) ) {
49
			$plugin = $plugins[ $plugin_slug ];
50
		}
51
		return $plugin;
52
	}
53
54
	public function edd_plugin_updater() {
55
56
		$license = $this->license;
57
58
		if ( empty( $license ) ) {
59
			add_action( 'after_plugin_row_' . plugin_basename( $this->plugin_file ), array( $this, 'show_license_message' ), 10, 2 );
60
		} else {
61
			if ( ! class_exists('EDD_SL_Plugin_Updater') ) {
62
				include( dirname( __FILE__ ) . '/EDD_SL_Plugin_Updater.php' );
63
			}
64
65
			// setup the updater
66
			$api_data = array(
67
				'version' 	=> $this->version,
68
				'license' 	=> $license,
69
				'author' 	=> $this->author,
70
			);
71
			if ( is_numeric( $this->download_id ) ) {
72
				$api_data['item_id'] = $this->download_id;
73
			}
74
75
			new EDD_SL_Plugin_Updater( $this->store_url, $this->plugin_file, $api_data );
76
77
			add_filter( 'site_transient_update_plugins', array( &$this, 'clear_expired_download' ) );
78
		}
79
	}
80
81
	public function get_license() {
82
		return trim( get_option( $this->option_name . 'key' ) );
83
	}
84
85
	public function set_license( $license ) {
86
		update_option( $this->option_name . 'key', $license );
87
	}
88
89
	public function clear_license() {
90
		delete_option( $this->option_name . 'active' );
91
		delete_option( $this->option_name . 'key' );
92
	}
93
94
	public function set_active( $is_active ) {
95
		update_option( $this->option_name . 'active', $is_active );
96
	}
97
98
	public function show_license_message( $file, $plugin ) {
99
		$wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
100
		echo '<tr class="plugin-update-tr active"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message">';
101
		echo sprintf( __( 'Your %1$s license key is missing. Please add it on the %2$slicenses page%3$s.', 'formidable' ), $this->plugin_name, '<a href="' . esc_url( admin_url('admin.php?page=formidable-settings&t=licenses_settings' ) ) . '">', '</a>' );
0 ignored issues
show
introduced by
Expected a sanitizing function (see Codex for 'Data Validation'), but instead saw 'sprintf'
Loading history...
102
		$id = sanitize_title( $plugin['Name'] );
103
		echo '<script type="text/javascript">var d = document.getElementById("' . esc_attr( $id ) . '");if ( d !== null ){ d.className = d.className + " update"; }</script>';
104
		echo '</div></td></tr>';
105
	}
106
107
	public function clear_expired_download( $transient ) {
108
		if ( ! is_object($transient) ) {
109
			return $transient;
110
		}
111
112
		if ( $this->is_current_version( $transient ) ) {
113
			//make sure it doesn't show there is an update if plugin is up-to-date
114
			if ( isset( $transient->response[ $this->plugin_folder ] ) ) {
115
				unset( $transient->response[ $this->plugin_folder ] );
116
			}
117
		} else if ( isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) ) {
118
			$cache_key = 'edd_plugin_' . md5( sanitize_key( $this->license . $this->version ) . '_get_version' );
119
			$version_info = get_transient( $cache_key );
120
			if ( $version_info !== false ) {
1 ignored issue
show
introduced by
Found "!== false". Use Yoda Condition checks, you must
Loading history...
121
				$transient->response[ $this->plugin_folder ] = $version_info;
122
			} else if ( ! $this->has_been_cleared() ) {
123
				// if the transient has expired, clear the update and trigger it again
124
				$this->cleared_plugins();
125
				$this->manually_queue_update();
126
				unset( $transient->response[ $this->plugin_folder ] );
127
			}
128
		}
129
130
		return $transient;
131
	}
132
133
	function is_current_version( $transient ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
134
		if ( empty( $transient->checked ) || ! isset( $transient->checked[ $this->plugin_folder ] ) ) {
135
			return false;
136
		}
137
138
		$response = ! isset( $transient->response ) || empty( $transient->response );
139
		if ( $response ) {
140
			return true;
141
		}
142
143
		return isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) && $transient->checked[ $this->plugin_folder ] == $transient->response[ $this->plugin_folder ]->new_version;
144
	}
145
146
	function has_been_cleared() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
147
		global $frm_vars;
148
		return isset( $frm_vars['cleared'] ) ? $frm_vars['cleared'] : false;
149
	}
150
151
	function cleared_plugins() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
152
		global $frm_vars;
153
		$frm_vars['cleared'] = true;
154
	}
155
156
	public static function activate() {
157
	 	check_ajax_referer( 'frm_ajax', 'nonce' );
158
159
		if ( ! isset( $_POST['license'] ) || empty( $_POST['license'] ) ) {
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
160
			wp_die( __( 'Oops! You forgot to enter your license number.', 'formidable' ) );
161
		}
162
163
		$license = stripslashes( sanitize_text_field( $_POST['license'] ) );
1 ignored issue
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
164
		$plugin_slug = sanitize_text_field( $_POST['plugin'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
165
		$this_plugin = self::get_addon( $plugin_slug );
166
		$this_plugin->set_license( $license );
167
168
		$response = array( 'success' => false, 'message' => '' );
169
		try {
170
			$license_data = $this_plugin->send_mothership_request( 'activate_license', $license );
171
172
			// $license_data->license will be either "valid" or "invalid"
173
			$is_valid = 'invalid';
174
			if ( is_array( $license_data ) ) {
175
				if ( $license_data['license'] == 'valid' ) {
176
					$is_valid = $license_data['license'];
177
					$response['message'] = __( 'Your license has been activated. Enjoy!', 'formidable' );
178
					$response['success'] = true;
179
				} else if ( $license_data['license'] == 'invalid' ) {
180
					$response['message'] = __( 'That license is invalid', 'formidable' );
181
				}
182
			} else if ( $license_data == 'expired' ) {
183
				$response['message'] = __( 'That license is expired', 'formidable' );
184
			} else if ( $license_data == 'no_activations_left' ) {
185
				$response['message'] = __( 'That license has been used too many times', 'formidable' );
186
			} else if ( $license_data == 'invalid_item_id' ) {
187
				$response['message'] = __( 'Oops! That is the wrong license number for this plugin.', 'formidable' );
188
			} else if ( $license_data == 'missing' ) {
189
				$response['message'] = __( 'That license is invalid', 'formidable' );
190
			} else {
191
				$response['message'] = FrmAppHelper::kses( $license_data, array( 'a' ) );
192
			}
193
194
			$this_plugin->set_active( $is_valid );
195
		} catch ( Exception $e ) {
196
			$response['message'] = $e->getMessage();
197
		}
198
199
		echo json_encode( $response );
200
		wp_die();
201
	}
202
203
	public static function deactivate() {
204
		check_ajax_referer( 'frm_ajax', 'nonce' );
205
206
		$license = stripslashes( sanitize_text_field( $_POST['license'] ) );
0 ignored issues
show
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
207
		$plugin_slug = sanitize_text_field( $_POST['plugin'] );
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-validated input variable: $_POST
Loading history...
208
		$this_plugin = self::get_addon( $plugin_slug );
209
210
		$response = array( 'success' => false, 'message' => '' );
211
		try {
212
			// $license_data->license will be either "deactivated" or "failed"
213
			$license_data = $this_plugin->send_mothership_request( 'deactivate_license', $license );
214
			if ( is_array( $license_data ) && $license_data['license'] == 'deactivated' ) {
215
				$response['success'] = true;
216
				$response['message'] = __( 'That license was removed successfully', 'helpdesk' );
217
			} else {
218
				$response['message'] = __( 'There was an error deactivating your license.', 'formidable' );
219
			}
220
		} catch ( Exception $e ) {
221
			$response['message'] = $e->getMessage();
222
		}
223
224
		$this_plugin->clear_license();
225
226
		echo json_encode( $response );
227
		wp_die();
228
	}
229
230
	public function send_mothership_request( $action, $license ) {
231
		$api_params = array(
232
			'edd_action' => $action,
233
			'license'    => $license,
234
			'item_name'  => urlencode( $this->plugin_name ),
235
			'url'        => home_url(),
236
		);
237
		if ( is_numeric( $this->download_id ) ) {
238
			$api_params['item_id'] = absint( $this->download_id );
239
		}
240
241
		$arg_array = array(
242
			'body'      => $api_params,
243
			'timeout'   => 15,
244
			'sslverify' => false,
245
			'user-agent' => $this->plugin_slug . '/' . $this->version . '; ' . get_bloginfo( 'url' ),
246
		);
247
248
		$resp = wp_remote_post( $this->store_url, $arg_array );
249
		$body = wp_remote_retrieve_body( $resp );
250
251
		$message = __( 'Your License Key was invalid', 'formidable' );
252
		if ( is_wp_error( $resp ) ) {
253
			$message = sprintf( __( 'You had an error communicating with Formidable Pro\'s API. %1$sClick here%2$s for more information.', 'formidable' ), '<a href="http://formidablepro.com/knowledgebase/why-cant-i-activate-formidable-pro/" target="_blank">', '</a>');
254
			if ( is_wp_error( $resp ) ) {
255
				$message .= ' '. $resp->get_error_message();
256
			}
257
		} else if ( $body == 'error' || is_wp_error( $body ) ) {
258
			$message = __( 'You had an HTTP error connecting to Formidable Pro\'s API', 'formidable' );
259
		} else {
260
			$json_res = json_decode( $body, true );
261
			if ( null !== $json_res ) {
262
				if ( is_array( $json_res ) && isset( $json_res['error'] ) ) {
263
					$message = $json_res['error'];
264
				} else {
265
					$message = $json_res;
266
				}
267
			} else if ( isset( $resp['response'] ) && isset( $resp['response']['code'] ) ) {
268
				$message = sprintf( __( 'There was a %1$s error: %2$s', 'formidable' ), $resp['response']['code'], $resp['response']['message'] .' '. $resp['body'] );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not '$resp'
Loading history...
269
			}
270
		}
271
272
		return $message;
273
	}
274
275
    function manually_queue_update(){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
276
        set_site_transient( 'update_plugins', null );
277
    }
278
}
279