Version Description
Release Date: July 7th, 2016
-
Bugfixes:
- Fixes compatibiltiy with upcoming Shiny Updates v2 in WP core
-
Enhancements:
- Updates license manager to have more reliable update information including better compatibility with Yoast SEO products.
Download this release
Release Info
Developer | chriscct7 |
Plugin | Google Analytics for WordPress by MonsterInsights |
Version | 5.5.2 |
Comparing to | |
See all releases |
Code changes from version 5.5 to 5.5.2
- admin/class-admin.php +620 -620
- googleanalytics.php +2 -2
- includes/ecommerce-addon-license-fix.php +6 -2
- readme.txt +12 -2
- vendor/yoast/license-manager-2/.gitigore +2 -2
- vendor/yoast/license-manager-2/class-api-request.php +138 -140
- vendor/yoast/license-manager-2/class-license-manager.php +613 -619
- vendor/yoast/license-manager-2/class-plugin-license-manager.php +90 -90
- vendor/yoast/license-manager-2/class-plugin-update-manager.php +93 -102
- vendor/yoast/license-manager-2/class-product.php +292 -228
- vendor/yoast/license-manager-2/class-theme-license-manager.php +51 -53
- vendor/yoast/license-manager-2/class-theme-update-manager.php +141 -149
- vendor/yoast/license-manager-2/class-update-manager.php +216 -211
- vendor/yoast/license-manager/.gitigore +2 -2
- vendor/yoast/license-manager/README.md +21 -21
- vendor/yoast/license-manager/class-api-request.php +140 -140
- vendor/yoast/license-manager/class-license-manager.php +613 -619
- vendor/yoast/license-manager/class-plugin-license-manager.php +90 -90
- vendor/yoast/license-manager/class-plugin-update-manager.php +93 -102
- vendor/yoast/license-manager/class-product.php +292 -228
- vendor/yoast/license-manager/class-theme-license-manager.php +51 -53
- vendor/yoast/license-manager/class-theme-update-manager.php +141 -149
- vendor/yoast/license-manager/class-update-manager.php +216 -211
- vendor/yoast/license-manager/composer.json +28 -28
- vendor/yoast/license-manager/samples/sample-plugin.php +74 -74
- vendor/yoast/license-manager/samples/sample-product.php +22 -22
admin/class-admin.php
CHANGED
@@ -1,620 +1,620 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @package GoogleAnalytics\Admin
|
4 |
-
*/
|
5 |
-
|
6 |
-
/**
|
7 |
-
* This class is for the backend, extendable for all child classes
|
8 |
-
*/
|
9 |
-
class Yoast_GA_Admin extends Yoast_GA_Options {
|
10 |
-
|
11 |
-
/**
|
12 |
-
* Constructor
|
13 |
-
*/
|
14 |
-
public function __construct() {
|
15 |
-
parent::__construct();
|
16 |
-
|
17 |
-
add_action( 'plugins_loaded', array( $this, 'init_ga' ) );
|
18 |
-
|
19 |
-
// Only run admin_init when there is a cron jon executed.
|
20 |
-
$current_page = filter_input( INPUT_GET, 'page' );
|
21 |
-
|
22 |
-
// Only when current page is not 'wpseo'.
|
23 |
-
if ( strpos( $current_page, 'wpseo' ) !== 0 ) {
|
24 |
-
if ( ( $this->is_running_cron() || $this->is_running_ajax() ) || strpos( $current_page, 'yst_ga' ) === 0 ) {
|
25 |
-
add_action( 'admin_init', array( $this, 'init_settings' ) );
|
26 |
-
}
|
27 |
-
}
|
28 |
-
|
29 |
-
add_action( 'admin_init', array( $this, 'system_info' ) );
|
30 |
-
|
31 |
-
}
|
32 |
-
|
33 |
-
/**
|
34 |
-
* Init function when the plugin is loaded
|
35 |
-
*/
|
36 |
-
public function init_ga() {
|
37 |
-
|
38 |
-
new Yoast_GA_Admin_Menu( $this );
|
39 |
-
|
40 |
-
add_filter( 'plugin_action_links_' . plugin_basename( GAWP_FILE ), array( $this, 'add_action_links' ) );
|
41 |
-
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Init function for the settings of GA
|
46 |
-
*/
|
47 |
-
public function init_settings() {
|
48 |
-
$this->options = $this->get_options();
|
49 |
-
|
50 |
-
try {
|
51 |
-
// Loading Google Api Libs with minimal version 2.0.
|
52 |
-
new MI_Api_Libs( '2.0' );
|
53 |
-
}
|
54 |
-
catch( Exception $exception ) {
|
55 |
-
if ( $exception->getMessage() === 'required_version' ) {
|
56 |
-
add_action( 'admin_notices', array( $this, 'set_api_libs_error' ) );
|
57 |
-
}
|
58 |
-
}
|
59 |
-
|
60 |
-
$dashboards = Yoast_GA_Dashboards::get_instance();
|
61 |
-
|
62 |
-
// Listener for reconnecting with google analytics
|
63 |
-
$this->google_analytics_listener();
|
64 |
-
|
65 |
-
if ( is_null( $this->get_tracking_code() ) && $this->show_admin_warning() ) {
|
66 |
-
add_action( 'admin_notices', array( 'Yoast_Google_Analytics_Notice', 'config_warning' ) );
|
67 |
-
}
|
68 |
-
|
69 |
-
// Check if something has went wrong with GA-api calls
|
70 |
-
$has_tracking_code = ( ! is_null( $this->get_tracking_code() ) && empty( $this->options['manual_ua_code_field'] ) );
|
71 |
-
if ( $has_tracking_code && $this->show_admin_dashboard_warning() ) {
|
72 |
-
Yoast_Google_Analytics::get_instance()->check_for_ga_issues();
|
73 |
-
}
|
74 |
-
|
75 |
-
|
76 |
-
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
77 |
-
$this->handle_ga_post_request( $dashboards );
|
78 |
-
}
|
79 |
-
|
80 |
-
/**
|
81 |
-
* Show the notifications if we have one
|
82 |
-
*/
|
83 |
-
$this->show_notification( 'ga_notifications' );
|
84 |
-
|
85 |
-
// Load the Google Analytics Dashboards functionality
|
86 |
-
$dashboards->init_dashboards( $this->get_current_profile() );
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* There is an error with the API libs. So show a notice.
|
91 |
-
*/
|
92 |
-
public function set_api_libs_error() {
|
93 |
-
echo '<div class="error notice"><p>' . __( 'MonsterInsights plugins share some code between them to make your site faster. As a result of that, we need all MonsterInsights plugins to be up to date. We\'ve detected this isn\'t the case, so please update the MonsterInsights plugins that aren\'t up to date yet.', 'google-analytics-for-wordpress' ) . '</p></div>';
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* This function saves the settings in the option field and returns a wp success message on success
|
98 |
-
*
|
99 |
-
* @param array $data
|
100 |
-
*/
|
101 |
-
public function save_settings( $data ) {
|
102 |
-
|
103 |
-
unset( $data['google_auth_code'] );
|
104 |
-
|
105 |
-
foreach ( $data as $key => $value ) {
|
106 |
-
if ( $key != 'return_tab' ) {
|
107 |
-
if ( is_string( $value ) ) {
|
108 |
-
if ( $key === 'custom_code' && ! current_user_can( 'unfiltered_html' ) ) {
|
109 |
-
continue;
|
110 |
-
}
|
111 |
-
else {
|
112 |
-
$value = strip_tags( $value );
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
$this->options[ $key ] = $value;
|
117 |
-
}
|
118 |
-
}
|
119 |
-
|
120 |
-
// Check checkboxes, on a uncheck they won't be posted to this function
|
121 |
-
$defaults = $this->default_ga_values();
|
122 |
-
foreach ( $defaults[ $this->option_prefix ] as $option_name => $value ) {
|
123 |
-
$this->handle_default_setting( $data, $option_name, $value );
|
124 |
-
}
|
125 |
-
|
126 |
-
if ( ! empty( $this->options['analytics_profile'] ) ) {
|
127 |
-
$this->options['analytics_profile_code'] = $this->get_ua_code_from_profile( $this->options['analytics_profile'] );
|
128 |
-
}
|
129 |
-
|
130 |
-
$this->do_validation( $data['return_tab'] );
|
131 |
-
|
132 |
-
if ( $this->update_option( $this->options ) ) {
|
133 |
-
// Success, add a new notification
|
134 |
-
$this->add_notification( 'ga_notifications', array(
|
135 |
-
'type' => 'success',
|
136 |
-
'description' => __( 'Settings saved.', 'google-analytics-for-wordpress' ),
|
137 |
-
) );
|
138 |
-
}
|
139 |
-
else {
|
140 |
-
// Fail, add a new notification
|
141 |
-
$this->add_notification( 'ga_notifications', array(
|
142 |
-
'type' => 'error',
|
143 |
-
'description' => __( 'There were no changes to save, please try again.', 'google-analytics-for-wordpress' ),
|
144 |
-
) );
|
145 |
-
}
|
146 |
-
|
147 |
-
// redirect
|
148 |
-
wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $data['return_tab'], 301 );
|
149 |
-
exit;
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Redirect to settings with a validation error if there are validation errors
|
154 |
-
*
|
155 |
-
* @param string $return_tab The tab to return to when there is a validation error.
|
156 |
-
*/
|
157 |
-
protected function do_validation( $return_tab ) {
|
158 |
-
$validation = $this->validate_settings();
|
159 |
-
if ( is_wp_error( $validation ) ) {
|
160 |
-
$this->add_notification( 'ga_notifications', array(
|
161 |
-
'type' => 'error',
|
162 |
-
'description' => $validation->get_error_message(),
|
163 |
-
) );
|
164 |
-
|
165 |
-
wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $return_tab, 301 );
|
166 |
-
exit;
|
167 |
-
}
|
168 |
-
}
|
169 |
-
|
170 |
-
/**
|
171 |
-
* Validates the settings in the `options` attribute, returns an WP_Error object on error
|
172 |
-
*
|
173 |
-
* @return true|WP_Error true or an error object.
|
174 |
-
*/
|
175 |
-
protected function validate_settings() {
|
176 |
-
|
177 |
-
if ( ! empty( $this->options['manual_ua_code_field'] ) ) {
|
178 |
-
$this->options['manual_ua_code_field'] = trim( $this->options['manual_ua_code_field'] );
|
179 |
-
// en dash to minus, prevents issue with code copied from web with "fancy" dash
|
180 |
-
$this->options['manual_ua_code_field'] = str_replace( '–', '-', $this->options['manual_ua_code_field'] );
|
181 |
-
|
182 |
-
// Regex to tests if a valid UA code has been set. Valid codes follow: "UA-[4 digits]-[at least 1 digit]".
|
183 |
-
if ( ! preg_match( '|^UA-\d{4,}-\d+$|', $this->options['manual_ua_code_field'] ) ) {
|
184 |
-
|
185 |
-
return new WP_Error(
|
186 |
-
'ua-code-format',
|
187 |
-
__( 'The UA code needs to follow UA-XXXXXXXX-X format.', 'google-analytics-for-wordpress' )
|
188 |
-
);
|
189 |
-
}
|
190 |
-
}
|
191 |
-
|
192 |
-
/**
|
193 |
-
* Filters the validation for the admin options
|
194 |
-
*
|
195 |
-
* @param true|WP_Error true if the validation is successful, WP_Error on error.
|
196 |
-
* @param array $this->options The options that are being saved.
|
197 |
-
*/
|
198 |
-
return apply_filters( 'yst_ga_admin_validate_settings', true, $this->options );
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Run a this deactivation hook on deactivation of GA. When this happens we'll
|
203 |
-
* remove the options for the profiles and the refresh token.
|
204 |
-
*/
|
205 |
-
public static function ga_deactivation_hook() {
|
206 |
-
// Remove the refresh token and other API settings
|
207 |
-
self::analytics_api_clean_up();
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Handle a default setting in GA
|
212 |
-
*
|
213 |
-
* @param array $data
|
214 |
-
* @param string $option_name
|
215 |
-
* @param mixed $value
|
216 |
-
*/
|
217 |
-
private function handle_default_setting( $data, $option_name, $value ) {
|
218 |
-
if ( ! isset( $data[ $option_name ] ) ) {
|
219 |
-
// If no data was passed in, set it to the default.
|
220 |
-
if ( $value === 1 ) {
|
221 |
-
// Disable the checkbox for now, use value 0
|
222 |
-
$this->options[ $option_name ] = 0;
|
223 |
-
}
|
224 |
-
else {
|
225 |
-
$this->options[ $option_name ] = $value;
|
226 |
-
}
|
227 |
-
}
|
228 |
-
}
|
229 |
-
|
230 |
-
/**
|
231 |
-
* Handle the post requests in the admin form of the GA plugin
|
232 |
-
*
|
233 |
-
* @param Yoast_GA_Dashboards $dashboards
|
234 |
-
*/
|
235 |
-
private function handle_ga_post_request( $dashboards ) {
|
236 |
-
if ( ! function_exists( 'wp_verify_nonce' ) ) {
|
237 |
-
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
238 |
-
}
|
239 |
-
|
240 |
-
if ( isset( $_POST['ga-form-settings'] ) && wp_verify_nonce( $_POST['yoast_ga_nonce'], 'save_settings' ) ) {
|
241 |
-
if ( ! isset ( $_POST['ignore_users'] ) ) {
|
242 |
-
$_POST['ignore_users'] = array();
|
243 |
-
}
|
244 |
-
|
245 |
-
$dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
|
246 |
-
|
247 |
-
if ( ( $dashboards_disabled == false && isset( $_POST['dashboards_disabled'] ) ) || $this->ga_profile_changed( $_POST ) ) {
|
248 |
-
$dashboards->reset_dashboards_data();
|
249 |
-
}
|
250 |
-
|
251 |
-
// Post submitted and verified with our nonce
|
252 |
-
$this->save_settings( $_POST );
|
253 |
-
}
|
254 |
-
}
|
255 |
-
|
256 |
-
/**
|
257 |
-
* Is there selected an other property in the settings post? Returns true or false.
|
258 |
-
*
|
259 |
-
* @param array $post
|
260 |
-
*
|
261 |
-
* @return bool
|
262 |
-
*/
|
263 |
-
private function ga_profile_changed( $post ) {
|
264 |
-
if ( isset( $post['analytics_profile'] ) && isset( $this->options['analytics_profile'] ) ) {
|
265 |
-
if ( $post['analytics_profile'] != $this->options['analytics_profile'] ) {
|
266 |
-
return true;
|
267 |
-
}
|
268 |
-
}
|
269 |
-
|
270 |
-
return false;
|
271 |
-
}
|
272 |
-
|
273 |
-
/**
|
274 |
-
* Are we allowed to show a warning message? returns true if it's allowed
|
275 |
-
*
|
276 |
-
* @return bool
|
277 |
-
*/
|
278 |
-
private function show_admin_warning() {
|
279 |
-
return ( current_user_can( 'manage_options' ) && ( ! isset( $_GET['page'] ) || ( isset( $_GET['page'] ) && $_GET['page'] !== 'yst_ga_settings' ) ) );
|
280 |
-
}
|
281 |
-
|
282 |
-
/**
|
283 |
-
* Are we allowed to show a warning message? returns true if it's allowed ( this is meant to be only for dashboard )
|
284 |
-
*
|
285 |
-
* @return bool
|
286 |
-
*/
|
287 |
-
private function show_admin_dashboard_warning() {
|
288 |
-
return ( current_user_can( 'manage_options' ) && isset( $_GET['page'] ) && $_GET['page'] === 'yst_ga_dashboard' );
|
289 |
-
}
|
290 |
-
|
291 |
-
/**
|
292 |
-
* Transform the Profile ID into an helpful UA code
|
293 |
-
*
|
294 |
-
* @param integer $profile_id
|
295 |
-
*
|
296 |
-
* @return null
|
297 |
-
*/
|
298 |
-
private function get_ua_code_from_profile( $profile_id ) {
|
299 |
-
$profiles = $this->get_profiles();
|
300 |
-
$ua_code = null;
|
301 |
-
|
302 |
-
foreach ( $profiles as $account ) {
|
303 |
-
foreach ( $account['items'] as $profile ) {
|
304 |
-
foreach ( $profile['items'] as $subprofile ) {
|
305 |
-
if ( isset( $subprofile['id'] ) && $subprofile['id'] === $profile_id ) {
|
306 |
-
return $subprofile['ua_code'];
|
307 |
-
}
|
308 |
-
}
|
309 |
-
}
|
310 |
-
}
|
311 |
-
|
312 |
-
return $ua_code;
|
313 |
-
}
|
314 |
-
|
315 |
-
/**
|
316 |
-
* Add a link to the settings page to the plugins list
|
317 |
-
*
|
318 |
-
* @param array $links array of links for the plugins, adapted when the current plugin is found.
|
319 |
-
*
|
320 |
-
* @return array $links
|
321 |
-
*/
|
322 |
-
public function add_action_links( $links ) {
|
323 |
-
// add link to knowledgebase
|
324 |
-
// @todo UTM link fix
|
325 |
-
$faq_link = '<a title="MonsterInsights Knowledge Base" href="http://www.monsterinsights.com/docs/">' . __( 'FAQ', 'google-analytics-for-wordpress' ) . '</a>';
|
326 |
-
array_unshift( $links, $faq_link );
|
327 |
-
|
328 |
-
$settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=yst_ga_settings' ) ) . '">' . __( 'Settings', 'google-analytics-for-wordpress' ) . '</a>';
|
329 |
-
array_unshift( $links, $settings_link );
|
330 |
-
|
331 |
-
return $links;
|
332 |
-
}
|
333 |
-
|
334 |
-
/**
|
335 |
-
* Adds some promo text for the premium plugin on the custom dimensions tab.
|
336 |
-
*/
|
337 |
-
public function premium_promo() {
|
338 |
-
echo '<div class="ga-promote">';
|
339 |
-
echo '<p>';
|
340 |
-
printf( __( 'If you want to track custom dimensions like page views per author or post type, you should upgrade to the %1$spremium version of Google Analytics by MonsterInsights%2$s.', 'google-analytics-for-wordpress' ), '<a href="https://www.monsterinsights.com/pricing/#utm_medium=text-link&utm_source=gawp-config&utm_campaign=wpgaplugin&utm_content=custom_dimensions_tab">', '</a>' );
|
341 |
-
echo ' ';
|
342 |
-
_e( 'This will also give you access to the support team at MonsterInsights, who will provide support on the plugin 24/7.', 'google-analytics-for-wordpress' );
|
343 |
-
echo '</p>';
|
344 |
-
echo '</div>';
|
345 |
-
}
|
346 |
-
|
347 |
-
/**
|
348 |
-
* Load the page of a menu item in the GA plugin
|
349 |
-
*/
|
350 |
-
public function load_page() {
|
351 |
-
|
352 |
-
if ( ! has_action( 'yst_ga_custom_dimensions_tab-content' ) ) {
|
353 |
-
add_action( 'yst_ga_custom_dimensions_tab-content', array( $this, 'premium_promo' ) );
|
354 |
-
}
|
355 |
-
|
356 |
-
if ( ! has_action( 'yst_ga_custom_dimension_add-dashboards-tab' ) ) {
|
357 |
-
add_action( 'yst_ga_custom_dimension_add-dashboards-tab', array( $this, 'premium_promo' ) );
|
358 |
-
}
|
359 |
-
|
360 |
-
switch ( filter_input( INPUT_GET, 'page' ) ) {
|
361 |
-
case 'yst_ga_settings':
|
362 |
-
require_once( $this->plugin_path . 'admin/pages/settings.php' );
|
363 |
-
break;
|
364 |
-
case 'yst_ga_extensions':
|
365 |
-
require_once( $this->plugin_path . 'admin/pages/extensions.php' );
|
366 |
-
break;
|
367 |
-
case 'yst_ga_dashboard':
|
368 |
-
default:
|
369 |
-
require_once( $this->plugin_path . 'admin/pages/dashboard.php' );
|
370 |
-
break;
|
371 |
-
}
|
372 |
-
}
|
373 |
-
|
374 |
-
|
375 |
-
/**
|
376 |
-
* Get the Google Analytics profiles which are in this google account
|
377 |
-
*
|
378 |
-
* @return array
|
379 |
-
*/
|
380 |
-
public function get_profiles() {
|
381 |
-
$return = Yoast_Google_Analytics::get_instance()->get_profiles();
|
382 |
-
|
383 |
-
return $return;
|
384 |
-
}
|
385 |
-
|
386 |
-
/**
|
387 |
-
* Checks if there is a callback to get token from Google Analytics API
|
388 |
-
*/
|
389 |
-
private function google_analytics_listener() {
|
390 |
-
$google_auth_code = filter_input( INPUT_POST, 'google_auth_code' );
|
391 |
-
if ( $google_auth_code && current_user_can( 'manage_options' ) && wp_verify_nonce( filter_input( INPUT_POST, 'yoast_ga_nonce' ), 'save_settings' ) ) {
|
392 |
-
self::analytics_api_clean_up();
|
393 |
-
|
394 |
-
Yoast_Google_Analytics::get_instance()->authenticate( trim( $google_auth_code ) );
|
395 |
-
}
|
396 |
-
}
|
397 |
-
|
398 |
-
/**
|
399 |
-
* Clean up the Analytics API settings
|
400 |
-
*/
|
401 |
-
public static function analytics_api_clean_up() {
|
402 |
-
delete_option( 'yoast-ga-refresh_token' );
|
403 |
-
delete_option( 'yst_ga_api_call_fail' );
|
404 |
-
delete_option( 'yst_ga_last_wp_run' );
|
405 |
-
delete_option( 'yst_ga_api' );
|
406 |
-
}
|
407 |
-
|
408 |
-
/**
|
409 |
-
* Get the current GA profile
|
410 |
-
*
|
411 |
-
* @return null
|
412 |
-
*/
|
413 |
-
private function get_current_profile() {
|
414 |
-
if ( ! empty( $this->options['analytics_profile'] ) ) {
|
415 |
-
return $this->options['analytics_profile'];
|
416 |
-
}
|
417 |
-
|
418 |
-
return null;
|
419 |
-
}
|
420 |
-
|
421 |
-
/**
|
422 |
-
* Get the user roles of this WordPress blog
|
423 |
-
*
|
424 |
-
* @return array
|
425 |
-
*/
|
426 |
-
public function get_userroles() {
|
427 |
-
global $wp_roles;
|
428 |
-
|
429 |
-
$all_roles = $wp_roles->roles;
|
430 |
-
$roles = array();
|
431 |
-
|
432 |
-
/**
|
433 |
-
* Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
|
434 |
-
*
|
435 |
-
* @api array $all_roles
|
436 |
-
*/
|
437 |
-
$editable_roles = apply_filters( 'editable_roles', $all_roles );
|
438 |
-
|
439 |
-
foreach ( $editable_roles as $id => $name ) {
|
440 |
-
$roles[] = array(
|
441 |
-
'id' => $id,
|
442 |
-
'name' => translate_user_role( $name['name'] ),
|
443 |
-
);
|
444 |
-
}
|
445 |
-
|
446 |
-
return $roles;
|
447 |
-
}
|
448 |
-
|
449 |
-
/**
|
450 |
-
* Get types of how we can track downloads
|
451 |
-
*
|
452 |
-
* @return array
|
453 |
-
*/
|
454 |
-
public function track_download_types() {
|
455 |
-
return array(
|
456 |
-
0 => array( 'id' => 'event', 'name' => __( 'Event', 'google-analytics-for-wordpress' ) ),
|
457 |
-
1 => array( 'id' => 'pageview', 'name' => __( 'Pageview', 'google-analytics-for-wordpress' ) ),
|
458 |
-
);
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* Get options for the track full url or links setting
|
463 |
-
*
|
464 |
-
* @return array
|
465 |
-
*/
|
466 |
-
public function get_track_full_url() {
|
467 |
-
return array(
|
468 |
-
0 => array( 'id' => 'domain', 'name' => __( 'Just the domain', 'google-analytics-for-wordpress' ) ),
|
469 |
-
1 => array( 'id' => 'full_links', 'name' => __( 'Full links', 'google-analytics-for-wordpress' ) ),
|
470 |
-
);
|
471 |
-
}
|
472 |
-
|
473 |
-
/**
|
474 |
-
* Render the admin page head for the GA Plugin
|
475 |
-
*/
|
476 |
-
public function content_head() {
|
477 |
-
require 'views/content_head.php';
|
478 |
-
}
|
479 |
-
|
480 |
-
/**
|
481 |
-
* Output System Info file
|
482 |
-
*/
|
483 |
-
public function system_info() {
|
484 |
-
if ( ! empty( $_REQUEST['monsterinsights-action'] ) && $_REQUEST['monsterinsights-action'] === 'download_sysinfo' ) {
|
485 |
-
if ( ! current_user_can( 'manage_options' ) ) {
|
486 |
-
return;
|
487 |
-
}
|
488 |
-
nocache_headers();
|
489 |
-
header( 'Content-Type: text/plain' );
|
490 |
-
header( 'Content-Disposition: attachment; filename="monsterinsights-system-info.txt"' );
|
491 |
-
echo wp_strip_all_tags( $_POST['monsterinsights-sysinfo'] );
|
492 |
-
die();
|
493 |
-
}
|
494 |
-
}
|
495 |
-
|
496 |
-
/**
|
497 |
-
* Render the admin page footer with sidebar for the GA Plugin
|
498 |
-
*/
|
499 |
-
public function content_footer() {
|
500 |
-
|
501 |
-
do_action( 'yoast_ga_admin_footer' );
|
502 |
-
|
503 |
-
if ( class_exists( 'MI_Product_GA_Premium' ) ) {
|
504 |
-
$license_manager = new MI_Plugin_License_Manager( new MI_Product_GA_Premium() );
|
505 |
-
if ( $license_manager->license_is_valid() ) {
|
506 |
-
return;
|
507 |
-
}
|
508 |
-
}
|
509 |
-
|
510 |
-
$banners = array();
|
511 |
-
$banners[] = array(
|
512 |
-
'url' => 'https://
|
513 |
-
'banner' => $this->plugin_url . 'assets/img/omupsell.png',
|
514 |
-
'title' => 'Convert Visitors into Subscribers',
|
515 |
-
);
|
516 |
-
$banners[] = array(
|
517 |
-
'url' => 'https://www.monsterinsights.com/pricing/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
518 |
-
'banner' => $this->plugin_url . 'assets/img/upgradetopro.png',
|
519 |
-
'title' => 'Get the premium version of Google Analytics by MonsterInsights!',
|
520 |
-
);
|
521 |
-
$banners[] = array(
|
522 |
-
'url' => 'http://www.wpbeginner.net/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
523 |
-
'banner' => $this->plugin_url . 'assets/img/wpbeginnerupsell.png',
|
524 |
-
'title' => 'The best collection of free beginner WordPress resources!',
|
525 |
-
);
|
526 |
-
$banners[] = array(
|
527 |
-
'url' => 'https://wpforms.com/pricing/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
528 |
-
'banner' => $this->plugin_url . 'assets/img/wpformsupsell.png',
|
529 |
-
'title' => 'Get the most beginner friendly WordPress contact form plugin in the market!',
|
530 |
-
);
|
531 |
-
|
532 |
-
shuffle( $banners );
|
533 |
-
|
534 |
-
require 'views/content-footer.php';
|
535 |
-
|
536 |
-
}
|
537 |
-
|
538 |
-
/**
|
539 |
-
* Returns a list of all available extensions
|
540 |
-
*
|
541 |
-
* @return array
|
542 |
-
*/
|
543 |
-
public function get_extensions() {
|
544 |
-
$extensions = array(
|
545 |
-
'ga_premium' => (object) array(
|
546 |
-
'url' => 'https://www.monsterinsights.com/pricing/',
|
547 |
-
'title' => __( 'Google Analytics by MonsterInsights Pro', 'google-analytics-for-wordpress' ),
|
548 |
-
'desc' => __( 'The premium version of Google Analytics by MonsterInsights with more features and support.', 'google-analytics-for-wordpress' ),
|
549 |
-
'status' => 'uninstalled',
|
550 |
-
),
|
551 |
-
'ecommerce' => (object) array(
|
552 |
-
'url' => 'https://www.monsterinsights.com/pricing/',
|
553 |
-
'title' => __( 'Google Analytics by MonsterInsights', 'google-analytics-for-wordpress' ) . '<br />' . __( 'eCommerce tracking', 'google-analytics-for-wordpress' ),
|
554 |
-
'desc' => __( 'Track your eCommerce data and transactions with this eCommerce extension for Google Analytics.', 'google-analytics-for-wordpress' ),
|
555 |
-
'status' => 'uninstalled',
|
556 |
-
),
|
557 |
-
);
|
558 |
-
|
559 |
-
$extensions = apply_filters( 'yst_ga_extension_status', $extensions );
|
560 |
-
|
561 |
-
return $extensions;
|
562 |
-
}
|
563 |
-
|
564 |
-
/**
|
565 |
-
* Add a notification to the notification transient
|
566 |
-
*
|
567 |
-
* @param string $transient_name
|
568 |
-
* @param array $settings
|
569 |
-
*/
|
570 |
-
private function add_notification( $transient_name, $settings ) {
|
571 |
-
set_transient( $transient_name, $settings, MINUTE_IN_SECONDS );
|
572 |
-
}
|
573 |
-
|
574 |
-
/**
|
575 |
-
* Show the notification that should be set, after showing the notification this function unset the transient
|
576 |
-
*
|
577 |
-
* @param string $transient_name The name of the transient which contains the notification
|
578 |
-
*/
|
579 |
-
public function show_notification( $transient_name ) {
|
580 |
-
$transient = get_transient( $transient_name );
|
581 |
-
|
582 |
-
if ( isset( $transient['type'] ) && isset( $transient['description'] ) ) {
|
583 |
-
if ( $transient['type'] == 'success' ) {
|
584 |
-
add_settings_error(
|
585 |
-
'yoast_google_analytics',
|
586 |
-
'yoast_google_analytics',
|
587 |
-
$transient['description'],
|
588 |
-
'updated'
|
589 |
-
);
|
590 |
-
}
|
591 |
-
else {
|
592 |
-
add_settings_error(
|
593 |
-
'yoast_google_analytics',
|
594 |
-
'yoast_google_analytics',
|
595 |
-
$transient['description'],
|
596 |
-
'error'
|
597 |
-
);
|
598 |
-
}
|
599 |
-
|
600 |
-
delete_transient( $transient_name );
|
601 |
-
}
|
602 |
-
}
|
603 |
-
|
604 |
-
/**
|
605 |
-
* Check if there the aggregate data cron is executed
|
606 |
-
* @return bool
|
607 |
-
*/
|
608 |
-
private function is_running_cron() {
|
609 |
-
return doing_action( 'yst_ga_aggregate_data' ) && defined( 'DOING_CRON' ) && DOING_CRON;
|
610 |
-
}
|
611 |
-
|
612 |
-
/**
|
613 |
-
* Check if there the aggregate data cron is executed
|
614 |
-
* @return bool
|
615 |
-
*/
|
616 |
-
private function is_running_ajax() {
|
617 |
-
return defined( 'DOING_AJAX' ) && DOING_AJAX && strpos( filter_input( INPUT_GET, 'action' ), 'yoast_dashboard' ) === 0;
|
618 |
-
}
|
619 |
-
|
620 |
-
}
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @package GoogleAnalytics\Admin
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* This class is for the backend, extendable for all child classes
|
8 |
+
*/
|
9 |
+
class Yoast_GA_Admin extends Yoast_GA_Options {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Constructor
|
13 |
+
*/
|
14 |
+
public function __construct() {
|
15 |
+
parent::__construct();
|
16 |
+
|
17 |
+
add_action( 'plugins_loaded', array( $this, 'init_ga' ) );
|
18 |
+
|
19 |
+
// Only run admin_init when there is a cron jon executed.
|
20 |
+
$current_page = filter_input( INPUT_GET, 'page' );
|
21 |
+
|
22 |
+
// Only when current page is not 'wpseo'.
|
23 |
+
if ( strpos( $current_page, 'wpseo' ) !== 0 ) {
|
24 |
+
if ( ( $this->is_running_cron() || $this->is_running_ajax() ) || strpos( $current_page, 'yst_ga' ) === 0 ) {
|
25 |
+
add_action( 'admin_init', array( $this, 'init_settings' ) );
|
26 |
+
}
|
27 |
+
}
|
28 |
+
|
29 |
+
add_action( 'admin_init', array( $this, 'system_info' ) );
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Init function when the plugin is loaded
|
35 |
+
*/
|
36 |
+
public function init_ga() {
|
37 |
+
|
38 |
+
new Yoast_GA_Admin_Menu( $this );
|
39 |
+
|
40 |
+
add_filter( 'plugin_action_links_' . plugin_basename( GAWP_FILE ), array( $this, 'add_action_links' ) );
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Init function for the settings of GA
|
46 |
+
*/
|
47 |
+
public function init_settings() {
|
48 |
+
$this->options = $this->get_options();
|
49 |
+
|
50 |
+
try {
|
51 |
+
// Loading Google Api Libs with minimal version 2.0.
|
52 |
+
new MI_Api_Libs( '2.0' );
|
53 |
+
}
|
54 |
+
catch( Exception $exception ) {
|
55 |
+
if ( $exception->getMessage() === 'required_version' ) {
|
56 |
+
add_action( 'admin_notices', array( $this, 'set_api_libs_error' ) );
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
$dashboards = Yoast_GA_Dashboards::get_instance();
|
61 |
+
|
62 |
+
// Listener for reconnecting with google analytics
|
63 |
+
$this->google_analytics_listener();
|
64 |
+
|
65 |
+
if ( is_null( $this->get_tracking_code() ) && $this->show_admin_warning() ) {
|
66 |
+
add_action( 'admin_notices', array( 'Yoast_Google_Analytics_Notice', 'config_warning' ) );
|
67 |
+
}
|
68 |
+
|
69 |
+
// Check if something has went wrong with GA-api calls
|
70 |
+
$has_tracking_code = ( ! is_null( $this->get_tracking_code() ) && empty( $this->options['manual_ua_code_field'] ) );
|
71 |
+
if ( $has_tracking_code && $this->show_admin_dashboard_warning() ) {
|
72 |
+
Yoast_Google_Analytics::get_instance()->check_for_ga_issues();
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
|
77 |
+
$this->handle_ga_post_request( $dashboards );
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Show the notifications if we have one
|
82 |
+
*/
|
83 |
+
$this->show_notification( 'ga_notifications' );
|
84 |
+
|
85 |
+
// Load the Google Analytics Dashboards functionality
|
86 |
+
$dashboards->init_dashboards( $this->get_current_profile() );
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* There is an error with the API libs. So show a notice.
|
91 |
+
*/
|
92 |
+
public function set_api_libs_error() {
|
93 |
+
echo '<div class="error notice"><p>' . __( 'MonsterInsights plugins share some code between them to make your site faster. As a result of that, we need all MonsterInsights plugins to be up to date. We\'ve detected this isn\'t the case, so please update the MonsterInsights plugins that aren\'t up to date yet.', 'google-analytics-for-wordpress' ) . '</p></div>';
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* This function saves the settings in the option field and returns a wp success message on success
|
98 |
+
*
|
99 |
+
* @param array $data
|
100 |
+
*/
|
101 |
+
public function save_settings( $data ) {
|
102 |
+
|
103 |
+
unset( $data['google_auth_code'] );
|
104 |
+
|
105 |
+
foreach ( $data as $key => $value ) {
|
106 |
+
if ( $key != 'return_tab' ) {
|
107 |
+
if ( is_string( $value ) ) {
|
108 |
+
if ( $key === 'custom_code' && ! current_user_can( 'unfiltered_html' ) ) {
|
109 |
+
continue;
|
110 |
+
}
|
111 |
+
else {
|
112 |
+
$value = strip_tags( $value );
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
$this->options[ $key ] = $value;
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
// Check checkboxes, on a uncheck they won't be posted to this function
|
121 |
+
$defaults = $this->default_ga_values();
|
122 |
+
foreach ( $defaults[ $this->option_prefix ] as $option_name => $value ) {
|
123 |
+
$this->handle_default_setting( $data, $option_name, $value );
|
124 |
+
}
|
125 |
+
|
126 |
+
if ( ! empty( $this->options['analytics_profile'] ) ) {
|
127 |
+
$this->options['analytics_profile_code'] = $this->get_ua_code_from_profile( $this->options['analytics_profile'] );
|
128 |
+
}
|
129 |
+
|
130 |
+
$this->do_validation( $data['return_tab'] );
|
131 |
+
|
132 |
+
if ( $this->update_option( $this->options ) ) {
|
133 |
+
// Success, add a new notification
|
134 |
+
$this->add_notification( 'ga_notifications', array(
|
135 |
+
'type' => 'success',
|
136 |
+
'description' => __( 'Settings saved.', 'google-analytics-for-wordpress' ),
|
137 |
+
) );
|
138 |
+
}
|
139 |
+
else {
|
140 |
+
// Fail, add a new notification
|
141 |
+
$this->add_notification( 'ga_notifications', array(
|
142 |
+
'type' => 'error',
|
143 |
+
'description' => __( 'There were no changes to save, please try again.', 'google-analytics-for-wordpress' ),
|
144 |
+
) );
|
145 |
+
}
|
146 |
+
|
147 |
+
// redirect
|
148 |
+
wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $data['return_tab'], 301 );
|
149 |
+
exit;
|
150 |
+
}
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Redirect to settings with a validation error if there are validation errors
|
154 |
+
*
|
155 |
+
* @param string $return_tab The tab to return to when there is a validation error.
|
156 |
+
*/
|
157 |
+
protected function do_validation( $return_tab ) {
|
158 |
+
$validation = $this->validate_settings();
|
159 |
+
if ( is_wp_error( $validation ) ) {
|
160 |
+
$this->add_notification( 'ga_notifications', array(
|
161 |
+
'type' => 'error',
|
162 |
+
'description' => $validation->get_error_message(),
|
163 |
+
) );
|
164 |
+
|
165 |
+
wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $return_tab, 301 );
|
166 |
+
exit;
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Validates the settings in the `options` attribute, returns an WP_Error object on error
|
172 |
+
*
|
173 |
+
* @return true|WP_Error true or an error object.
|
174 |
+
*/
|
175 |
+
protected function validate_settings() {
|
176 |
+
|
177 |
+
if ( ! empty( $this->options['manual_ua_code_field'] ) ) {
|
178 |
+
$this->options['manual_ua_code_field'] = trim( $this->options['manual_ua_code_field'] );
|
179 |
+
// en dash to minus, prevents issue with code copied from web with "fancy" dash
|
180 |
+
$this->options['manual_ua_code_field'] = str_replace( '–', '-', $this->options['manual_ua_code_field'] );
|
181 |
+
|
182 |
+
// Regex to tests if a valid UA code has been set. Valid codes follow: "UA-[4 digits]-[at least 1 digit]".
|
183 |
+
if ( ! preg_match( '|^UA-\d{4,}-\d+$|', $this->options['manual_ua_code_field'] ) ) {
|
184 |
+
|
185 |
+
return new WP_Error(
|
186 |
+
'ua-code-format',
|
187 |
+
__( 'The UA code needs to follow UA-XXXXXXXX-X format.', 'google-analytics-for-wordpress' )
|
188 |
+
);
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Filters the validation for the admin options
|
194 |
+
*
|
195 |
+
* @param true|WP_Error true if the validation is successful, WP_Error on error.
|
196 |
+
* @param array $this->options The options that are being saved.
|
197 |
+
*/
|
198 |
+
return apply_filters( 'yst_ga_admin_validate_settings', true, $this->options );
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Run a this deactivation hook on deactivation of GA. When this happens we'll
|
203 |
+
* remove the options for the profiles and the refresh token.
|
204 |
+
*/
|
205 |
+
public static function ga_deactivation_hook() {
|
206 |
+
// Remove the refresh token and other API settings
|
207 |
+
self::analytics_api_clean_up();
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Handle a default setting in GA
|
212 |
+
*
|
213 |
+
* @param array $data
|
214 |
+
* @param string $option_name
|
215 |
+
* @param mixed $value
|
216 |
+
*/
|
217 |
+
private function handle_default_setting( $data, $option_name, $value ) {
|
218 |
+
if ( ! isset( $data[ $option_name ] ) ) {
|
219 |
+
// If no data was passed in, set it to the default.
|
220 |
+
if ( $value === 1 ) {
|
221 |
+
// Disable the checkbox for now, use value 0
|
222 |
+
$this->options[ $option_name ] = 0;
|
223 |
+
}
|
224 |
+
else {
|
225 |
+
$this->options[ $option_name ] = $value;
|
226 |
+
}
|
227 |
+
}
|
228 |
+
}
|
229 |
+
|
230 |
+
/**
|
231 |
+
* Handle the post requests in the admin form of the GA plugin
|
232 |
+
*
|
233 |
+
* @param Yoast_GA_Dashboards $dashboards
|
234 |
+
*/
|
235 |
+
private function handle_ga_post_request( $dashboards ) {
|
236 |
+
if ( ! function_exists( 'wp_verify_nonce' ) ) {
|
237 |
+
require_once( ABSPATH . 'wp-includes/pluggable.php' );
|
238 |
+
}
|
239 |
+
|
240 |
+
if ( isset( $_POST['ga-form-settings'] ) && wp_verify_nonce( $_POST['yoast_ga_nonce'], 'save_settings' ) ) {
|
241 |
+
if ( ! isset ( $_POST['ignore_users'] ) ) {
|
242 |
+
$_POST['ignore_users'] = array();
|
243 |
+
}
|
244 |
+
|
245 |
+
$dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
|
246 |
+
|
247 |
+
if ( ( $dashboards_disabled == false && isset( $_POST['dashboards_disabled'] ) ) || $this->ga_profile_changed( $_POST ) ) {
|
248 |
+
$dashboards->reset_dashboards_data();
|
249 |
+
}
|
250 |
+
|
251 |
+
// Post submitted and verified with our nonce
|
252 |
+
$this->save_settings( $_POST );
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Is there selected an other property in the settings post? Returns true or false.
|
258 |
+
*
|
259 |
+
* @param array $post
|
260 |
+
*
|
261 |
+
* @return bool
|
262 |
+
*/
|
263 |
+
private function ga_profile_changed( $post ) {
|
264 |
+
if ( isset( $post['analytics_profile'] ) && isset( $this->options['analytics_profile'] ) ) {
|
265 |
+
if ( $post['analytics_profile'] != $this->options['analytics_profile'] ) {
|
266 |
+
return true;
|
267 |
+
}
|
268 |
+
}
|
269 |
+
|
270 |
+
return false;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* Are we allowed to show a warning message? returns true if it's allowed
|
275 |
+
*
|
276 |
+
* @return bool
|
277 |
+
*/
|
278 |
+
private function show_admin_warning() {
|
279 |
+
return ( current_user_can( 'manage_options' ) && ( ! isset( $_GET['page'] ) || ( isset( $_GET['page'] ) && $_GET['page'] !== 'yst_ga_settings' ) ) );
|
280 |
+
}
|
281 |
+
|
282 |
+
/**
|
283 |
+
* Are we allowed to show a warning message? returns true if it's allowed ( this is meant to be only for dashboard )
|
284 |
+
*
|
285 |
+
* @return bool
|
286 |
+
*/
|
287 |
+
private function show_admin_dashboard_warning() {
|
288 |
+
return ( current_user_can( 'manage_options' ) && isset( $_GET['page'] ) && $_GET['page'] === 'yst_ga_dashboard' );
|
289 |
+
}
|
290 |
+
|
291 |
+
/**
|
292 |
+
* Transform the Profile ID into an helpful UA code
|
293 |
+
*
|
294 |
+
* @param integer $profile_id
|
295 |
+
*
|
296 |
+
* @return null
|
297 |
+
*/
|
298 |
+
private function get_ua_code_from_profile( $profile_id ) {
|
299 |
+
$profiles = $this->get_profiles();
|
300 |
+
$ua_code = null;
|
301 |
+
|
302 |
+
foreach ( $profiles as $account ) {
|
303 |
+
foreach ( $account['items'] as $profile ) {
|
304 |
+
foreach ( $profile['items'] as $subprofile ) {
|
305 |
+
if ( isset( $subprofile['id'] ) && $subprofile['id'] === $profile_id ) {
|
306 |
+
return $subprofile['ua_code'];
|
307 |
+
}
|
308 |
+
}
|
309 |
+
}
|
310 |
+
}
|
311 |
+
|
312 |
+
return $ua_code;
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Add a link to the settings page to the plugins list
|
317 |
+
*
|
318 |
+
* @param array $links array of links for the plugins, adapted when the current plugin is found.
|
319 |
+
*
|
320 |
+
* @return array $links
|
321 |
+
*/
|
322 |
+
public function add_action_links( $links ) {
|
323 |
+
// add link to knowledgebase
|
324 |
+
// @todo UTM link fix
|
325 |
+
$faq_link = '<a title="MonsterInsights Knowledge Base" href="http://www.monsterinsights.com/docs/">' . __( 'FAQ', 'google-analytics-for-wordpress' ) . '</a>';
|
326 |
+
array_unshift( $links, $faq_link );
|
327 |
+
|
328 |
+
$settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=yst_ga_settings' ) ) . '">' . __( 'Settings', 'google-analytics-for-wordpress' ) . '</a>';
|
329 |
+
array_unshift( $links, $settings_link );
|
330 |
+
|
331 |
+
return $links;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Adds some promo text for the premium plugin on the custom dimensions tab.
|
336 |
+
*/
|
337 |
+
public function premium_promo() {
|
338 |
+
echo '<div class="ga-promote">';
|
339 |
+
echo '<p>';
|
340 |
+
printf( __( 'If you want to track custom dimensions like page views per author or post type, you should upgrade to the %1$spremium version of Google Analytics by MonsterInsights%2$s.', 'google-analytics-for-wordpress' ), '<a href="https://www.monsterinsights.com/pricing/#utm_medium=text-link&utm_source=gawp-config&utm_campaign=wpgaplugin&utm_content=custom_dimensions_tab">', '</a>' );
|
341 |
+
echo ' ';
|
342 |
+
_e( 'This will also give you access to the support team at MonsterInsights, who will provide support on the plugin 24/7.', 'google-analytics-for-wordpress' );
|
343 |
+
echo '</p>';
|
344 |
+
echo '</div>';
|
345 |
+
}
|
346 |
+
|
347 |
+
/**
|
348 |
+
* Load the page of a menu item in the GA plugin
|
349 |
+
*/
|
350 |
+
public function load_page() {
|
351 |
+
|
352 |
+
if ( ! has_action( 'yst_ga_custom_dimensions_tab-content' ) ) {
|
353 |
+
add_action( 'yst_ga_custom_dimensions_tab-content', array( $this, 'premium_promo' ) );
|
354 |
+
}
|
355 |
+
|
356 |
+
if ( ! has_action( 'yst_ga_custom_dimension_add-dashboards-tab' ) ) {
|
357 |
+
add_action( 'yst_ga_custom_dimension_add-dashboards-tab', array( $this, 'premium_promo' ) );
|
358 |
+
}
|
359 |
+
|
360 |
+
switch ( filter_input( INPUT_GET, 'page' ) ) {
|
361 |
+
case 'yst_ga_settings':
|
362 |
+
require_once( $this->plugin_path . 'admin/pages/settings.php' );
|
363 |
+
break;
|
364 |
+
case 'yst_ga_extensions':
|
365 |
+
require_once( $this->plugin_path . 'admin/pages/extensions.php' );
|
366 |
+
break;
|
367 |
+
case 'yst_ga_dashboard':
|
368 |
+
default:
|
369 |
+
require_once( $this->plugin_path . 'admin/pages/dashboard.php' );
|
370 |
+
break;
|
371 |
+
}
|
372 |
+
}
|
373 |
+
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Get the Google Analytics profiles which are in this google account
|
377 |
+
*
|
378 |
+
* @return array
|
379 |
+
*/
|
380 |
+
public function get_profiles() {
|
381 |
+
$return = Yoast_Google_Analytics::get_instance()->get_profiles();
|
382 |
+
|
383 |
+
return $return;
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Checks if there is a callback to get token from Google Analytics API
|
388 |
+
*/
|
389 |
+
private function google_analytics_listener() {
|
390 |
+
$google_auth_code = filter_input( INPUT_POST, 'google_auth_code' );
|
391 |
+
if ( $google_auth_code && current_user_can( 'manage_options' ) && wp_verify_nonce( filter_input( INPUT_POST, 'yoast_ga_nonce' ), 'save_settings' ) ) {
|
392 |
+
self::analytics_api_clean_up();
|
393 |
+
|
394 |
+
Yoast_Google_Analytics::get_instance()->authenticate( trim( $google_auth_code ) );
|
395 |
+
}
|
396 |
+
}
|
397 |
+
|
398 |
+
/**
|
399 |
+
* Clean up the Analytics API settings
|
400 |
+
*/
|
401 |
+
public static function analytics_api_clean_up() {
|
402 |
+
delete_option( 'yoast-ga-refresh_token' );
|
403 |
+
delete_option( 'yst_ga_api_call_fail' );
|
404 |
+
delete_option( 'yst_ga_last_wp_run' );
|
405 |
+
delete_option( 'yst_ga_api' );
|
406 |
+
}
|
407 |
+
|
408 |
+
/**
|
409 |
+
* Get the current GA profile
|
410 |
+
*
|
411 |
+
* @return null
|
412 |
+
*/
|
413 |
+
private function get_current_profile() {
|
414 |
+
if ( ! empty( $this->options['analytics_profile'] ) ) {
|
415 |
+
return $this->options['analytics_profile'];
|
416 |
+
}
|
417 |
+
|
418 |
+
return null;
|
419 |
+
}
|
420 |
+
|
421 |
+
/**
|
422 |
+
* Get the user roles of this WordPress blog
|
423 |
+
*
|
424 |
+
* @return array
|
425 |
+
*/
|
426 |
+
public function get_userroles() {
|
427 |
+
global $wp_roles;
|
428 |
+
|
429 |
+
$all_roles = $wp_roles->roles;
|
430 |
+
$roles = array();
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
|
434 |
+
*
|
435 |
+
* @api array $all_roles
|
436 |
+
*/
|
437 |
+
$editable_roles = apply_filters( 'editable_roles', $all_roles );
|
438 |
+
|
439 |
+
foreach ( $editable_roles as $id => $name ) {
|
440 |
+
$roles[] = array(
|
441 |
+
'id' => $id,
|
442 |
+
'name' => translate_user_role( $name['name'] ),
|
443 |
+
);
|
444 |
+
}
|
445 |
+
|
446 |
+
return $roles;
|
447 |
+
}
|
448 |
+
|
449 |
+
/**
|
450 |
+
* Get types of how we can track downloads
|
451 |
+
*
|
452 |
+
* @return array
|
453 |
+
*/
|
454 |
+
public function track_download_types() {
|
455 |
+
return array(
|
456 |
+
0 => array( 'id' => 'event', 'name' => __( 'Event', 'google-analytics-for-wordpress' ) ),
|
457 |
+
1 => array( 'id' => 'pageview', 'name' => __( 'Pageview', 'google-analytics-for-wordpress' ) ),
|
458 |
+
);
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Get options for the track full url or links setting
|
463 |
+
*
|
464 |
+
* @return array
|
465 |
+
*/
|
466 |
+
public function get_track_full_url() {
|
467 |
+
return array(
|
468 |
+
0 => array( 'id' => 'domain', 'name' => __( 'Just the domain', 'google-analytics-for-wordpress' ) ),
|
469 |
+
1 => array( 'id' => 'full_links', 'name' => __( 'Full links', 'google-analytics-for-wordpress' ) ),
|
470 |
+
);
|
471 |
+
}
|
472 |
+
|
473 |
+
/**
|
474 |
+
* Render the admin page head for the GA Plugin
|
475 |
+
*/
|
476 |
+
public function content_head() {
|
477 |
+
require 'views/content_head.php';
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Output System Info file
|
482 |
+
*/
|
483 |
+
public function system_info() {
|
484 |
+
if ( ! empty( $_REQUEST['monsterinsights-action'] ) && $_REQUEST['monsterinsights-action'] === 'download_sysinfo' ) {
|
485 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
486 |
+
return;
|
487 |
+
}
|
488 |
+
nocache_headers();
|
489 |
+
header( 'Content-Type: text/plain' );
|
490 |
+
header( 'Content-Disposition: attachment; filename="monsterinsights-system-info.txt"' );
|
491 |
+
echo wp_strip_all_tags( $_POST['monsterinsights-sysinfo'] );
|
492 |
+
die();
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Render the admin page footer with sidebar for the GA Plugin
|
498 |
+
*/
|
499 |
+
public function content_footer() {
|
500 |
+
|
501 |
+
do_action( 'yoast_ga_admin_footer' );
|
502 |
+
|
503 |
+
if ( class_exists( 'MI_Product_GA_Premium' ) ) {
|
504 |
+
$license_manager = new MI_Plugin_License_Manager( new MI_Product_GA_Premium() );
|
505 |
+
if ( $license_manager->license_is_valid() ) {
|
506 |
+
return;
|
507 |
+
}
|
508 |
+
}
|
509 |
+
|
510 |
+
$banners = array();
|
511 |
+
$banners[] = array(
|
512 |
+
'url' => 'https://optinmonster.com/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
513 |
+
'banner' => $this->plugin_url . 'assets/img/omupsell.png',
|
514 |
+
'title' => 'Convert Visitors into Subscribers',
|
515 |
+
);
|
516 |
+
$banners[] = array(
|
517 |
+
'url' => 'https://www.monsterinsights.com/pricing/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
518 |
+
'banner' => $this->plugin_url . 'assets/img/upgradetopro.png',
|
519 |
+
'title' => 'Get the premium version of Google Analytics by MonsterInsights!',
|
520 |
+
);
|
521 |
+
$banners[] = array(
|
522 |
+
'url' => 'http://www.wpbeginner.net/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
523 |
+
'banner' => $this->plugin_url . 'assets/img/wpbeginnerupsell.png',
|
524 |
+
'title' => 'The best collection of free beginner WordPress resources!',
|
525 |
+
);
|
526 |
+
$banners[] = array(
|
527 |
+
'url' => 'https://wpforms.com/pricing/?utm_source=monsterinsights-config&utm_medium=banner&utm_campaign=gaplugin',
|
528 |
+
'banner' => $this->plugin_url . 'assets/img/wpformsupsell.png',
|
529 |
+
'title' => 'Get the most beginner friendly WordPress contact form plugin in the market!',
|
530 |
+
);
|
531 |
+
|
532 |
+
shuffle( $banners );
|
533 |
+
|
534 |
+
require 'views/content-footer.php';
|
535 |
+
|
536 |
+
}
|
537 |
+
|
538 |
+
/**
|
539 |
+
* Returns a list of all available extensions
|
540 |
+
*
|
541 |
+
* @return array
|
542 |
+
*/
|
543 |
+
public function get_extensions() {
|
544 |
+
$extensions = array(
|
545 |
+
'ga_premium' => (object) array(
|
546 |
+
'url' => 'https://www.monsterinsights.com/pricing/',
|
547 |
+
'title' => __( 'Google Analytics by MonsterInsights Pro', 'google-analytics-for-wordpress' ),
|
548 |
+
'desc' => __( 'The premium version of Google Analytics by MonsterInsights with more features and support.', 'google-analytics-for-wordpress' ),
|
549 |
+
'status' => 'uninstalled',
|
550 |
+
),
|
551 |
+
'ecommerce' => (object) array(
|
552 |
+
'url' => 'https://www.monsterinsights.com/pricing/',
|
553 |
+
'title' => __( 'Google Analytics by MonsterInsights', 'google-analytics-for-wordpress' ) . '<br />' . __( 'eCommerce tracking', 'google-analytics-for-wordpress' ),
|
554 |
+
'desc' => __( 'Track your eCommerce data and transactions with this eCommerce extension for Google Analytics.', 'google-analytics-for-wordpress' ),
|
555 |
+
'status' => 'uninstalled',
|
556 |
+
),
|
557 |
+
);
|
558 |
+
|
559 |
+
$extensions = apply_filters( 'yst_ga_extension_status', $extensions );
|
560 |
+
|
561 |
+
return $extensions;
|
562 |
+
}
|
563 |
+
|
564 |
+
/**
|
565 |
+
* Add a notification to the notification transient
|
566 |
+
*
|
567 |
+
* @param string $transient_name
|
568 |
+
* @param array $settings
|
569 |
+
*/
|
570 |
+
private function add_notification( $transient_name, $settings ) {
|
571 |
+
set_transient( $transient_name, $settings, MINUTE_IN_SECONDS );
|
572 |
+
}
|
573 |
+
|
574 |
+
/**
|
575 |
+
* Show the notification that should be set, after showing the notification this function unset the transient
|
576 |
+
*
|
577 |
+
* @param string $transient_name The name of the transient which contains the notification
|
578 |
+
*/
|
579 |
+
public function show_notification( $transient_name ) {
|
580 |
+
$transient = get_transient( $transient_name );
|
581 |
+
|
582 |
+
if ( isset( $transient['type'] ) && isset( $transient['description'] ) ) {
|
583 |
+
if ( $transient['type'] == 'success' ) {
|
584 |
+
add_settings_error(
|
585 |
+
'yoast_google_analytics',
|
586 |
+
'yoast_google_analytics',
|
587 |
+
$transient['description'],
|
588 |
+
'updated'
|
589 |
+
);
|
590 |
+
}
|
591 |
+
else {
|
592 |
+
add_settings_error(
|
593 |
+
'yoast_google_analytics',
|
594 |
+
'yoast_google_analytics',
|
595 |
+
$transient['description'],
|
596 |
+
'error'
|
597 |
+
);
|
598 |
+
}
|
599 |
+
|
600 |
+
delete_transient( $transient_name );
|
601 |
+
}
|
602 |
+
}
|
603 |
+
|
604 |
+
/**
|
605 |
+
* Check if there the aggregate data cron is executed
|
606 |
+
* @return bool
|
607 |
+
*/
|
608 |
+
private function is_running_cron() {
|
609 |
+
return doing_action( 'yst_ga_aggregate_data' ) && defined( 'DOING_CRON' ) && DOING_CRON;
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Check if there the aggregate data cron is executed
|
614 |
+
* @return bool
|
615 |
+
*/
|
616 |
+
private function is_running_ajax() {
|
617 |
+
return defined( 'DOING_AJAX' ) && DOING_AJAX && strpos( filter_input( INPUT_GET, 'action' ), 'yoast_dashboard' ) === 0;
|
618 |
+
}
|
619 |
+
|
620 |
+
}
|
googleanalytics.php
CHANGED
@@ -9,7 +9,7 @@
|
|
9 |
* Plugin URI: https://www.monsterinsights.com/pricing/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wpgaplugin&utm_content=v504
|
10 |
* Description: This plugin makes it simple to add Google Analytics to your WordPress site, adding lots of features, e.g. error page, search result and automatic outgoing links and download tracking.
|
11 |
* Author: MonsterInsights
|
12 |
-
* Version: 5.5
|
13 |
* Requires at least: 3.9
|
14 |
* Author URI: https://www.monsterinsights.com/
|
15 |
* License: GPL v3
|
@@ -35,7 +35,7 @@
|
|
35 |
|
36 |
// This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics, but has since been rewritten and refactored multiple times.
|
37 |
|
38 |
-
define( 'GAWP_VERSION', '5.5' );
|
39 |
|
40 |
define( 'GAWP_FILE', __FILE__ );
|
41 |
|
9 |
* Plugin URI: https://www.monsterinsights.com/pricing/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wpgaplugin&utm_content=v504
|
10 |
* Description: This plugin makes it simple to add Google Analytics to your WordPress site, adding lots of features, e.g. error page, search result and automatic outgoing links and download tracking.
|
11 |
* Author: MonsterInsights
|
12 |
+
* Version: 5.5.2
|
13 |
* Requires at least: 3.9
|
14 |
* Author URI: https://www.monsterinsights.com/
|
15 |
* License: GPL v3
|
35 |
|
36 |
// This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics, but has since been rewritten and refactored multiple times.
|
37 |
|
38 |
+
define( 'GAWP_VERSION', '5.5.2' );
|
39 |
|
40 |
define( 'GAWP_FILE', __FILE__ );
|
41 |
|
includes/ecommerce-addon-license-fix.php
CHANGED
@@ -17,15 +17,19 @@ if ( ! class_exists( 'MI_Product_GA_eCommerce', false ) && class_exists( 'MI_Pro
|
|
17 |
|
18 |
|
19 |
public function __construct() {
|
|
|
|
|
|
|
20 |
parent::__construct(
|
21 |
'https://www.monsterinsights.com',
|
22 |
'eCommerce Addon',
|
23 |
-
|
24 |
Yoast_GA_eCommerce_Tracking::VERSION,
|
25 |
'https://www.monsterinsights.com/pricing/',
|
26 |
'admin.php?page=yst_ga_extensions#top#licenses',
|
27 |
'yoast-ga-ecommerce',
|
28 |
-
'MonsterInsights'
|
|
|
29 |
);
|
30 |
|
31 |
$this->setup_license_manager();
|
17 |
|
18 |
|
19 |
public function __construct() {
|
20 |
+
$file = plugin_basename( Yoast_GA_eCommerce_Tracking::PLUGIN_FILE );
|
21 |
+
$slug = dirname( $file );
|
22 |
+
|
23 |
parent::__construct(
|
24 |
'https://www.monsterinsights.com',
|
25 |
'eCommerce Addon',
|
26 |
+
$slug,
|
27 |
Yoast_GA_eCommerce_Tracking::VERSION,
|
28 |
'https://www.monsterinsights.com/pricing/',
|
29 |
'admin.php?page=yst_ga_extensions#top#licenses',
|
30 |
'yoast-ga-ecommerce',
|
31 |
+
'MonsterInsights',
|
32 |
+
$file
|
33 |
);
|
34 |
|
35 |
$this->setup_license_manager();
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: chriscct7, smub
|
|
3 |
Donate link: http://www.wpbeginner.com/wpbeginner-needs-your-help/
|
4 |
Tags: analytics, analytics dashboard, google analytics, google analytics dashboard, google analytics widget, universal google analytics, statistics, tracking, stats, google, yoast, google analytics by yoast, ga, monster insights, monsterinsights, universal analytics, web stats, ecommerce, ecommerce tracking
|
5 |
Requires at least: 3.9
|
6 |
-
Tested up to: 4.
|
7 |
-
Stable tag: 5.5
|
8 |
License: GPL v3
|
9 |
|
10 |
Connect Google Analytics with WordPress by adding your Google Analytics tracking code. Get the stats that matter.
|
@@ -70,6 +70,16 @@ You can also learn about other <a href="http://www.wpbeginner.com/category/plugi
|
|
70 |
|
71 |
== Changelog ==
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
= 5.5 =
|
74 |
|
75 |
Release Date: May 1st, 2016
|
3 |
Donate link: http://www.wpbeginner.com/wpbeginner-needs-your-help/
|
4 |
Tags: analytics, analytics dashboard, google analytics, google analytics dashboard, google analytics widget, universal google analytics, statistics, tracking, stats, google, yoast, google analytics by yoast, ga, monster insights, monsterinsights, universal analytics, web stats, ecommerce, ecommerce tracking
|
5 |
Requires at least: 3.9
|
6 |
+
Tested up to: 4.6
|
7 |
+
Stable tag: 5.5.2
|
8 |
License: GPL v3
|
9 |
|
10 |
Connect Google Analytics with WordPress by adding your Google Analytics tracking code. Get the stats that matter.
|
70 |
|
71 |
== Changelog ==
|
72 |
|
73 |
+
= 5.5.2 =
|
74 |
+
|
75 |
+
Release Date: July 7th, 2016
|
76 |
+
|
77 |
+
* Bugfixes:
|
78 |
+
* Fixes compatibiltiy with upcoming Shiny Updates v2 in WP core
|
79 |
+
|
80 |
+
* Enhancements:
|
81 |
+
* Updates license manager to have more reliable update information including better compatibility with Yoast SEO products.
|
82 |
+
|
83 |
= 5.5 =
|
84 |
|
85 |
Release Date: May 1st, 2016
|
vendor/yoast/license-manager-2/.gitigore
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
.idea/
|
2 |
-
.idea/*
|
1 |
+
.idea/
|
2 |
+
.idea/*
|
vendor/yoast/license-manager-2/class-api-request.php
CHANGED
@@ -1,140 +1,138 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( "Yoast_API_Request", false ) ) {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Handles requests to the Yoast EDD API
|
7 |
-
*/
|
8 |
-
class Yoast_API_Request {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string Request URL
|
12 |
-
*/
|
13 |
-
private $url = '';
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var array Request parameters
|
17 |
-
*/
|
18 |
-
private $args = array(
|
19 |
-
'method' => 'GET',
|
20 |
-
'timeout' => 10,
|
21 |
-
'sslverify' => false,
|
22 |
-
'headers' => array(
|
23 |
-
'Accept-Encoding' => '*',
|
24 |
-
'X-Yoast-EDD' => '1'
|
25 |
-
)
|
26 |
-
);
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @var boolean
|
30 |
-
*/
|
31 |
-
private $success = false;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @var mixed
|
35 |
-
*/
|
36 |
-
private $response;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @var string
|
40 |
-
*/
|
41 |
-
private $error_message = '';
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Constructor
|
45 |
-
*
|
46 |
-
* @param string url
|
47 |
-
* @param array $args
|
48 |
-
*/
|
49 |
-
public function __construct( $url, array $args = array() ) {
|
50 |
-
|
51 |
-
// set api url
|
52 |
-
$this->url = $url;
|
53 |
-
|
54 |
-
// set request args (merge with defaults)
|
55 |
-
$this->args = wp_parse_args( $args, $this->args );
|
56 |
-
|
57 |
-
// fire the request
|
58 |
-
$this->success = $this->fire();
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Fires the request, automatically called from constructor
|
63 |
-
*
|
64 |
-
* @return boolean
|
65 |
-
*/
|
66 |
-
private function fire() {
|
67 |
-
|
68 |
-
// fire request to shop
|
69 |
-
$response = wp_remote_request( $this->url, $this->args );
|
70 |
-
|
71 |
-
// validate raw response
|
72 |
-
if( $this->validate_raw_response( $response ) === false ) {
|
73 |
-
return false;
|
74 |
-
}
|
75 |
-
|
76 |
-
// decode the response
|
77 |
-
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
78 |
-
|
79 |
-
// response should be an object
|
80 |
-
if( ! is_object( $this->response ) ) {
|
81 |
-
$this->error_message = 'No JSON object was returned.';
|
82 |
-
return false;
|
83 |
-
}
|
84 |
-
|
85 |
-
return true;
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* @param object $response
|
90 |
-
* @return boolean
|
91 |
-
*/
|
92 |
-
private function validate_raw_response( $response ) {
|
93 |
-
|
94 |
-
// make sure response came back okay
|
95 |
-
if( is_wp_error( $response ) ) {
|
96 |
-
$this->error_message = $response->get_error_message();
|
97 |
-
return false;
|
98 |
-
}
|
99 |
-
|
100 |
-
// check response code, should be 200
|
101 |
-
$response_code = wp_remote_retrieve_response_code( $response );
|
102 |
-
|
103 |
-
if( false === strstr( $response_code, '200' ) ) {
|
104 |
-
|
105 |
-
$response_message = wp_remote_retrieve_response_message( $response );
|
106 |
-
$this->error_message = "{$response_code} {$response_message}";
|
107 |
-
|
108 |
-
return false;
|
109 |
-
}
|
110 |
-
|
111 |
-
return true;
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Was a valid response returned?
|
116 |
-
*
|
117 |
-
* @return boolean
|
118 |
-
*/
|
119 |
-
public function is_valid() {
|
120 |
-
return ( $this->success === true );
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @return string
|
125 |
-
*/
|
126 |
-
public function get_error_message() {
|
127 |
-
return $this->error_message;
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* @return object
|
132 |
-
*/
|
133 |
-
public function get_response() {
|
134 |
-
return $this->response;
|
135 |
-
}
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
}
|
140 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( "Yoast_API_Request", false ) ) {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Handles requests to the Yoast EDD API
|
7 |
+
*/
|
8 |
+
class Yoast_API_Request {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string Request URL
|
12 |
+
*/
|
13 |
+
private $url = '';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array Request parameters
|
17 |
+
*/
|
18 |
+
private $args = array(
|
19 |
+
'method' => 'GET',
|
20 |
+
'timeout' => 10,
|
21 |
+
'sslverify' => false,
|
22 |
+
'headers' => array(
|
23 |
+
'Accept-Encoding' => '*',
|
24 |
+
'X-Yoast-EDD' => '1'
|
25 |
+
)
|
26 |
+
);
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var boolean
|
30 |
+
*/
|
31 |
+
private $success = false;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var mixed
|
35 |
+
*/
|
36 |
+
private $response;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
private $error_message = '';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Constructor
|
45 |
+
*
|
46 |
+
* @param string url
|
47 |
+
* @param array $args
|
48 |
+
*/
|
49 |
+
public function __construct( $url, array $args = array() ) {
|
50 |
+
|
51 |
+
// set api url
|
52 |
+
$this->url = $url;
|
53 |
+
|
54 |
+
// set request args (merge with defaults)
|
55 |
+
$this->args = wp_parse_args( $args, $this->args );
|
56 |
+
|
57 |
+
// fire the request
|
58 |
+
$this->success = $this->fire();
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Fires the request, automatically called from constructor
|
63 |
+
*
|
64 |
+
* @return boolean
|
65 |
+
*/
|
66 |
+
private function fire() {
|
67 |
+
|
68 |
+
// fire request to shop
|
69 |
+
$response = wp_remote_request( $this->url, $this->args );
|
70 |
+
|
71 |
+
// validate raw response
|
72 |
+
if( $this->validate_raw_response( $response ) === false ) {
|
73 |
+
return false;
|
74 |
+
}
|
75 |
+
|
76 |
+
// decode the response
|
77 |
+
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
78 |
+
|
79 |
+
// response should be an object
|
80 |
+
if( ! is_object( $this->response ) ) {
|
81 |
+
$this->error_message = 'No JSON object was returned.';
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
|
85 |
+
return true;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param object $response
|
90 |
+
* @return boolean
|
91 |
+
*/
|
92 |
+
private function validate_raw_response( $response ) {
|
93 |
+
|
94 |
+
// make sure response came back okay
|
95 |
+
if( is_wp_error( $response ) ) {
|
96 |
+
$this->error_message = $response->get_error_message();
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
// check response code, should be 200
|
101 |
+
$response_code = wp_remote_retrieve_response_code( $response );
|
102 |
+
|
103 |
+
if( false === strstr( $response_code, '200' ) ) {
|
104 |
+
|
105 |
+
$response_message = wp_remote_retrieve_response_message( $response );
|
106 |
+
$this->error_message = "{$response_code} {$response_message}";
|
107 |
+
|
108 |
+
return false;
|
109 |
+
}
|
110 |
+
|
111 |
+
return true;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Was a valid response returned?
|
116 |
+
*
|
117 |
+
* @return boolean
|
118 |
+
*/
|
119 |
+
public function is_valid() {
|
120 |
+
return ( $this->success === true );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @return string
|
125 |
+
*/
|
126 |
+
public function get_error_message() {
|
127 |
+
return $this->error_message;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @return object
|
132 |
+
*/
|
133 |
+
public function get_response() {
|
134 |
+
return $this->response;
|
135 |
+
}
|
136 |
+
}
|
137 |
+
|
138 |
+
}
|
|
|
|
vendor/yoast/license-manager-2/class-license-manager.php
CHANGED
@@ -1,619 +1,613 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( ! interface_exists( 'iYoast_License_Manager', false ) ) {
|
4 |
-
|
5 |
-
interface iYoast_License_Manager {
|
6 |
-
|
7 |
-
public function
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
$message .= sprintf( __( '<a href="%s">
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
$
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
*
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
$
|
442 |
-
|
443 |
-
$
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
case '
|
517 |
-
return $this->
|
518 |
-
break;
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
}
|
615 |
-
|
616 |
-
|
617 |
-
}
|
618 |
-
|
619 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! interface_exists( 'iYoast_License_Manager', false ) ) {
|
4 |
+
|
5 |
+
interface iYoast_License_Manager {
|
6 |
+
public function specific_hooks();
|
7 |
+
public function setup_auto_updater();
|
8 |
+
}
|
9 |
+
|
10 |
+
}
|
11 |
+
|
12 |
+
if ( ! class_exists( 'Yoast_License_Manager', false ) ) {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class Yoast_License_Manager
|
16 |
+
*
|
17 |
+
* @todo Maybe create a license class that contains key and option
|
18 |
+
* @todo Not sure if Yoast_License_Manager is a good name for this class, it's more managing the product (plugin or theme)
|
19 |
+
*/
|
20 |
+
abstract class Yoast_License_Manager implements iYoast_License_Manager {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @const VERSION The version number of the License_Manager class
|
24 |
+
*/
|
25 |
+
const VERSION = 1;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var Yoast_License The license
|
29 |
+
*/
|
30 |
+
protected $product;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
private $license_constant_name = '';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var boolean True if license is defined with a constant
|
39 |
+
*/
|
40 |
+
private $license_constant_is_defined = false;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var boolean True if remote license activation just failed
|
44 |
+
*/
|
45 |
+
private $remote_license_activation_failed = false;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @var array Array of license related options
|
49 |
+
*/
|
50 |
+
private $options = array();
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var string Used to prefix ID's, option names, etc..
|
54 |
+
*/
|
55 |
+
protected $prefix;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @var bool Boolean indicating whether this plugin is network activated
|
59 |
+
*/
|
60 |
+
protected $is_network_activated = false;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Constructor
|
64 |
+
*
|
65 |
+
* @param Yoast_Product $product
|
66 |
+
*/
|
67 |
+
public function __construct( Yoast_Product $product ) {
|
68 |
+
|
69 |
+
// Set the license
|
70 |
+
$this->product = $product;
|
71 |
+
|
72 |
+
// set prefix
|
73 |
+
$this->prefix = sanitize_title_with_dashes( $this->product->get_item_name() . '_', null, 'save' );
|
74 |
+
|
75 |
+
// maybe set license key from constant
|
76 |
+
$this->maybe_set_license_key_from_constant();
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Setup hooks
|
81 |
+
*
|
82 |
+
*/
|
83 |
+
public function setup_hooks() {
|
84 |
+
|
85 |
+
// show admin notice if license is not active
|
86 |
+
add_action( 'admin_notices', array( $this, 'display_admin_notices' ) );
|
87 |
+
|
88 |
+
// catch POST requests from license form
|
89 |
+
add_action( 'admin_init', array( $this, 'catch_post_request' ) );
|
90 |
+
|
91 |
+
// setup item type (plugin|theme) specific hooks
|
92 |
+
$this->specific_hooks();
|
93 |
+
|
94 |
+
// setup the auto updater
|
95 |
+
$this->setup_auto_updater();
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Display license specific admin notices, namely:
|
101 |
+
*
|
102 |
+
* - License for the product isn't activated
|
103 |
+
* - External requests are blocked through WP_HTTP_BLOCK_EXTERNAL
|
104 |
+
*/
|
105 |
+
public function display_admin_notices() {
|
106 |
+
|
107 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
// show notice if license is invalid
|
112 |
+
if ( ! $this->license_is_valid() ) {
|
113 |
+
if ( $this->get_license_key() == '' ) {
|
114 |
+
$message = '<b>Warning!</b> You didn\'t set your %s license key yet, which means you\'re missing out on updates and support! <a href="%s">Enter your license key</a> or <a href="%s" target="_blank">get a license here</a>.';
|
115 |
+
} else {
|
116 |
+
$message = '<b>Warning!</b> Your %s license is inactive which means you\'re missing out on updates and support! <a href="%s">Activate your license</a> or <a href="%s" target="_blank">get a license here</a>.';
|
117 |
+
}
|
118 |
+
?>
|
119 |
+
<div class="error">
|
120 |
+
<p><?php printf( __( $message, $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url(), $this->product->get_tracking_url( 'activate-license-notice' ) ); ?></p>
|
121 |
+
</div>
|
122 |
+
<?php
|
123 |
+
}
|
124 |
+
|
125 |
+
// show notice if external requests are blocked through the WP_HTTP_BLOCK_EXTERNAL constant
|
126 |
+
if ( defined( "WP_HTTP_BLOCK_EXTERNAL" ) && WP_HTTP_BLOCK_EXTERNAL === true ) {
|
127 |
+
|
128 |
+
// check if our API endpoint is in the allowed hosts
|
129 |
+
$host = parse_url( $this->product->get_api_url(), PHP_URL_HOST );
|
130 |
+
|
131 |
+
if ( ! defined( "WP_ACCESSIBLE_HOSTS" ) || stristr( WP_ACCESSIBLE_HOSTS, $host ) === false ) {
|
132 |
+
?>
|
133 |
+
<div class="error">
|
134 |
+
<p><?php printf( __( '<b>Warning!</b> You\'re blocking external requests which means you won\'t be able to get %s updates. Please add %s to %s.', $this->product->get_text_domain() ), $this->product->get_item_name(), '<strong>' . $host . '</strong>', '<code>WP_ACCESSIBLE_HOSTS</code>' ); ?></p>
|
135 |
+
</div>
|
136 |
+
<?php
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Set a notice to display in the admin area
|
144 |
+
*
|
145 |
+
* @param string $type error|updated
|
146 |
+
* @param string $message The message to display
|
147 |
+
*/
|
148 |
+
protected function set_notice( $message, $success = true ) {
|
149 |
+
$css_class = ( $success ) ? 'updated' : 'error';
|
150 |
+
add_settings_error( $this->prefix . 'license', 'license-notice', $message, $css_class );
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Remotely activate License
|
155 |
+
* @return boolean True if the license is now activated, false if not
|
156 |
+
*/
|
157 |
+
public function activate_license() {
|
158 |
+
|
159 |
+
$result = $this->call_license_api( 'activate' );
|
160 |
+
|
161 |
+
|
162 |
+
if ( $result ) {
|
163 |
+
|
164 |
+
// story expiry date
|
165 |
+
if ( isset( $result->expires ) ) {
|
166 |
+
$this->set_license_expiry_date( $result->expires );
|
167 |
+
$expiry_date = strtotime( $result->expires );
|
168 |
+
} else {
|
169 |
+
$expiry_date = false;
|
170 |
+
}
|
171 |
+
|
172 |
+
// show success notice if license is valid
|
173 |
+
if ( $result->license === 'valid' ) {
|
174 |
+
|
175 |
+
$message = sprintf( __( "Your %s license has been activated. ", $this->product->get_text_domain() ), $this->product->get_item_name() );
|
176 |
+
|
177 |
+
// show a custom notice if users have an unlimited license
|
178 |
+
if ( $result->license_limit == 0 ) {
|
179 |
+
$message .= __( "You have an unlimited license. ", $this->product->get_text_domain() );
|
180 |
+
} else {
|
181 |
+
$message .= sprintf( __( "You have used %d/%d activations. ", $this->product->get_text_domain() ), $result->site_count, $result->license_limit );
|
182 |
+
}
|
183 |
+
|
184 |
+
// add upgrade notice if user has less than 3 activations left
|
185 |
+
if ( $result->license_limit > 0 && ( $result->license_limit - $result->site_count ) <= 3 ) {
|
186 |
+
$message .= sprintf( __( '<a href="%s">Did you know you can upgrade your license?</a>', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-nearing-limit-notice' ) );
|
187 |
+
// add extend notice if license is expiring in less than 1 month
|
188 |
+
} elseif ( $expiry_date !== false && $expiry_date < strtotime( "+1 month" ) ) {
|
189 |
+
$days_left = round( ( $expiry_date - strtotime( "now" ) ) / 86400 );
|
190 |
+
$message .= sprintf( __( '<a href="%s">Your license is expiring in %d days, would you like to extend it?</a>', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-expiring-notice' ), $days_left );
|
191 |
+
}
|
192 |
+
|
193 |
+
$this->set_notice( $message, true );
|
194 |
+
|
195 |
+
} else {
|
196 |
+
|
197 |
+
if ( isset( $result->error ) && $result->error === 'no_activations_left' ) {
|
198 |
+
// show notice if user is at their activation limit
|
199 |
+
$this->set_notice( sprintf( __( 'You\'ve reached your activation limit. You must <a href="%s">upgrade your license</a> to use it on this site.', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-at-limit-notice' ) ), false );
|
200 |
+
} elseif ( isset( $result->error ) && $result->error == "expired" ) {
|
201 |
+
// show notice if the license is expired
|
202 |
+
$this->set_notice( sprintf( __( 'Your license has expired. You must <a href="%s">extend your license</a> in order to use it again.', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-expired-notice' ) ), false );
|
203 |
+
} else {
|
204 |
+
// show a general notice if it's any other error
|
205 |
+
$this->set_notice( __( "Failed to activate your license, your license key seems to be invalid.", $this->product->get_text_domain() ), false );
|
206 |
+
}
|
207 |
+
|
208 |
+
$this->remote_license_activation_failed = true;
|
209 |
+
}
|
210 |
+
|
211 |
+
$this->set_license_status( $result->license );
|
212 |
+
}
|
213 |
+
|
214 |
+
return ( $this->license_is_valid() );
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Remotely deactivate License
|
219 |
+
* @return boolean True if the license is now deactivated, false if not
|
220 |
+
*/
|
221 |
+
public function deactivate_license() {
|
222 |
+
|
223 |
+
$result = $this->call_license_api( 'deactivate' );
|
224 |
+
|
225 |
+
if ( $result ) {
|
226 |
+
|
227 |
+
// show notice if license is deactivated
|
228 |
+
if ( $result->license === 'deactivated' ) {
|
229 |
+
$this->set_notice( sprintf( __( "Your %s license has been deactivated.", $this->product->get_text_domain() ), $this->product->get_item_name() ) );
|
230 |
+
} else {
|
231 |
+
$this->set_notice( sprintf( __( "Failed to deactivate your %s license.", $this->product->get_text_domain() ), $this->product->get_item_name() ), false );
|
232 |
+
}
|
233 |
+
|
234 |
+
$this->set_license_status( $result->license );
|
235 |
+
}
|
236 |
+
|
237 |
+
return ( $this->get_license_status() === 'deactivated' );
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* @param string $action activate|deactivate
|
242 |
+
*
|
243 |
+
* @return mixed
|
244 |
+
*/
|
245 |
+
protected function call_license_api( $action ) {
|
246 |
+
|
247 |
+
// don't make a request if license key is empty
|
248 |
+
if ( $this->get_license_key() === '' ) {
|
249 |
+
return false;
|
250 |
+
}
|
251 |
+
|
252 |
+
// data to send in our API request
|
253 |
+
$api_params = array(
|
254 |
+
'edd_action' => $action . '_license',
|
255 |
+
'license' => $this->get_license_key(),
|
256 |
+
'item_name' => urlencode( trim( $this->product->get_item_name() ) ),
|
257 |
+
'url' => get_option( 'home' ) // grab the URL straight from the option to prevent filters from breaking it.
|
258 |
+
);
|
259 |
+
|
260 |
+
// create api request url
|
261 |
+
$url = add_query_arg( $api_params, $this->product->get_api_url() );
|
262 |
+
|
263 |
+
require_once dirname( __FILE__ ) . '/class-api-request.php';
|
264 |
+
$request = new Yoast_API_Request( $url );
|
265 |
+
|
266 |
+
if ( $request->is_valid() !== true ) {
|
267 |
+
$this->set_notice( sprintf( __( "Request error: \"%s\" (%scommon license notices%s)", $this->product->get_text_domain() ), $request->get_error_message(), '<a href="http://kb.yoast.com/article/13-license-activation-notices">', '</a>' ), false );
|
268 |
+
}
|
269 |
+
|
270 |
+
// get response
|
271 |
+
$response = $request->get_response();
|
272 |
+
|
273 |
+
// update license status
|
274 |
+
$license_data = $response;
|
275 |
+
|
276 |
+
return $license_data;
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Set the license status
|
282 |
+
*
|
283 |
+
* @param string $license_status
|
284 |
+
*/
|
285 |
+
public function set_license_status( $license_status ) {
|
286 |
+
$this->set_option( 'status', $license_status );
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* Get the license status
|
291 |
+
*
|
292 |
+
* @return string $license_status;
|
293 |
+
*/
|
294 |
+
public function get_license_status() {
|
295 |
+
$license_status = $this->get_option( 'status' );
|
296 |
+
|
297 |
+
return trim( $license_status );
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Set the license key
|
302 |
+
*
|
303 |
+
* @param string $license_key
|
304 |
+
*/
|
305 |
+
public function set_license_key( $license_key ) {
|
306 |
+
$this->set_option( 'key', $license_key );
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Gets the license key from constant or option
|
311 |
+
*
|
312 |
+
* @return string $license_key
|
313 |
+
*/
|
314 |
+
public function get_license_key() {
|
315 |
+
$license_key = $this->get_option( 'key' );
|
316 |
+
|
317 |
+
return trim( $license_key );
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Gets the license expiry date
|
322 |
+
*
|
323 |
+
* @return string
|
324 |
+
*/
|
325 |
+
public function get_license_expiry_date() {
|
326 |
+
return $this->get_option( 'expiry_date' );
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Stores the license expiry date
|
331 |
+
*/
|
332 |
+
public function set_license_expiry_date( $expiry_date ) {
|
333 |
+
$this->set_option( 'expiry_date', $expiry_date );
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Checks whether the license status is active
|
338 |
+
*
|
339 |
+
* @return boolean True if license is active
|
340 |
+
*/
|
341 |
+
public function license_is_valid() {
|
342 |
+
return ( $this->get_license_status() === 'valid' );
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Get all license related options
|
347 |
+
*
|
348 |
+
* @return array Array of license options
|
349 |
+
*/
|
350 |
+
protected function get_options() {
|
351 |
+
|
352 |
+
// create option name
|
353 |
+
$option_name = $this->prefix . 'license';
|
354 |
+
|
355 |
+
// get array of options from db
|
356 |
+
if ( $this->is_network_activated ) {
|
357 |
+
$options = get_site_option( $option_name, array() );
|
358 |
+
} else {
|
359 |
+
$options = get_option( $option_name, array() );
|
360 |
+
}
|
361 |
+
|
362 |
+
// setup array of defaults
|
363 |
+
$defaults = array(
|
364 |
+
'key' => '',
|
365 |
+
'status' => '',
|
366 |
+
'expiry_date' => ''
|
367 |
+
);
|
368 |
+
|
369 |
+
// merge options with defaults
|
370 |
+
$this->options = wp_parse_args( $options, $defaults );
|
371 |
+
|
372 |
+
return $this->options;
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Set license related options
|
377 |
+
*
|
378 |
+
* @param array $options Array of new license options
|
379 |
+
*/
|
380 |
+
protected function set_options( array $options ) {
|
381 |
+
// create option name
|
382 |
+
$option_name = $this->prefix . 'license';
|
383 |
+
|
384 |
+
// update db
|
385 |
+
if ( $this->is_network_activated ) {
|
386 |
+
update_site_option( $option_name, $options );
|
387 |
+
} else {
|
388 |
+
update_option( $option_name, $options );
|
389 |
+
}
|
390 |
+
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Gets a license related option
|
395 |
+
*
|
396 |
+
* @param string $name The option name
|
397 |
+
*
|
398 |
+
* @return mixed The option value
|
399 |
+
*/
|
400 |
+
protected function get_option( $name ) {
|
401 |
+
$options = $this->get_options();
|
402 |
+
|
403 |
+
return $options[$name];
|
404 |
+
}
|
405 |
+
|
406 |
+
/**
|
407 |
+
* Set a license related option
|
408 |
+
*
|
409 |
+
* @param string $name The option name
|
410 |
+
* @param mixed $value The option value
|
411 |
+
*/
|
412 |
+
protected function set_option( $name, $value ) {
|
413 |
+
// get options
|
414 |
+
$options = $this->get_options();
|
415 |
+
|
416 |
+
// update option
|
417 |
+
$options[$name] = $value;
|
418 |
+
|
419 |
+
// save options
|
420 |
+
$this->set_options( $options );
|
421 |
+
}
|
422 |
+
|
423 |
+
public function show_license_form_heading() {
|
424 |
+
?>
|
425 |
+
<h3>
|
426 |
+
<?php printf( __( "%s: License Settings", $this->product->get_text_domain() ), $this->product->get_item_name() ); ?>
|
427 |
+
</h3>
|
428 |
+
<?php
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* Show a form where users can enter their license key
|
433 |
+
*
|
434 |
+
* @param boolean $embedded Boolean indicating whether this form is embedded in another form?
|
435 |
+
*/
|
436 |
+
public function show_license_form( $embedded = true ) {
|
437 |
+
$key_name = $this->prefix . 'license_key';
|
438 |
+
$nonce_name = $this->prefix . 'license_nonce';
|
439 |
+
$action_name = $this->prefix . 'license_action';
|
440 |
+
|
441 |
+
$api_host_available = $this->get_api_availability();
|
442 |
+
|
443 |
+
$visible_license_key = $this->get_license_key();
|
444 |
+
|
445 |
+
// obfuscate license key
|
446 |
+
$obfuscate = ( strlen( $this->get_license_key() ) > 5 && ( $this->license_is_valid() || ! $this->remote_license_activation_failed ) );
|
447 |
+
|
448 |
+
if ( $obfuscate ) {
|
449 |
+
$visible_license_key = str_repeat( '*', strlen( $this->get_license_key() ) - 4 ) . substr( $this->get_license_key(), - 4 );
|
450 |
+
}
|
451 |
+
|
452 |
+
// make license key readonly when license key is valid or license is defined with a constant
|
453 |
+
$readonly = ( $this->license_is_valid() || $this->license_constant_is_defined );
|
454 |
+
|
455 |
+
require dirname( __FILE__ ) . '/views/form.php';
|
456 |
+
|
457 |
+
// enqueue script in the footer
|
458 |
+
add_action( 'admin_footer', array( $this, 'output_script' ), 99 );
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Check if the license form has been submitted
|
463 |
+
*/
|
464 |
+
public function catch_post_request() {
|
465 |
+
|
466 |
+
$name = $this->prefix . 'license_key';
|
467 |
+
|
468 |
+
// check if license key was posted and not empty
|
469 |
+
if ( ! isset( $_POST[$name] ) ) {
|
470 |
+
return;
|
471 |
+
}
|
472 |
+
|
473 |
+
// run a quick security check
|
474 |
+
$nonce_name = $this->prefix . 'license_nonce';
|
475 |
+
|
476 |
+
if ( ! check_admin_referer( $nonce_name, $nonce_name ) ) {
|
477 |
+
return;
|
478 |
+
}
|
479 |
+
|
480 |
+
// @TODO: check for user cap?
|
481 |
+
|
482 |
+
// get key from posted value
|
483 |
+
$license_key = $_POST[$name];
|
484 |
+
|
485 |
+
// check if license key doesn't accidentally contain asterisks
|
486 |
+
if ( strstr( $license_key, '*' ) === false ) {
|
487 |
+
|
488 |
+
// sanitize key
|
489 |
+
$license_key = trim( sanitize_key( $_POST[$name] ) );
|
490 |
+
|
491 |
+
// save license key
|
492 |
+
$this->set_license_key( $license_key );
|
493 |
+
}
|
494 |
+
|
495 |
+
// does user have an activated valid license
|
496 |
+
if ( ! $this->license_is_valid() ) {
|
497 |
+
|
498 |
+
// try to auto-activate license
|
499 |
+
return $this->activate_license();
|
500 |
+
|
501 |
+
}
|
502 |
+
|
503 |
+
$action_name = $this->prefix . 'license_action';
|
504 |
+
|
505 |
+
// was one of the action buttons clicked?
|
506 |
+
if ( isset( $_POST[$action_name] ) ) {
|
507 |
+
|
508 |
+
$action = trim( $_POST[$action_name] );
|
509 |
+
|
510 |
+
switch ( $action ) {
|
511 |
+
|
512 |
+
case 'activate':
|
513 |
+
return $this->activate_license();
|
514 |
+
break;
|
515 |
+
|
516 |
+
case 'deactivate':
|
517 |
+
return $this->deactivate_license();
|
518 |
+
break;
|
519 |
+
}
|
520 |
+
|
521 |
+
}
|
522 |
+
|
523 |
+
}
|
524 |
+
|
525 |
+
/**
|
526 |
+
* Output the script containing the YoastLicenseManager JS Object
|
527 |
+
*
|
528 |
+
* This takes care of disabling the 'activate' and 'deactivate' buttons
|
529 |
+
*/
|
530 |
+
public function output_script() {
|
531 |
+
require_once dirname( __FILE__ ) . '/views/script.php';
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Set the constant used to define the license
|
536 |
+
*
|
537 |
+
* @param string $license_constant_name The license constant name
|
538 |
+
*/
|
539 |
+
public function set_license_constant_name( $license_constant_name ) {
|
540 |
+
$this->license_constant_name = trim( $license_constant_name );
|
541 |
+
$this->maybe_set_license_key_from_constant();
|
542 |
+
}
|
543 |
+
|
544 |
+
/**
|
545 |
+
* Get the API availability information
|
546 |
+
*
|
547 |
+
* @return array
|
548 |
+
*/
|
549 |
+
protected function get_api_availability(){
|
550 |
+
return array(
|
551 |
+
'url' => $this->product->get_api_url(),
|
552 |
+
'availability' => $this->check_api_host_availability(),
|
553 |
+
'curl_version' => $this->get_curl_version(),
|
554 |
+
);
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Check if the API host address is available from this server
|
559 |
+
*
|
560 |
+
* @return bool
|
561 |
+
*/
|
562 |
+
private function check_api_host_availability() {
|
563 |
+
$wp_http = new WP_Http();
|
564 |
+
if ( $wp_http->block_request( $this->product->get_api_url() ) === false ) {
|
565 |
+
return true;
|
566 |
+
}
|
567 |
+
|
568 |
+
return false;
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Get the current curl version, or false
|
573 |
+
*
|
574 |
+
* @return mixed
|
575 |
+
*/
|
576 |
+
protected function get_curl_version() {
|
577 |
+
if ( function_exists( 'curl_version' ) ) {
|
578 |
+
$curl_version = curl_version();
|
579 |
+
|
580 |
+
if ( isset( $curl_version['version'] ) ) {
|
581 |
+
return $curl_version['version'];
|
582 |
+
}
|
583 |
+
}
|
584 |
+
|
585 |
+
return false;
|
586 |
+
}
|
587 |
+
|
588 |
+
/**
|
589 |
+
* Maybe set license key from a defined constant
|
590 |
+
*/
|
591 |
+
private function maybe_set_license_key_from_constant() {
|
592 |
+
|
593 |
+
if ( empty( $this->license_constant_name ) ) {
|
594 |
+
// generate license constant name
|
595 |
+
$this->set_license_constant_name( strtoupper( str_replace( array( ' ', '-' ), '', sanitize_key( $this->product->get_item_name() ) ) ) . '_LICENSE' );
|
596 |
+
}
|
597 |
+
|
598 |
+
// set license key from constant
|
599 |
+
if ( defined( $this->license_constant_name ) ) {
|
600 |
+
|
601 |
+
$license_constant_value = constant( $this->license_constant_name );
|
602 |
+
|
603 |
+
// update license key value with value of constant
|
604 |
+
if ( $this->get_license_key() !== $license_constant_value ) {
|
605 |
+
$this->set_license_key( $license_constant_value );
|
606 |
+
}
|
607 |
+
|
608 |
+
$this->license_constant_is_defined = true;
|
609 |
+
}
|
610 |
+
}
|
611 |
+
}
|
612 |
+
|
613 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yoast/license-manager-2/class-plugin-license-manager.php
CHANGED
@@ -1,90 +1,90 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( class_exists( 'Yoast_License_Manager' ) && ! class_exists( "Yoast_Plugin_License_Manager", false ) ) {
|
4 |
-
|
5 |
-
class Yoast_Plugin_License_Manager extends Yoast_License_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Constructor
|
9 |
-
*
|
10 |
-
* @param Yoast_Product $product
|
11 |
-
*/
|
12 |
-
public function __construct( Yoast_Product $product ) {
|
13 |
-
|
14 |
-
parent::__construct( $product );
|
15 |
-
|
16 |
-
// Check if plugin is network activated. We should use site(wide) options in that case.
|
17 |
-
if( is_admin() && is_multisite() ) {
|
18 |
-
|
19 |
-
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
20 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
21 |
-
}
|
22 |
-
|
23 |
-
$this->is_network_activated = is_plugin_active_for_network( $product->
|
24 |
-
}
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Setup auto updater for plugins
|
29 |
-
*/
|
30 |
-
public function setup_auto_updater() {
|
31 |
-
if ( $this->license_is_valid() ) {
|
32 |
-
// setup auto updater
|
33 |
-
require_once( dirname( __FILE__ ) . '/class-update-manager.php' );
|
34 |
-
require_once( dirname( __FILE__ ) . '/class-plugin-update-manager.php' );
|
35 |
-
new Yoast_Plugin_Update_Manager( $this->product, $this );
|
36 |
-
}
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Setup hooks
|
41 |
-
*/
|
42 |
-
public function specific_hooks() {
|
43 |
-
|
44 |
-
// deactivate the license remotely on plugin deactivation
|
45 |
-
register_deactivation_hook( $this->product->
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Show a form where users can enter their license key
|
50 |
-
* Takes Multisites into account
|
51 |
-
*
|
52 |
-
* @param bool $embedded
|
53 |
-
* @return null
|
54 |
-
*/
|
55 |
-
public function show_license_form( $embedded = true ) {
|
56 |
-
|
57 |
-
// For non-multisites, always show the license form
|
58 |
-
if( ! is_multisite() ) {
|
59 |
-
parent::show_license_form( $embedded );
|
60 |
-
return;
|
61 |
-
}
|
62 |
-
|
63 |
-
// Plugin is network activated
|
64 |
-
if( $this->is_network_activated ) {
|
65 |
-
|
66 |
-
// We're on the network admin
|
67 |
-
if( is_network_admin() ) {
|
68 |
-
parent::show_license_form( $embedded );
|
69 |
-
} else {
|
70 |
-
// We're not in the network admin area, show a notice
|
71 |
-
parent::show_license_form_heading();
|
72 |
-
if ( is_super_admin() ) {
|
73 |
-
echo "<p>" . sprintf( __( '%s is network activated, you can manage your license in the <a href="%s">network admin license page</a>.', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url() ) . "</p>";
|
74 |
-
} else {
|
75 |
-
echo "<p>" . sprintf( __( '%s is network activated, please contact your site administrator to manage the license.', $this->product->get_text_domain() ), $this->product->get_item_name() ) . "</p>";
|
76 |
-
}
|
77 |
-
|
78 |
-
}
|
79 |
-
|
80 |
-
} else {
|
81 |
-
|
82 |
-
if( false == is_network_admin() ) {
|
83 |
-
parent::show_license_form( $embedded );
|
84 |
-
}
|
85 |
-
|
86 |
-
}
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( class_exists( 'Yoast_License_Manager' ) && ! class_exists( "Yoast_Plugin_License_Manager", false ) ) {
|
4 |
+
|
5 |
+
class Yoast_Plugin_License_Manager extends Yoast_License_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Constructor
|
9 |
+
*
|
10 |
+
* @param Yoast_Product $product
|
11 |
+
*/
|
12 |
+
public function __construct( Yoast_Product $product ) {
|
13 |
+
|
14 |
+
parent::__construct( $product );
|
15 |
+
|
16 |
+
// Check if plugin is network activated. We should use site(wide) options in that case.
|
17 |
+
if( is_admin() && is_multisite() ) {
|
18 |
+
|
19 |
+
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
20 |
+
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
21 |
+
}
|
22 |
+
|
23 |
+
$this->is_network_activated = is_plugin_active_for_network( $product->get_file() );
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Setup auto updater for plugins
|
29 |
+
*/
|
30 |
+
public function setup_auto_updater() {
|
31 |
+
if ( $this->license_is_valid() ) {
|
32 |
+
// setup auto updater
|
33 |
+
require_once( dirname( __FILE__ ) . '/class-update-manager.php' );
|
34 |
+
require_once( dirname( __FILE__ ) . '/class-plugin-update-manager.php' );
|
35 |
+
new Yoast_Plugin_Update_Manager( $this->product, $this );
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Setup hooks
|
41 |
+
*/
|
42 |
+
public function specific_hooks() {
|
43 |
+
|
44 |
+
// deactivate the license remotely on plugin deactivation
|
45 |
+
register_deactivation_hook( $this->product->get_file(), array( $this, 'deactivate_license' ) );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Show a form where users can enter their license key
|
50 |
+
* Takes Multisites into account
|
51 |
+
*
|
52 |
+
* @param bool $embedded
|
53 |
+
* @return null
|
54 |
+
*/
|
55 |
+
public function show_license_form( $embedded = true ) {
|
56 |
+
|
57 |
+
// For non-multisites, always show the license form
|
58 |
+
if( ! is_multisite() ) {
|
59 |
+
parent::show_license_form( $embedded );
|
60 |
+
return;
|
61 |
+
}
|
62 |
+
|
63 |
+
// Plugin is network activated
|
64 |
+
if( $this->is_network_activated ) {
|
65 |
+
|
66 |
+
// We're on the network admin
|
67 |
+
if( is_network_admin() ) {
|
68 |
+
parent::show_license_form( $embedded );
|
69 |
+
} else {
|
70 |
+
// We're not in the network admin area, show a notice
|
71 |
+
parent::show_license_form_heading();
|
72 |
+
if ( is_super_admin() ) {
|
73 |
+
echo "<p>" . sprintf( __( '%s is network activated, you can manage your license in the <a href="%s">network admin license page</a>.', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url() ) . "</p>";
|
74 |
+
} else {
|
75 |
+
echo "<p>" . sprintf( __( '%s is network activated, please contact your site administrator to manage the license.', $this->product->get_text_domain() ), $this->product->get_item_name() ) . "</p>";
|
76 |
+
}
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
} else {
|
81 |
+
|
82 |
+
if( false == is_network_admin() ) {
|
83 |
+
parent::show_license_form( $embedded );
|
84 |
+
}
|
85 |
+
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
}
|
vendor/yoast/license-manager-2/class-plugin-update-manager.php
CHANGED
@@ -1,102 +1,93 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
if
|
49 |
-
return $data;
|
50 |
-
}
|
51 |
-
|
52 |
-
//
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
}
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
*
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
$api_response
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
}
|
95 |
-
|
96 |
-
// return api response
|
97 |
-
return $api_response;
|
98 |
-
}
|
99 |
-
|
100 |
-
}
|
101 |
-
|
102 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( class_exists( 'Yoast_Update_Manager' ) && ! class_exists( "Yoast_Plugin_Update_Manager", false ) ) {
|
4 |
+
|
5 |
+
class Yoast_Plugin_Update_Manager extends Yoast_Update_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Constructor
|
9 |
+
*
|
10 |
+
* @param Yoast_Product $product The Product.
|
11 |
+
* @param string $license_key The License entered.
|
12 |
+
*/
|
13 |
+
public function __construct( Yoast_Product $product, $license_key ) {
|
14 |
+
parent::__construct( $product, $license_key );
|
15 |
+
|
16 |
+
// setup hooks
|
17 |
+
$this->setup_hooks();
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Setup hooks
|
22 |
+
*/
|
23 |
+
private function setup_hooks() {
|
24 |
+
|
25 |
+
// check for updates
|
26 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'set_updates_available_data' ) );
|
27 |
+
|
28 |
+
// get correct plugin information (when viewing details)
|
29 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Check for updates and if so, add to "updates available" data
|
34 |
+
*
|
35 |
+
* @param object $data
|
36 |
+
* @return object $data
|
37 |
+
*/
|
38 |
+
public function set_updates_available_data( $data ) {
|
39 |
+
|
40 |
+
if ( empty( $data ) ) {
|
41 |
+
return $data;
|
42 |
+
}
|
43 |
+
|
44 |
+
// send of API request to check for updates
|
45 |
+
$remote_data = $this->get_remote_data();
|
46 |
+
|
47 |
+
// did we get a response?
|
48 |
+
if( $remote_data === false ) {
|
49 |
+
return $data;
|
50 |
+
}
|
51 |
+
|
52 |
+
// compare local version with remote version
|
53 |
+
if ( version_compare( $this->product->get_version(), $remote_data->new_version, '<' ) ) {
|
54 |
+
|
55 |
+
// remote version is newer, add to data
|
56 |
+
$data->response[ $this->product->get_file() ] = $remote_data;
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
return $data;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Gets new plugin version details (view version x.x.x details)
|
65 |
+
*
|
66 |
+
* @uses api_request()
|
67 |
+
*
|
68 |
+
* @param object $data
|
69 |
+
* @param string $action
|
70 |
+
* @param object $args (optional)
|
71 |
+
*
|
72 |
+
* @return object $data
|
73 |
+
*/
|
74 |
+
public function plugins_api_filter( $data, $action = '', $args = null ) {
|
75 |
+
|
76 |
+
// only do something if we're checking for our plugin
|
77 |
+
if ( $action !== 'plugin_information' || ! isset( $args->slug ) || $args->slug !== $this->product->get_slug() ) {
|
78 |
+
return $data;
|
79 |
+
}
|
80 |
+
|
81 |
+
$api_response = $this->get_remote_data();
|
82 |
+
|
83 |
+
// did we get a response?
|
84 |
+
if ( $api_response === false ) {
|
85 |
+
return $data;
|
86 |
+
}
|
87 |
+
|
88 |
+
// return api response
|
89 |
+
return $api_response;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yoast/license-manager-2/class-product.php
CHANGED
@@ -1,228 +1,292 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( "Yoast_Product", false ) ) {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class Yoast_Product
|
7 |
-
*
|
8 |
-
* @todo create a license class and store an object of it in this class
|
9 |
-
*/
|
10 |
-
class Yoast_Product {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var string The URL of the shop running the EDD API.
|
14 |
-
*/
|
15 |
-
protected $api_url;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string The item name in the EDD shop.
|
19 |
-
*/
|
20 |
-
protected $item_name;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var string The theme slug or plugin file
|
24 |
-
*/
|
25 |
-
protected $slug;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var string The version number of the item
|
29 |
-
*/
|
30 |
-
protected $version;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string The absolute url on which users can purchase a license
|
34 |
-
*/
|
35 |
-
protected $item_url;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @var string Absolute admin URL on which users can enter their license key.
|
39 |
-
*/
|
40 |
-
protected $license_page_url;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* @var string The text domain used for translating strings
|
44 |
-
*/
|
45 |
-
protected $text_domain;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* @var string The item author
|
49 |
-
*/
|
50 |
-
protected $author;
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
$this->
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* @
|
89 |
-
*/
|
90 |
-
public function
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* @
|
96 |
-
*/
|
97 |
-
public function
|
98 |
-
$this->
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @
|
103 |
-
*/
|
104 |
-
public function
|
105 |
-
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* @
|
110 |
-
*/
|
111 |
-
public function
|
112 |
-
$this->
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* @
|
117 |
-
*/
|
118 |
-
public function
|
119 |
-
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* @
|
124 |
-
*/
|
125 |
-
public function
|
126 |
-
$this->
|
127 |
-
}
|
128 |
-
|
129 |
-
/**
|
130 |
-
* @
|
131 |
-
*/
|
132 |
-
public function
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
$
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( "Yoast_Product", false ) ) {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class Yoast_Product
|
7 |
+
*
|
8 |
+
* @todo create a license class and store an object of it in this class
|
9 |
+
*/
|
10 |
+
class Yoast_Product {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var string The URL of the shop running the EDD API.
|
14 |
+
*/
|
15 |
+
protected $api_url;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string The item name in the EDD shop.
|
19 |
+
*/
|
20 |
+
protected $item_name;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string The theme slug or plugin file
|
24 |
+
*/
|
25 |
+
protected $slug;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var string The version number of the item
|
29 |
+
*/
|
30 |
+
protected $version;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string The absolute url on which users can purchase a license
|
34 |
+
*/
|
35 |
+
protected $item_url;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string Absolute admin URL on which users can enter their license key.
|
39 |
+
*/
|
40 |
+
protected $license_page_url;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var string The text domain used for translating strings
|
44 |
+
*/
|
45 |
+
protected $text_domain;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @var string The item author
|
49 |
+
*/
|
50 |
+
protected $author;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var string Relative file path to the plugin.
|
54 |
+
*/
|
55 |
+
protected $file;
|
56 |
+
|
57 |
+
/** @var int Product ID in backend system for quick lookup */
|
58 |
+
protected $product_id;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Yoast_Product constructor.
|
62 |
+
*
|
63 |
+
* @param string $api_url The URL of the shop running the EDD API.
|
64 |
+
* @param string $item_name The item name in the EDD shop.
|
65 |
+
* @param string $slug The slug of the plugin, for shiny updates this needs to be a valid HTML id.
|
66 |
+
* @param string $version The version number of the item.
|
67 |
+
* @param string $item_url The absolute url on which users can purchase a license.
|
68 |
+
* @param string $license_page_url Absolute admin URL on which users can enter their license key.
|
69 |
+
* @param string $text_domain The text domain used for translating strings.
|
70 |
+
* @param string $author The item author.
|
71 |
+
* @param string $file The relative file path to the plugin.
|
72 |
+
* @param int $product_id The ID of the product in the backend system.
|
73 |
+
*/
|
74 |
+
public function __construct( $api_url, $item_name, $slug, $version, $item_url = '', $license_page_url = '#', $text_domain = 'yoast', $author = 'Yoast', $file = '', $product_id = 0 ) {
|
75 |
+
$this->set_api_url( $api_url );
|
76 |
+
$this->set_item_name( $item_name );
|
77 |
+
$this->set_slug( $slug );
|
78 |
+
$this->set_version( $version );
|
79 |
+
$this->set_item_url( $item_url );
|
80 |
+
$this->set_license_page_url( $license_page_url );
|
81 |
+
$this->set_text_domain( $text_domain );
|
82 |
+
$this->set_author( $author );
|
83 |
+
$this->set_file( $file );
|
84 |
+
$this->set_product_id( $product_id );
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param string $api_url
|
89 |
+
*/
|
90 |
+
public function set_api_url( $api_url ) {
|
91 |
+
$this->api_url = $api_url;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return string
|
96 |
+
*/
|
97 |
+
public function get_api_url() {
|
98 |
+
return $this->api_url;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @param string $author
|
103 |
+
*/
|
104 |
+
public function set_author( $author ) {
|
105 |
+
$this->author = $author;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return string
|
110 |
+
*/
|
111 |
+
public function get_author() {
|
112 |
+
return $this->author;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @param string $item_name
|
117 |
+
*/
|
118 |
+
public function set_item_name( $item_name ) {
|
119 |
+
$this->item_name = $item_name;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @return string
|
124 |
+
*/
|
125 |
+
public function get_item_name() {
|
126 |
+
return $this->item_name;
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* @param string $item_url
|
131 |
+
*/
|
132 |
+
public function set_item_url( $item_url ) {
|
133 |
+
if ( empty( $item_url ) ) {
|
134 |
+
$item_url = $this->api_url;
|
135 |
+
}
|
136 |
+
|
137 |
+
$this->item_url = $item_url;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @return string
|
142 |
+
*/
|
143 |
+
public function get_item_url() {
|
144 |
+
return $this->item_url;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @param string $license_page_url
|
149 |
+
*/
|
150 |
+
public function set_license_page_url( $license_page_url ) {
|
151 |
+
|
152 |
+
if ( is_admin() && is_multisite() ) {
|
153 |
+
|
154 |
+
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
155 |
+
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
156 |
+
}
|
157 |
+
|
158 |
+
if ( is_plugin_active_for_network( $this->get_slug() ) ) {
|
159 |
+
$this->license_page_url = network_admin_url( $license_page_url );
|
160 |
+
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
$this->license_page_url = admin_url( $license_page_url );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
public function get_license_page_url() {
|
172 |
+
return $this->license_page_url;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @param string $slug
|
177 |
+
*/
|
178 |
+
public function set_slug( $slug ) {
|
179 |
+
$this->slug = $slug;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* @return string
|
184 |
+
*/
|
185 |
+
public function get_slug() {
|
186 |
+
return $this->slug;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Returns the dirname of the slug and limits it to 15 chars
|
191 |
+
*
|
192 |
+
* @return string
|
193 |
+
*/
|
194 |
+
public function get_transient_prefix() {
|
195 |
+
return substr( md5( $this->file ), 0, 15 );
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @param string $text_domain
|
200 |
+
*/
|
201 |
+
public function set_text_domain( $text_domain ) {
|
202 |
+
$this->text_domain = $text_domain;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @return string
|
207 |
+
*/
|
208 |
+
public function get_text_domain() {
|
209 |
+
return $this->text_domain;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @param string $version
|
214 |
+
*/
|
215 |
+
public function set_version( $version ) {
|
216 |
+
$this->version = $version;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* @return string
|
221 |
+
*/
|
222 |
+
public function get_version() {
|
223 |
+
return $this->version;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Returns the file path relative to the plugins folder
|
228 |
+
*
|
229 |
+
* @return string
|
230 |
+
*/
|
231 |
+
public function get_file() {
|
232 |
+
/*
|
233 |
+
* Fall back to the slug for BC reasons.
|
234 |
+
*
|
235 |
+
* We used to pass the file to the slug field, but this isn't supported with the shiny updates in WordPress.
|
236 |
+
* WordPress uses the slug in the HTML as an ID and a slash isn't a valid
|
237 |
+
*/
|
238 |
+
return empty( $this->file ) ? $this->slug : $this->file;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Sets the file path relative to the plugins folder
|
243 |
+
*
|
244 |
+
* @param string $file Relative file path to the plugin.
|
245 |
+
*/
|
246 |
+
public function set_file( $file ) {
|
247 |
+
$this->file = $file;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Return the Product ID
|
252 |
+
*
|
253 |
+
* @return int
|
254 |
+
*/
|
255 |
+
public function get_product_id() {
|
256 |
+
return $this->product_id;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Set the product ID
|
261 |
+
*
|
262 |
+
* @param int $product_id Product ID to set.
|
263 |
+
*/
|
264 |
+
public function set_product_id( $product_id ) {
|
265 |
+
$this->product_id = (int) $product_id;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Gets a Google Analytics Campaign url for this product
|
270 |
+
*
|
271 |
+
* @param string $link_identifier
|
272 |
+
*
|
273 |
+
* @return string The full URL
|
274 |
+
*/
|
275 |
+
public function get_tracking_url( $link_identifier = '' ) {
|
276 |
+
|
277 |
+
$tracking_vars = array(
|
278 |
+
'utm_campaign' => $this->get_item_name() . ' licensing',
|
279 |
+
'utm_medium' => 'link',
|
280 |
+
'utm_source' => $this->get_item_name(),
|
281 |
+
'utm_content' => $link_identifier
|
282 |
+
);
|
283 |
+
|
284 |
+
// URL encode tracking vars.
|
285 |
+
$tracking_vars = urlencode_deep( $tracking_vars );
|
286 |
+
$query_string = build_query( $tracking_vars );
|
287 |
+
|
288 |
+
return $this->get_item_url() . '#' . $query_string;
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
}
|
vendor/yoast/license-manager-2/class-theme-license-manager.php
CHANGED
@@ -1,53 +1,51 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( class_exists( 'Yoast_License_Manager' ) &&
|
4 |
-
|
5 |
-
class Yoast_Theme_License_Manager extends Yoast_License_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Setup auto updater for themes
|
9 |
-
*/
|
10 |
-
public function setup_auto_updater() {
|
11 |
-
if ( $this->license_is_valid() ) {
|
12 |
-
// setup auto updater
|
13 |
-
require_once dirname( __FILE__ ) . '/class-update-manager.php';
|
14 |
-
require_once dirname( __FILE__ ) . '/class-theme-update-manager.php'; // @TODO: Autoload?
|
15 |
-
new Yoast_Theme_Update_Manager( $this->product, $this );
|
16 |
-
}
|
17 |
-
}
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Setup hooks
|
21 |
-
*/
|
22 |
-
public function specific_hooks() {
|
23 |
-
// remotely deactivate license upon switching away from this theme
|
24 |
-
add_action( 'switch_theme', array( $this, 'deactivate_license' ) );
|
25 |
-
|
26 |
-
// Add the license menu
|
27 |
-
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Add license page and add it to Themes menu
|
32 |
-
*/
|
33 |
-
public function add_license_menu() {
|
34 |
-
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Shows license page
|
39 |
-
*/
|
40 |
-
public function show_license_page() {
|
41 |
-
?>
|
42 |
-
<div class="wrap">
|
43 |
-
<?php settings_errors(); ?>
|
44 |
-
|
45 |
-
<?php $this->show_license_form( false ); ?>
|
46 |
-
</div>
|
47 |
-
<?php
|
48 |
-
}
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( class_exists( 'Yoast_License_Manager' ) && ! class_exists( "Yoast_Theme_License_Manager", false ) ) {
|
4 |
+
|
5 |
+
class Yoast_Theme_License_Manager extends Yoast_License_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Setup auto updater for themes
|
9 |
+
*/
|
10 |
+
public function setup_auto_updater() {
|
11 |
+
if ( $this->license_is_valid() ) {
|
12 |
+
// setup auto updater
|
13 |
+
require_once dirname( __FILE__ ) . '/class-update-manager.php';
|
14 |
+
require_once dirname( __FILE__ ) . '/class-theme-update-manager.php'; // @TODO: Autoload?
|
15 |
+
new Yoast_Theme_Update_Manager( $this->product, $this );
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Setup hooks
|
21 |
+
*/
|
22 |
+
public function specific_hooks() {
|
23 |
+
// remotely deactivate license upon switching away from this theme
|
24 |
+
add_action( 'switch_theme', array( $this, 'deactivate_license' ) );
|
25 |
+
|
26 |
+
// Add the license menu
|
27 |
+
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Add license page and add it to Themes menu
|
32 |
+
*/
|
33 |
+
public function add_license_menu() {
|
34 |
+
add_theme_page( sprintf( __( '%s License', $this->product->get_text_domain() ), $this->product->get_item_name() ), __( 'Theme License', $this->product->get_text_domain() ), 'manage_options', 'theme-license', array( $this, 'show_license_page' ) );
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Shows license page
|
39 |
+
*/
|
40 |
+
public function show_license_page() {
|
41 |
+
?>
|
42 |
+
<div class="wrap">
|
43 |
+
<?php settings_errors(); ?>
|
44 |
+
|
45 |
+
<?php $this->show_license_form( false ); ?>
|
46 |
+
</div>
|
47 |
+
<?php
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
}
|
|
|
|
vendor/yoast/license-manager-2/class-theme-update-manager.php
CHANGED
@@ -1,149 +1,141 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( class_exists( 'Yoast_Update_Manager' ) && ! class_exists(
|
4 |
-
|
5 |
-
class Yoast_Theme_Update_Manager extends Yoast_Update_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
$
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
//
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
// an update is available
|
143 |
-
return $update_data;
|
144 |
-
}
|
145 |
-
|
146 |
-
|
147 |
-
}
|
148 |
-
|
149 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( class_exists( 'Yoast_Update_Manager' ) && ! class_exists( 'Yoast_Theme_Update_Manager', false ) ) {
|
4 |
+
|
5 |
+
class Yoast_Theme_Update_Manager extends Yoast_Update_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Constructor
|
9 |
+
*
|
10 |
+
* @param Yoast_Product $product The Product.
|
11 |
+
* @param string $license_key The License key.
|
12 |
+
*/
|
13 |
+
public function __construct( Yoast_Product $product, $license_key ) {
|
14 |
+
parent::__construct( $product, $license_key );
|
15 |
+
|
16 |
+
// setup hooks
|
17 |
+
$this->setup_hooks();
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get the current theme version
|
22 |
+
*
|
23 |
+
* @return string The version number
|
24 |
+
*/
|
25 |
+
private function get_theme_version() {
|
26 |
+
|
27 |
+
// if version was not set, get it from the Theme stylesheet
|
28 |
+
if ( $this->product->get_version() === '' ) {
|
29 |
+
$theme = wp_get_theme( $this->product->get_slug() );
|
30 |
+
|
31 |
+
return $theme->get( 'Version' );
|
32 |
+
}
|
33 |
+
|
34 |
+
return $this->product->get_version();
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Setup hooks
|
39 |
+
*/
|
40 |
+
private function setup_hooks() {
|
41 |
+
add_filter( 'site_transient_update_themes', array( $this, 'set_theme_update_transient' ) );
|
42 |
+
add_action( 'load-themes.php', array( $this, 'load_themes_screen' ) );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Set "updates available" transient
|
47 |
+
*/
|
48 |
+
public function set_theme_update_transient( $value ) {
|
49 |
+
|
50 |
+
$update_data = $this->get_update_data();
|
51 |
+
|
52 |
+
if ( $update_data === false ) {
|
53 |
+
return $value;
|
54 |
+
}
|
55 |
+
|
56 |
+
// add update data to "updates available" array. convert object to array.
|
57 |
+
$value->response[ $this->product->get_slug() ] = (array) $update_data;
|
58 |
+
|
59 |
+
return $value;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Add hooks and scripts to the Appearance > Themes screen
|
64 |
+
*/
|
65 |
+
public function load_themes_screen() {
|
66 |
+
|
67 |
+
$update_data = $this->get_update_data();
|
68 |
+
|
69 |
+
// only do if an update is available
|
70 |
+
if ( $update_data === false ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
add_thickbox();
|
75 |
+
add_action( 'admin_notices', array( $this, 'show_update_details' ) );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Show update link.
|
80 |
+
* Opens Thickbox with Changelog.
|
81 |
+
*/
|
82 |
+
public function show_update_details() {
|
83 |
+
|
84 |
+
$update_data = $this->get_update_data();
|
85 |
+
|
86 |
+
// only show if an update is available
|
87 |
+
if ( $update_data === false ) {
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
|
91 |
+
$update_url = wp_nonce_url( 'update.php?action=upgrade-theme&theme=' . urlencode( $this->product->get_slug() ), 'upgrade-theme_' . $this->product->get_slug() );
|
92 |
+
$update_onclick = ' onclick="if ( confirm(\'' . esc_js( __( "Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update." ) ) . '\') ) {return true;}return false;"';
|
93 |
+
?>
|
94 |
+
<div id="update-nag">
|
95 |
+
<?php
|
96 |
+
printf(
|
97 |
+
__( '<strong>%s version %s</strong> is available. <a href="%s" class="thickbox" title="%s">Check out what\'s new</a> or <a href="%s" %s>update now</a>.' ),
|
98 |
+
$this->product->get_item_name(),
|
99 |
+
$update_data->new_version,
|
100 |
+
'#TB_inline?width=640&inlineId=' . $this->product->get_slug() . '_changelog',
|
101 |
+
$this->get_item_name(),
|
102 |
+
$update_url,
|
103 |
+
$update_onclick
|
104 |
+
);
|
105 |
+
?>
|
106 |
+
</div>
|
107 |
+
<div id="<?php echo $this->product->get_slug(); ?>_changelog" style="display: none;">
|
108 |
+
<?php echo wpautop( $update_data->sections['changelog'] ); ?>
|
109 |
+
</div>
|
110 |
+
<?php
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get update data
|
115 |
+
*
|
116 |
+
* This gets the update data from a transient (12 hours), if set.
|
117 |
+
* If not, it will make a remote request and get the update data.
|
118 |
+
*
|
119 |
+
* @return object $update_data Object containing the update data
|
120 |
+
*/
|
121 |
+
public function get_update_data() {
|
122 |
+
|
123 |
+
$api_response = $this->get_remote_data();
|
124 |
+
|
125 |
+
if ( false === $api_response ) {
|
126 |
+
return false;
|
127 |
+
}
|
128 |
+
|
129 |
+
$update_data = $api_response;
|
130 |
+
|
131 |
+
// check if a new version is available.
|
132 |
+
if ( version_compare( $this->get_theme_version(), $update_data->new_version, '>=' ) ) {
|
133 |
+
return false;
|
134 |
+
}
|
135 |
+
|
136 |
+
// an update is available
|
137 |
+
return $update_data;
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yoast/license-manager-2/class-update-manager.php
CHANGED
@@ -1,211 +1,216 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( "Yoast_Update_Manager", false ) ) {
|
4 |
-
|
5 |
-
class Yoast_Update_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var Yoast_Product
|
9 |
-
*/
|
10 |
-
protected $product;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var Yoast_License_Manager
|
14 |
-
*/
|
15 |
-
protected $license_manager;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string
|
19 |
-
*/
|
20 |
-
protected $error_message = '';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var object
|
24 |
-
*/
|
25 |
-
protected $update_response = null;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var string The transient name storing the API response
|
29 |
-
*/
|
30 |
-
private $response_transient_key = '';
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string The transient name that stores failed request tries
|
34 |
-
*/
|
35 |
-
private $request_failed_transient_key = '';
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Constructor
|
39 |
-
*
|
40 |
-
* @param
|
41 |
-
* @param
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
$this->
|
49 |
-
$this->
|
50 |
-
|
51 |
-
//
|
52 |
-
$this->
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
*
|
90 |
-
*
|
91 |
-
* @
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
//
|
105 |
-
|
106 |
-
|
107 |
-
//
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
'
|
114 |
-
'
|
115 |
-
'
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
*
|
171 |
-
*
|
172 |
-
*
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( "Yoast_Update_Manager", false ) ) {
|
4 |
+
|
5 |
+
class Yoast_Update_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var Yoast_Product
|
9 |
+
*/
|
10 |
+
protected $product;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var Yoast_License_Manager
|
14 |
+
*/
|
15 |
+
protected $license_manager;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
protected $error_message = '';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var object
|
24 |
+
*/
|
25 |
+
protected $update_response = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var string The transient name storing the API response
|
29 |
+
*/
|
30 |
+
private $response_transient_key = '';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string The transient name that stores failed request tries
|
34 |
+
*/
|
35 |
+
private $request_failed_transient_key = '';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Constructor
|
39 |
+
*
|
40 |
+
* @param Yoast_Product $product The product.
|
41 |
+
* @param Yoast_License_Manager $license_manager The License Manager.
|
42 |
+
*/
|
43 |
+
public function __construct( Yoast_Product $product, $license_manager ) {
|
44 |
+
$this->product = $product;
|
45 |
+
$this->license_manager = $license_manager;
|
46 |
+
|
47 |
+
// generate transient names
|
48 |
+
$this->response_transient_key = $this->product->get_transient_prefix() . '-update-response';
|
49 |
+
$this->request_failed_transient_key = $this->product->get_transient_prefix() . '-update-request-failed';
|
50 |
+
|
51 |
+
// maybe delete transient
|
52 |
+
$this->maybe_delete_transients();
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Deletes the various transients
|
57 |
+
* If we're on the update-core.php?force-check=1 page
|
58 |
+
*/
|
59 |
+
private function maybe_delete_transients() {
|
60 |
+
global $pagenow;
|
61 |
+
|
62 |
+
if ( $pagenow === 'update-core.php' && isset( $_GET['force-check'] ) ) {
|
63 |
+
delete_transient( $this->response_transient_key );
|
64 |
+
delete_transient( $this->request_failed_transient_key );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* If the update check returned a WP_Error, show it to the user
|
70 |
+
*/
|
71 |
+
public function show_update_error() {
|
72 |
+
|
73 |
+
if ( $this->error_message === '' ) {
|
74 |
+
return;
|
75 |
+
}
|
76 |
+
|
77 |
+
?>
|
78 |
+
<div class="error">
|
79 |
+
<p><?php printf( __( '%s failed to check for updates because of the following error: <em>%s</em>', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->error_message ); ?></p>
|
80 |
+
</div>
|
81 |
+
<?php
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
86 |
+
*
|
87 |
+
* @uses get_bloginfo()
|
88 |
+
* @uses wp_remote_post()
|
89 |
+
* @uses is_wp_error()
|
90 |
+
*
|
91 |
+
* @return false||object
|
92 |
+
*/
|
93 |
+
private function call_remote_api() {
|
94 |
+
|
95 |
+
// only check if the failed transient is not set (or if it's expired)
|
96 |
+
if ( get_transient( $this->request_failed_transient_key ) !== false ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
// start request process
|
101 |
+
global $wp_version;
|
102 |
+
|
103 |
+
// set a transient to prevent failed update checks on every page load
|
104 |
+
// this transient will be removed if a request succeeds
|
105 |
+
set_transient( $this->request_failed_transient_key, 'failed', 10800 );
|
106 |
+
|
107 |
+
// setup api parameters
|
108 |
+
$api_params = array(
|
109 |
+
'edd_action' => 'get_version',
|
110 |
+
'license' => $this->license_manager->get_license_key(),
|
111 |
+
'item_name' => $this->product->get_item_name(),
|
112 |
+
'wp_version' => $wp_version,
|
113 |
+
'item_version' => $this->product->get_version(),
|
114 |
+
'url' => home_url(),
|
115 |
+
'slug' => $this->product->get_slug(),
|
116 |
+
);
|
117 |
+
|
118 |
+
// Add product ID from product if it is implemented.
|
119 |
+
if ( method_exists( $this->product, 'get_product_id' ) ) {
|
120 |
+
$product_id = $this->product->get_product_id();
|
121 |
+
if ( $product_id > 0 ) {
|
122 |
+
$api_params['product_id'] = $this->product->get_product_id();
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
// setup request parameters
|
127 |
+
$request_params = array(
|
128 |
+
'method' => 'POST',
|
129 |
+
'body' => $api_params
|
130 |
+
);
|
131 |
+
|
132 |
+
require_once dirname( __FILE__ ) . '/class-api-request.php';
|
133 |
+
$request = new Yoast_API_Request( $this->product->get_api_url(), $request_params );
|
134 |
+
|
135 |
+
if ( $request->is_valid() !== true ) {
|
136 |
+
|
137 |
+
// show error message
|
138 |
+
$this->error_message = $request->get_error_message();
|
139 |
+
add_action( 'admin_notices', array( $this, 'show_update_error' ) );
|
140 |
+
|
141 |
+
return false;
|
142 |
+
}
|
143 |
+
|
144 |
+
// request succeeded, delete transient indicating a request failed
|
145 |
+
delete_transient( $this->request_failed_transient_key );
|
146 |
+
|
147 |
+
// decode response
|
148 |
+
$response = $request->get_response();
|
149 |
+
|
150 |
+
// check if response returned that a given site was inactive
|
151 |
+
if ( isset( $response->license_check ) && ! empty( $response->license_check ) && $response->license_check != 'valid' ) {
|
152 |
+
|
153 |
+
// deactivate local license
|
154 |
+
$this->license_manager->set_license_status( 'invalid' );
|
155 |
+
|
156 |
+
// show notice to let the user know we deactivated his/her license
|
157 |
+
$this->error_message = __( "This site has not been activated properly on yoast.com and thus cannot check for future updates. Please activate your site with a valid license key.", $this->product->get_text_domain() );
|
158 |
+
add_action( 'admin_notices', array( $this, 'show_update_error' ) );
|
159 |
+
}
|
160 |
+
|
161 |
+
$response->sections = maybe_unserialize( $response->sections );
|
162 |
+
|
163 |
+
// store response
|
164 |
+
set_transient( $this->response_transient_key, $response, 10800 );
|
165 |
+
|
166 |
+
return $response;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Gets the remote product data (from the EDD API)
|
171 |
+
*
|
172 |
+
* - If it was previously fetched in the current requests, this gets it from the instance property
|
173 |
+
* - Next, it tries the 3-hour transient
|
174 |
+
* - Next, it calls the remote API and stores the result
|
175 |
+
*
|
176 |
+
* @return object
|
177 |
+
*/
|
178 |
+
protected function get_remote_data() {
|
179 |
+
|
180 |
+
// always use property if it's set
|
181 |
+
if ( null !== $this->update_response ) {
|
182 |
+
return $this->update_response;
|
183 |
+
}
|
184 |
+
|
185 |
+
// get cached remote data
|
186 |
+
$data = $this->get_cached_remote_data();
|
187 |
+
|
188 |
+
// if cache is empty or expired, call remote api
|
189 |
+
if ( $data === false ) {
|
190 |
+
$data = $this->call_remote_api();
|
191 |
+
}
|
192 |
+
|
193 |
+
$this->update_response = $data;
|
194 |
+
|
195 |
+
return $data;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Gets the remote product data from a 3-hour transient
|
200 |
+
*
|
201 |
+
* @return bool|mixed
|
202 |
+
*/
|
203 |
+
private function get_cached_remote_data() {
|
204 |
+
|
205 |
+
$data = get_transient( $this->response_transient_key );
|
206 |
+
|
207 |
+
if ( $data ) {
|
208 |
+
return $data;
|
209 |
+
}
|
210 |
+
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
|
214 |
+
}
|
215 |
+
|
216 |
+
}
|
vendor/yoast/license-manager/.gitigore
CHANGED
@@ -1,2 +1,2 @@
|
|
1 |
-
.idea/
|
2 |
-
.idea/*
|
1 |
+
.idea/
|
2 |
+
.idea/*
|
vendor/yoast/license-manager/README.md
CHANGED
@@ -1,21 +1,21 @@
|
|
1 |
-
Yoast License Manager
|
2 |
-
=====================
|
3 |
-
|
4 |
-
This library will take care of the following.
|
5 |
-
|
6 |
-
- Managing license related options
|
7 |
-
- Setting license key from a constant
|
8 |
-
- Obfuscasting (valid) license keys
|
9 |
-
- Remote license activation / deactivation
|
10 |
-
- Checking for plugin or theme updates
|
11 |
-
|
12 |
-
## Usage
|
13 |
-
|
14 |
-
### Inside Plugins
|
15 |
-
|
16 |
-
A sample plugin is included, [have a look at its source](https://github.com/Yoast/License-Manager/blob/master/samples/sample-plugin.php).
|
17 |
-
|
18 |
-
### Inside Themes
|
19 |
-
|
20 |
-
A sample theme `functions.php` file is included, [have a look here](https://github.com/Yoast/License-Manager/blob/master/samples/sample-theme-functions.php).
|
21 |
-
|
1 |
+
Yoast License Manager
|
2 |
+
=====================
|
3 |
+
|
4 |
+
This library will take care of the following.
|
5 |
+
|
6 |
+
- Managing license related options
|
7 |
+
- Setting license key from a constant
|
8 |
+
- Obfuscasting (valid) license keys
|
9 |
+
- Remote license activation / deactivation
|
10 |
+
- Checking for plugin or theme updates
|
11 |
+
|
12 |
+
## Usage
|
13 |
+
|
14 |
+
### Inside Plugins
|
15 |
+
|
16 |
+
A sample plugin is included, [have a look at its source](https://github.com/Yoast/License-Manager/blob/master/samples/sample-plugin.php).
|
17 |
+
|
18 |
+
### Inside Themes
|
19 |
+
|
20 |
+
A sample theme `functions.php` file is included, [have a look here](https://github.com/Yoast/License-Manager/blob/master/samples/sample-theme-functions.php).
|
21 |
+
|
vendor/yoast/license-manager/class-api-request.php
CHANGED
@@ -1,140 +1,140 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( "MI_API_Request", false ) ) {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Handles requests to the Yoast EDD API
|
7 |
-
*/
|
8 |
-
class MI_API_Request {
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string Request URL
|
12 |
-
*/
|
13 |
-
private $url = '';
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var array Request parameters
|
17 |
-
*/
|
18 |
-
private $args = array(
|
19 |
-
'method' => 'GET',
|
20 |
-
'timeout' => 10,
|
21 |
-
'sslverify' => false,
|
22 |
-
'headers' => array(
|
23 |
-
'Accept-Encoding' => '*',
|
24 |
-
'X-Yoast-EDD' => '1'
|
25 |
-
)
|
26 |
-
);
|
27 |
-
|
28 |
-
/**
|
29 |
-
* @var boolean
|
30 |
-
*/
|
31 |
-
private $success = false;
|
32 |
-
|
33 |
-
/**
|
34 |
-
* @var mixed
|
35 |
-
*/
|
36 |
-
private $response;
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @var string
|
40 |
-
*/
|
41 |
-
private $error_message = '';
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Constructor
|
45 |
-
*
|
46 |
-
* @param string url
|
47 |
-
* @param array $args
|
48 |
-
*/
|
49 |
-
public function __construct( $url, array $args = array() ) {
|
50 |
-
|
51 |
-
// set api url
|
52 |
-
$this->url = $url;
|
53 |
-
|
54 |
-
// set request args (merge with defaults)
|
55 |
-
$this->args = wp_parse_args( $args, $this->args );
|
56 |
-
|
57 |
-
// fire the request
|
58 |
-
$this->success = $this->fire();
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Fires the request, automatically called from constructor
|
63 |
-
*
|
64 |
-
* @return boolean
|
65 |
-
*/
|
66 |
-
private function fire() {
|
67 |
-
|
68 |
-
// fire request to shop
|
69 |
-
$response = wp_remote_request( $this->url, $this->args );
|
70 |
-
|
71 |
-
// validate raw response
|
72 |
-
if( $this->validate_raw_response( $response ) === false ) {
|
73 |
-
return false;
|
74 |
-
}
|
75 |
-
|
76 |
-
// decode the response
|
77 |
-
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
78 |
-
|
79 |
-
// response should be an object
|
80 |
-
if( ! is_object( $this->response ) ) {
|
81 |
-
$this->error_message = 'No JSON object was returned.';
|
82 |
-
return false;
|
83 |
-
}
|
84 |
-
|
85 |
-
return true;
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* @param object $response
|
90 |
-
* @return boolean
|
91 |
-
*/
|
92 |
-
private function validate_raw_response( $response ) {
|
93 |
-
|
94 |
-
// make sure response came back okay
|
95 |
-
if( is_wp_error( $response ) ) {
|
96 |
-
$this->error_message = $response->get_error_message();
|
97 |
-
return false;
|
98 |
-
}
|
99 |
-
|
100 |
-
// check response code, should be 200
|
101 |
-
$response_code = wp_remote_retrieve_response_code( $response );
|
102 |
-
|
103 |
-
if( false === strstr( $response_code, '200' ) ) {
|
104 |
-
|
105 |
-
$response_message = wp_remote_retrieve_response_message( $response );
|
106 |
-
$this->error_message = "{$response_code} {$response_message}";
|
107 |
-
|
108 |
-
return false;
|
109 |
-
}
|
110 |
-
|
111 |
-
return true;
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Was a valid response returned?
|
116 |
-
*
|
117 |
-
* @return boolean
|
118 |
-
*/
|
119 |
-
public function is_valid() {
|
120 |
-
return ( $this->success === true );
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @return string
|
125 |
-
*/
|
126 |
-
public function get_error_message() {
|
127 |
-
return $this->error_message;
|
128 |
-
}
|
129 |
-
|
130 |
-
/**
|
131 |
-
* @return object
|
132 |
-
*/
|
133 |
-
public function get_response() {
|
134 |
-
return $this->response;
|
135 |
-
}
|
136 |
-
|
137 |
-
}
|
138 |
-
|
139 |
-
}
|
140 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( ! class_exists( "MI_API_Request", false ) ) {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Handles requests to the Yoast EDD API
|
7 |
+
*/
|
8 |
+
class MI_API_Request {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* @var string Request URL
|
12 |
+
*/
|
13 |
+
private $url = '';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var array Request parameters
|
17 |
+
*/
|
18 |
+
private $args = array(
|
19 |
+
'method' => 'GET',
|
20 |
+
'timeout' => 10,
|
21 |
+
'sslverify' => false,
|
22 |
+
'headers' => array(
|
23 |
+
'Accept-Encoding' => '*',
|
24 |
+
'X-Yoast-EDD' => '1'
|
25 |
+
)
|
26 |
+
);
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var boolean
|
30 |
+
*/
|
31 |
+
private $success = false;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var mixed
|
35 |
+
*/
|
36 |
+
private $response;
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
private $error_message = '';
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Constructor
|
45 |
+
*
|
46 |
+
* @param string url
|
47 |
+
* @param array $args
|
48 |
+
*/
|
49 |
+
public function __construct( $url, array $args = array() ) {
|
50 |
+
|
51 |
+
// set api url
|
52 |
+
$this->url = $url;
|
53 |
+
|
54 |
+
// set request args (merge with defaults)
|
55 |
+
$this->args = wp_parse_args( $args, $this->args );
|
56 |
+
|
57 |
+
// fire the request
|
58 |
+
$this->success = $this->fire();
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Fires the request, automatically called from constructor
|
63 |
+
*
|
64 |
+
* @return boolean
|
65 |
+
*/
|
66 |
+
private function fire() {
|
67 |
+
|
68 |
+
// fire request to shop
|
69 |
+
$response = wp_remote_request( $this->url, $this->args );
|
70 |
+
|
71 |
+
// validate raw response
|
72 |
+
if( $this->validate_raw_response( $response ) === false ) {
|
73 |
+
return false;
|
74 |
+
}
|
75 |
+
|
76 |
+
// decode the response
|
77 |
+
$this->response = json_decode( wp_remote_retrieve_body( $response ) );
|
78 |
+
|
79 |
+
// response should be an object
|
80 |
+
if( ! is_object( $this->response ) ) {
|
81 |
+
$this->error_message = 'No JSON object was returned.';
|
82 |
+
return false;
|
83 |
+
}
|
84 |
+
|
85 |
+
return true;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* @param object $response
|
90 |
+
* @return boolean
|
91 |
+
*/
|
92 |
+
private function validate_raw_response( $response ) {
|
93 |
+
|
94 |
+
// make sure response came back okay
|
95 |
+
if( is_wp_error( $response ) ) {
|
96 |
+
$this->error_message = $response->get_error_message();
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
// check response code, should be 200
|
101 |
+
$response_code = wp_remote_retrieve_response_code( $response );
|
102 |
+
|
103 |
+
if( false === strstr( $response_code, '200' ) ) {
|
104 |
+
|
105 |
+
$response_message = wp_remote_retrieve_response_message( $response );
|
106 |
+
$this->error_message = "{$response_code} {$response_message}";
|
107 |
+
|
108 |
+
return false;
|
109 |
+
}
|
110 |
+
|
111 |
+
return true;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* Was a valid response returned?
|
116 |
+
*
|
117 |
+
* @return boolean
|
118 |
+
*/
|
119 |
+
public function is_valid() {
|
120 |
+
return ( $this->success === true );
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* @return string
|
125 |
+
*/
|
126 |
+
public function get_error_message() {
|
127 |
+
return $this->error_message;
|
128 |
+
}
|
129 |
+
|
130 |
+
/**
|
131 |
+
* @return object
|
132 |
+
*/
|
133 |
+
public function get_response() {
|
134 |
+
return $this->response;
|
135 |
+
}
|
136 |
+
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
140 |
+
|
vendor/yoast/license-manager/class-license-manager.php
CHANGED
@@ -1,619 +1,613 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( ! interface_exists( 'iMI_License_Manager', false ) ) {
|
4 |
-
|
5 |
-
interface iMI_License_Manager {
|
6 |
-
|
7 |
-
public function
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
$message .= sprintf( __( '<a href="%s">
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
$
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
*
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
$
|
442 |
-
|
443 |
-
$
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
|
485 |
-
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
-
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
|
497 |
-
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
case '
|
517 |
-
return $this->
|
518 |
-
break;
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
|
533 |
-
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
|
561 |
-
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
|
567 |
-
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
|
579 |
-
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
|
596 |
-
|
597 |
-
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
|
614 |
-
}
|
615 |
-
|
616 |
-
|
617 |
-
}
|
618 |
-
|
619 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! interface_exists( 'iMI_License_Manager', false ) ) {
|
4 |
+
|
5 |
+
interface iMI_License_Manager {
|
6 |
+
public function specific_hooks();
|
7 |
+
public function setup_auto_updater();
|
8 |
+
}
|
9 |
+
|
10 |
+
}
|
11 |
+
|
12 |
+
if ( ! class_exists( 'MI_License_Manager', false ) ) {
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class MI_License_Manager
|
16 |
+
*
|
17 |
+
* @todo Maybe create a license class that contains key and option
|
18 |
+
* @todo Not sure if MI_License_Manager is a good name for this class, it's more managing the product (plugin or theme)
|
19 |
+
*/
|
20 |
+
abstract class MI_License_Manager implements iMI_License_Manager {
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @const VERSION The version number of the License_Manager class
|
24 |
+
*/
|
25 |
+
const VERSION = 1;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var MI_License The license
|
29 |
+
*/
|
30 |
+
protected $product;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
private $license_constant_name = '';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var boolean True if license is defined with a constant
|
39 |
+
*/
|
40 |
+
private $license_constant_is_defined = false;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var boolean True if remote license activation just failed
|
44 |
+
*/
|
45 |
+
private $remote_license_activation_failed = false;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @var array Array of license related options
|
49 |
+
*/
|
50 |
+
private $options = array();
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var string Used to prefix ID's, option names, etc..
|
54 |
+
*/
|
55 |
+
protected $prefix;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* @var bool Boolean indicating whether this plugin is network activated
|
59 |
+
*/
|
60 |
+
protected $is_network_activated = false;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Constructor
|
64 |
+
*
|
65 |
+
* @param MI_Product $product
|
66 |
+
*/
|
67 |
+
public function __construct( MI_Product $product ) {
|
68 |
+
|
69 |
+
// Set the license
|
70 |
+
$this->product = $product;
|
71 |
+
|
72 |
+
// set prefix
|
73 |
+
$this->prefix = sanitize_title_with_dashes( $this->product->get_item_name() . '_', null, 'save' );
|
74 |
+
|
75 |
+
// maybe set license key from constant
|
76 |
+
$this->maybe_set_license_key_from_constant();
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Setup hooks
|
81 |
+
*
|
82 |
+
*/
|
83 |
+
public function setup_hooks() {
|
84 |
+
|
85 |
+
// show admin notice if license is not active
|
86 |
+
add_action( 'admin_notices', array( $this, 'display_admin_notices' ) );
|
87 |
+
|
88 |
+
// catch POST requests from license form
|
89 |
+
add_action( 'admin_init', array( $this, 'catch_post_request' ) );
|
90 |
+
|
91 |
+
// setup item type (plugin|theme) specific hooks
|
92 |
+
$this->specific_hooks();
|
93 |
+
|
94 |
+
// setup the auto updater
|
95 |
+
$this->setup_auto_updater();
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Display license specific admin notices, namely:
|
101 |
+
*
|
102 |
+
* - License for the product isn't activated
|
103 |
+
* - External requests are blocked through WP_HTTP_BLOCK_EXTERNAL
|
104 |
+
*/
|
105 |
+
public function display_admin_notices() {
|
106 |
+
|
107 |
+
if ( ! current_user_can( 'manage_options' ) ) {
|
108 |
+
return;
|
109 |
+
}
|
110 |
+
|
111 |
+
// show notice if license is invalid
|
112 |
+
if ( ! $this->license_is_valid() ) {
|
113 |
+
if ( $this->get_license_key() == '' ) {
|
114 |
+
$message = '<b>Warning!</b> You didn\'t set your %s license key yet, which means you\'re missing out on updates and support! <a href="%s">Enter your license key</a> or <a href="%s" target="_blank">get a license here</a>.';
|
115 |
+
} else {
|
116 |
+
$message = '<b>Warning!</b> Your %s license is inactive which means you\'re missing out on updates and support! <a href="%s">Activate your license</a> or <a href="%s" target="_blank">get a license here</a>.';
|
117 |
+
}
|
118 |
+
?>
|
119 |
+
<div class="error">
|
120 |
+
<p><?php printf( __( $message, $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url(), $this->product->get_tracking_url( 'activate-license-notice' ) ); ?></p>
|
121 |
+
</div>
|
122 |
+
<?php
|
123 |
+
}
|
124 |
+
|
125 |
+
// show notice if external requests are blocked through the WP_HTTP_BLOCK_EXTERNAL constant
|
126 |
+
if ( defined( "WP_HTTP_BLOCK_EXTERNAL" ) && WP_HTTP_BLOCK_EXTERNAL === true ) {
|
127 |
+
|
128 |
+
// check if our API endpoint is in the allowed hosts
|
129 |
+
$host = parse_url( $this->product->get_api_url(), PHP_URL_HOST );
|
130 |
+
|
131 |
+
if ( ! defined( "WP_ACCESSIBLE_HOSTS" ) || stristr( WP_ACCESSIBLE_HOSTS, $host ) === false ) {
|
132 |
+
?>
|
133 |
+
<div class="error">
|
134 |
+
<p><?php printf( __( '<b>Warning!</b> You\'re blocking external requests which means you won\'t be able to get %s updates. Please add %s to %s.', $this->product->get_text_domain() ), $this->product->get_item_name(), '<strong>' . $host . '</strong>', '<code>WP_ACCESSIBLE_HOSTS</code>' ); ?></p>
|
135 |
+
</div>
|
136 |
+
<?php
|
137 |
+
}
|
138 |
+
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Set a notice to display in the admin area
|
144 |
+
*
|
145 |
+
* @param string $type error|updated
|
146 |
+
* @param string $message The message to display
|
147 |
+
*/
|
148 |
+
protected function set_notice( $message, $success = true ) {
|
149 |
+
$css_class = ( $success ) ? 'updated' : 'error';
|
150 |
+
add_settings_error( $this->prefix . 'license', 'license-notice', $message, $css_class );
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Remotely activate License
|
155 |
+
* @return boolean True if the license is now activated, false if not
|
156 |
+
*/
|
157 |
+
public function activate_license() {
|
158 |
+
|
159 |
+
$result = $this->call_license_api( 'activate' );
|
160 |
+
|
161 |
+
|
162 |
+
if ( $result ) {
|
163 |
+
|
164 |
+
// story expiry date
|
165 |
+
if ( isset( $result->expires ) ) {
|
166 |
+
$this->set_license_expiry_date( $result->expires );
|
167 |
+
$expiry_date = strtotime( $result->expires );
|
168 |
+
} else {
|
169 |
+
$expiry_date = false;
|
170 |
+
}
|
171 |
+
|
172 |
+
// show success notice if license is valid
|
173 |
+
if ( $result->license === 'valid' ) {
|
174 |
+
|
175 |
+
$message = sprintf( __( "Your %s license has been activated. ", $this->product->get_text_domain() ), $this->product->get_item_name() );
|
176 |
+
|
177 |
+
// show a custom notice if users have an unlimited license
|
178 |
+
if ( $result->license_limit == 0 ) {
|
179 |
+
$message .= __( "You have an unlimited license. ", $this->product->get_text_domain() );
|
180 |
+
} else {
|
181 |
+
$message .= sprintf( __( "You have used %d/%d activations. ", $this->product->get_text_domain() ), $result->site_count, $result->license_limit );
|
182 |
+
}
|
183 |
+
|
184 |
+
// add upgrade notice if user has less than 3 activations left
|
185 |
+
if ( $result->license_limit > 0 && ( $result->license_limit - $result->site_count ) <= 3 ) {
|
186 |
+
$message .= sprintf( __( '<a href="%s">Did you know you can upgrade your license?</a>', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-nearing-limit-notice' ) );
|
187 |
+
// add extend notice if license is expiring in less than 1 month
|
188 |
+
} elseif ( $expiry_date !== false && $expiry_date < strtotime( "+1 month" ) ) {
|
189 |
+
$days_left = round( ( $expiry_date - strtotime( "now" ) ) / 86400 );
|
190 |
+
$message .= sprintf( __( '<a href="%s">Your license is expiring in %d days, would you like to extend it?</a>', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-expiring-notice' ), $days_left );
|
191 |
+
}
|
192 |
+
|
193 |
+
$this->set_notice( $message, true );
|
194 |
+
|
195 |
+
} else {
|
196 |
+
|
197 |
+
if ( isset( $result->error ) && $result->error === 'no_activations_left' ) {
|
198 |
+
// show notice if user is at their activation limit
|
199 |
+
$this->set_notice( sprintf( __( 'You\'ve reached your activation limit. You must <a href="%s">upgrade your license</a> to use it on this site.', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-at-limit-notice' ) ), false );
|
200 |
+
} elseif ( isset( $result->error ) && $result->error == "expired" ) {
|
201 |
+
// show notice if the license is expired
|
202 |
+
$this->set_notice( sprintf( __( 'Your license has expired. You must <a href="%s">extend your license</a> in order to use it again.', $this->product->get_text_domain() ), $this->product->get_tracking_url( 'license-expired-notice' ) ), false );
|
203 |
+
} else {
|
204 |
+
// show a general notice if it's any other error
|
205 |
+
$this->set_notice( __( "Failed to activate your license, your license key seems to be invalid.", $this->product->get_text_domain() ), false );
|
206 |
+
}
|
207 |
+
|
208 |
+
$this->remote_license_activation_failed = true;
|
209 |
+
}
|
210 |
+
|
211 |
+
$this->set_license_status( $result->license );
|
212 |
+
}
|
213 |
+
|
214 |
+
return ( $this->license_is_valid() );
|
215 |
+
}
|
216 |
+
|
217 |
+
/**
|
218 |
+
* Remotely deactivate License
|
219 |
+
* @return boolean True if the license is now deactivated, false if not
|
220 |
+
*/
|
221 |
+
public function deactivate_license() {
|
222 |
+
|
223 |
+
$result = $this->call_license_api( 'deactivate' );
|
224 |
+
|
225 |
+
if ( $result ) {
|
226 |
+
|
227 |
+
// show notice if license is deactivated
|
228 |
+
if ( $result->license === 'deactivated' ) {
|
229 |
+
$this->set_notice( sprintf( __( "Your %s license has been deactivated.", $this->product->get_text_domain() ), $this->product->get_item_name() ) );
|
230 |
+
} else {
|
231 |
+
$this->set_notice( sprintf( __( "Failed to deactivate your %s license.", $this->product->get_text_domain() ), $this->product->get_item_name() ), false );
|
232 |
+
}
|
233 |
+
|
234 |
+
$this->set_license_status( $result->license );
|
235 |
+
}
|
236 |
+
|
237 |
+
return ( $this->get_license_status() === 'deactivated' );
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* @param string $action activate|deactivate
|
242 |
+
*
|
243 |
+
* @return mixed
|
244 |
+
*/
|
245 |
+
protected function call_license_api( $action ) {
|
246 |
+
|
247 |
+
// don't make a request if license key is empty
|
248 |
+
if ( $this->get_license_key() === '' ) {
|
249 |
+
return false;
|
250 |
+
}
|
251 |
+
|
252 |
+
// data to send in our API request
|
253 |
+
$api_params = array(
|
254 |
+
'edd_action' => $action . '_license',
|
255 |
+
'license' => $this->get_license_key(),
|
256 |
+
'item_name' => urlencode( trim( $this->product->get_item_name() ) ),
|
257 |
+
'url' => get_option( 'home' ) // grab the URL straight from the option to prevent filters from breaking it.
|
258 |
+
);
|
259 |
+
|
260 |
+
// create api request url
|
261 |
+
$url = add_query_arg( $api_params, $this->product->get_api_url() );
|
262 |
+
|
263 |
+
require_once dirname( __FILE__ ) . '/class-api-request.php';
|
264 |
+
$request = new MI_API_Request( $url );
|
265 |
+
|
266 |
+
if ( $request->is_valid() !== true ) {
|
267 |
+
$this->set_notice( sprintf( __( "Request error: \"%s\" (%scommon license notices%s)", $this->product->get_text_domain() ), $request->get_error_message(), '<a href="http://kb.yoast.com/article/13-license-activation-notices">', '</a>' ), false );
|
268 |
+
}
|
269 |
+
|
270 |
+
// get response
|
271 |
+
$response = $request->get_response();
|
272 |
+
|
273 |
+
// update license status
|
274 |
+
$license_data = $response;
|
275 |
+
|
276 |
+
return $license_data;
|
277 |
+
}
|
278 |
+
|
279 |
+
|
280 |
+
/**
|
281 |
+
* Set the license status
|
282 |
+
*
|
283 |
+
* @param string $license_status
|
284 |
+
*/
|
285 |
+
public function set_license_status( $license_status ) {
|
286 |
+
$this->set_option( 'status', $license_status );
|
287 |
+
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* Get the license status
|
291 |
+
*
|
292 |
+
* @return string $license_status;
|
293 |
+
*/
|
294 |
+
public function get_license_status() {
|
295 |
+
$license_status = $this->get_option( 'status' );
|
296 |
+
|
297 |
+
return trim( $license_status );
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Set the license key
|
302 |
+
*
|
303 |
+
* @param string $license_key
|
304 |
+
*/
|
305 |
+
public function set_license_key( $license_key ) {
|
306 |
+
$this->set_option( 'key', $license_key );
|
307 |
+
}
|
308 |
+
|
309 |
+
/**
|
310 |
+
* Gets the license key from constant or option
|
311 |
+
*
|
312 |
+
* @return string $license_key
|
313 |
+
*/
|
314 |
+
public function get_license_key() {
|
315 |
+
$license_key = $this->get_option( 'key' );
|
316 |
+
|
317 |
+
return trim( $license_key );
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Gets the license expiry date
|
322 |
+
*
|
323 |
+
* @return string
|
324 |
+
*/
|
325 |
+
public function get_license_expiry_date() {
|
326 |
+
return $this->get_option( 'expiry_date' );
|
327 |
+
}
|
328 |
+
|
329 |
+
/**
|
330 |
+
* Stores the license expiry date
|
331 |
+
*/
|
332 |
+
public function set_license_expiry_date( $expiry_date ) {
|
333 |
+
$this->set_option( 'expiry_date', $expiry_date );
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Checks whether the license status is active
|
338 |
+
*
|
339 |
+
* @return boolean True if license is active
|
340 |
+
*/
|
341 |
+
public function license_is_valid() {
|
342 |
+
return ( $this->get_license_status() === 'valid' );
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Get all license related options
|
347 |
+
*
|
348 |
+
* @return array Array of license options
|
349 |
+
*/
|
350 |
+
protected function get_options() {
|
351 |
+
|
352 |
+
// create option name
|
353 |
+
$option_name = $this->prefix . 'license';
|
354 |
+
|
355 |
+
// get array of options from db
|
356 |
+
if ( $this->is_network_activated ) {
|
357 |
+
$options = get_site_option( $option_name, array() );
|
358 |
+
} else {
|
359 |
+
$options = get_option( $option_name, array() );
|
360 |
+
}
|
361 |
+
|
362 |
+
// setup array of defaults
|
363 |
+
$defaults = array(
|
364 |
+
'key' => '',
|
365 |
+
'status' => '',
|
366 |
+
'expiry_date' => ''
|
367 |
+
);
|
368 |
+
|
369 |
+
// merge options with defaults
|
370 |
+
$this->options = wp_parse_args( $options, $defaults );
|
371 |
+
|
372 |
+
return $this->options;
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Set license related options
|
377 |
+
*
|
378 |
+
* @param array $options Array of new license options
|
379 |
+
*/
|
380 |
+
protected function set_options( array $options ) {
|
381 |
+
// create option name
|
382 |
+
$option_name = $this->prefix . 'license';
|
383 |
+
|
384 |
+
// update db
|
385 |
+
if ( $this->is_network_activated ) {
|
386 |
+
update_site_option( $option_name, $options );
|
387 |
+
} else {
|
388 |
+
update_option( $option_name, $options );
|
389 |
+
}
|
390 |
+
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Gets a license related option
|
395 |
+
*
|
396 |
+
* @param string $name The option name
|
397 |
+
*
|
398 |
+
* @return mixed The option value
|
399 |
+
*/
|
400 |
+
protected function get_option( $name ) {
|
401 |
+
$options = $this->get_options();
|
402 |
+
|
403 |
+
return $options[$name];
|
404 |
+
}
|
405 |
+
|
406 |
+
/**
|
407 |
+
* Set a license related option
|
408 |
+
*
|
409 |
+
* @param string $name The option name
|
410 |
+
* @param mixed $value The option value
|
411 |
+
*/
|
412 |
+
protected function set_option( $name, $value ) {
|
413 |
+
// get options
|
414 |
+
$options = $this->get_options();
|
415 |
+
|
416 |
+
// update option
|
417 |
+
$options[$name] = $value;
|
418 |
+
|
419 |
+
// save options
|
420 |
+
$this->set_options( $options );
|
421 |
+
}
|
422 |
+
|
423 |
+
public function show_license_form_heading() {
|
424 |
+
?>
|
425 |
+
<h3>
|
426 |
+
<?php printf( __( "%s: License Settings", $this->product->get_text_domain() ), $this->product->get_item_name() ); ?>
|
427 |
+
</h3>
|
428 |
+
<?php
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* Show a form where users can enter their license key
|
433 |
+
*
|
434 |
+
* @param boolean $embedded Boolean indicating whether this form is embedded in another form?
|
435 |
+
*/
|
436 |
+
public function show_license_form( $embedded = true ) {
|
437 |
+
$key_name = $this->prefix . 'license_key';
|
438 |
+
$nonce_name = $this->prefix . 'license_nonce';
|
439 |
+
$action_name = $this->prefix . 'license_action';
|
440 |
+
|
441 |
+
$api_host_available = $this->get_api_availability();
|
442 |
+
|
443 |
+
$visible_license_key = $this->get_license_key();
|
444 |
+
|
445 |
+
// obfuscate license key
|
446 |
+
$obfuscate = ( strlen( $this->get_license_key() ) > 5 && ( $this->license_is_valid() || ! $this->remote_license_activation_failed ) );
|
447 |
+
|
448 |
+
if ( $obfuscate ) {
|
449 |
+
$visible_license_key = str_repeat( '*', strlen( $this->get_license_key() ) - 4 ) . substr( $this->get_license_key(), - 4 );
|
450 |
+
}
|
451 |
+
|
452 |
+
// make license key readonly when license key is valid or license is defined with a constant
|
453 |
+
$readonly = ( $this->license_is_valid() || $this->license_constant_is_defined );
|
454 |
+
|
455 |
+
require dirname( __FILE__ ) . '/views/form.php';
|
456 |
+
|
457 |
+
// enqueue script in the footer
|
458 |
+
add_action( 'admin_footer', array( $this, 'output_script' ), 99 );
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Check if the license form has been submitted
|
463 |
+
*/
|
464 |
+
public function catch_post_request() {
|
465 |
+
|
466 |
+
$name = $this->prefix . 'license_key';
|
467 |
+
|
468 |
+
// check if license key was posted and not empty
|
469 |
+
if ( ! isset( $_POST[$name] ) ) {
|
470 |
+
return;
|
471 |
+
}
|
472 |
+
|
473 |
+
// run a quick security check
|
474 |
+
$nonce_name = $this->prefix . 'license_nonce';
|
475 |
+
|
476 |
+
if ( ! check_admin_referer( $nonce_name, $nonce_name ) ) {
|
477 |
+
return;
|
478 |
+
}
|
479 |
+
|
480 |
+
// @TODO: check for user cap?
|
481 |
+
|
482 |
+
// get key from posted value
|
483 |
+
$license_key = $_POST[$name];
|
484 |
+
|
485 |
+
// check if license key doesn't accidentally contain asterisks
|
486 |
+
if ( strstr( $license_key, '*' ) === false ) {
|
487 |
+
|
488 |
+
// sanitize key
|
489 |
+
$license_key = trim( sanitize_key( $_POST[$name] ) );
|
490 |
+
|
491 |
+
// save license key
|
492 |
+
$this->set_license_key( $license_key );
|
493 |
+
}
|
494 |
+
|
495 |
+
// does user have an activated valid license
|
496 |
+
if ( ! $this->license_is_valid() ) {
|
497 |
+
|
498 |
+
// try to auto-activate license
|
499 |
+
return $this->activate_license();
|
500 |
+
|
501 |
+
}
|
502 |
+
|
503 |
+
$action_name = $this->prefix . 'license_action';
|
504 |
+
|
505 |
+
// was one of the action buttons clicked?
|
506 |
+
if ( isset( $_POST[$action_name] ) ) {
|
507 |
+
|
508 |
+
$action = trim( $_POST[$action_name] );
|
509 |
+
|
510 |
+
switch ( $action ) {
|
511 |
+
|
512 |
+
case 'activate':
|
513 |
+
return $this->activate_license();
|
514 |
+
break;
|
515 |
+
|
516 |
+
case 'deactivate':
|
517 |
+
return $this->deactivate_license();
|
518 |
+
break;
|
519 |
+
}
|
520 |
+
|
521 |
+
}
|
522 |
+
|
523 |
+
}
|
524 |
+
|
525 |
+
/**
|
526 |
+
* Output the script containing the MILicenseManager JS Object
|
527 |
+
*
|
528 |
+
* This takes care of disabling the 'activate' and 'deactivate' buttons
|
529 |
+
*/
|
530 |
+
public function output_script() {
|
531 |
+
require_once dirname( __FILE__ ) . '/views/script.php';
|
532 |
+
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Set the constant used to define the license
|
536 |
+
*
|
537 |
+
* @param string $license_constant_name The license constant name
|
538 |
+
*/
|
539 |
+
public function set_license_constant_name( $license_constant_name ) {
|
540 |
+
$this->license_constant_name = trim( $license_constant_name );
|
541 |
+
$this->maybe_set_license_key_from_constant();
|
542 |
+
}
|
543 |
+
|
544 |
+
/**
|
545 |
+
* Get the API availability information
|
546 |
+
*
|
547 |
+
* @return array
|
548 |
+
*/
|
549 |
+
protected function get_api_availability(){
|
550 |
+
return array(
|
551 |
+
'url' => $this->product->get_api_url(),
|
552 |
+
'availability' => $this->check_api_host_availability(),
|
553 |
+
'curl_version' => $this->get_curl_version(),
|
554 |
+
);
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Check if the API host address is available from this server
|
559 |
+
*
|
560 |
+
* @return bool
|
561 |
+
*/
|
562 |
+
private function check_api_host_availability() {
|
563 |
+
$wp_http = new WP_Http();
|
564 |
+
if ( $wp_http->block_request( $this->product->get_api_url() ) === false ) {
|
565 |
+
return true;
|
566 |
+
}
|
567 |
+
|
568 |
+
return false;
|
569 |
+
}
|
570 |
+
|
571 |
+
/**
|
572 |
+
* Get the current curl version, or false
|
573 |
+
*
|
574 |
+
* @return mixed
|
575 |
+
*/
|
576 |
+
protected function get_curl_version() {
|
577 |
+
if ( function_exists( 'curl_version' ) ) {
|
578 |
+
$curl_version = curl_version();
|
579 |
+
|
580 |
+
if ( isset( $curl_version['version'] ) ) {
|
581 |
+
return $curl_version['version'];
|
582 |
+
}
|
583 |
+
}
|
584 |
+
|
585 |
+
return false;
|
586 |
+
}
|
587 |
+
|
588 |
+
/**
|
589 |
+
* Maybe set license key from a defined constant
|
590 |
+
*/
|
591 |
+
private function maybe_set_license_key_from_constant() {
|
592 |
+
|
593 |
+
if ( empty( $this->license_constant_name ) ) {
|
594 |
+
// generate license constant name
|
595 |
+
$this->set_license_constant_name( strtoupper( str_replace( array( ' ', '-' ), '', sanitize_key( $this->product->get_item_name() ) ) ) . '_LICENSE' );
|
596 |
+
}
|
597 |
+
|
598 |
+
// set license key from constant
|
599 |
+
if ( defined( $this->license_constant_name ) ) {
|
600 |
+
|
601 |
+
$license_constant_value = constant( $this->license_constant_name );
|
602 |
+
|
603 |
+
// update license key value with value of constant
|
604 |
+
if ( $this->get_license_key() !== $license_constant_value ) {
|
605 |
+
$this->set_license_key( $license_constant_value );
|
606 |
+
}
|
607 |
+
|
608 |
+
$this->license_constant_is_defined = true;
|
609 |
+
}
|
610 |
+
}
|
611 |
+
}
|
612 |
+
|
613 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yoast/license-manager/class-plugin-license-manager.php
CHANGED
@@ -1,90 +1,90 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( class_exists( 'MI_License_Manager' ) && ! class_exists( "MI_Plugin_License_Manager", false ) ) {
|
4 |
-
|
5 |
-
class MI_Plugin_License_Manager extends MI_License_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Constructor
|
9 |
-
*
|
10 |
-
* @param MI_Product $product
|
11 |
-
*/
|
12 |
-
public function __construct( MI_Product $product ) {
|
13 |
-
|
14 |
-
parent::__construct( $product );
|
15 |
-
|
16 |
-
// Check if plugin is network activated. We should use site(wide) options in that case.
|
17 |
-
if( is_admin() && is_multisite() ) {
|
18 |
-
|
19 |
-
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
20 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
21 |
-
}
|
22 |
-
|
23 |
-
$this->is_network_activated = is_plugin_active_for_network( $product->
|
24 |
-
}
|
25 |
-
}
|
26 |
-
|
27 |
-
/**
|
28 |
-
* Setup auto updater for plugins
|
29 |
-
*/
|
30 |
-
public function setup_auto_updater() {
|
31 |
-
if ( $this->license_is_valid() ) {
|
32 |
-
// setup auto updater
|
33 |
-
require_once( dirname( __FILE__ ) . '/class-update-manager.php' );
|
34 |
-
require_once( dirname( __FILE__ ) . '/class-plugin-update-manager.php' );
|
35 |
-
new MI_Plugin_Update_Manager( $this->product, $this );
|
36 |
-
}
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* Setup hooks
|
41 |
-
*/
|
42 |
-
public function specific_hooks() {
|
43 |
-
|
44 |
-
// deactivate the license remotely on plugin deactivation
|
45 |
-
register_deactivation_hook( $this->product->
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Show a form where users can enter their license key
|
50 |
-
* Takes Multisites into account
|
51 |
-
*
|
52 |
-
* @param bool $embedded
|
53 |
-
* @return null
|
54 |
-
*/
|
55 |
-
public function show_license_form( $embedded = true ) {
|
56 |
-
|
57 |
-
// For non-multisites, always show the license form
|
58 |
-
if( ! is_multisite() ) {
|
59 |
-
parent::show_license_form( $embedded );
|
60 |
-
return;
|
61 |
-
}
|
62 |
-
|
63 |
-
// Plugin is network activated
|
64 |
-
if( $this->is_network_activated ) {
|
65 |
-
|
66 |
-
// We're on the network admin
|
67 |
-
if( is_network_admin() ) {
|
68 |
-
parent::show_license_form( $embedded );
|
69 |
-
} else {
|
70 |
-
// We're not in the network admin area, show a notice
|
71 |
-
parent::show_license_form_heading();
|
72 |
-
if ( is_super_admin() ) {
|
73 |
-
echo "<p>" . sprintf( __( '%s is network activated, you can manage your license in the <a href="%s">network admin license page</a>.', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url() ) . "</p>";
|
74 |
-
} else {
|
75 |
-
echo "<p>" . sprintf( __( '%s is network activated, please contact your site administrator to manage the license.', $this->product->get_text_domain() ), $this->product->get_item_name() ) . "</p>";
|
76 |
-
}
|
77 |
-
|
78 |
-
}
|
79 |
-
|
80 |
-
} else {
|
81 |
-
|
82 |
-
if( false == is_network_admin() ) {
|
83 |
-
parent::show_license_form( $embedded );
|
84 |
-
}
|
85 |
-
|
86 |
-
}
|
87 |
-
}
|
88 |
-
}
|
89 |
-
|
90 |
-
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( class_exists( 'MI_License_Manager' ) && ! class_exists( "MI_Plugin_License_Manager", false ) ) {
|
4 |
+
|
5 |
+
class MI_Plugin_License_Manager extends MI_License_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Constructor
|
9 |
+
*
|
10 |
+
* @param MI_Product $product
|
11 |
+
*/
|
12 |
+
public function __construct( MI_Product $product ) {
|
13 |
+
|
14 |
+
parent::__construct( $product );
|
15 |
+
|
16 |
+
// Check if plugin is network activated. We should use site(wide) options in that case.
|
17 |
+
if( is_admin() && is_multisite() ) {
|
18 |
+
|
19 |
+
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
20 |
+
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
21 |
+
}
|
22 |
+
|
23 |
+
$this->is_network_activated = is_plugin_active_for_network( $product->get_file() );
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Setup auto updater for plugins
|
29 |
+
*/
|
30 |
+
public function setup_auto_updater() {
|
31 |
+
if ( $this->license_is_valid() ) {
|
32 |
+
// setup auto updater
|
33 |
+
require_once( dirname( __FILE__ ) . '/class-update-manager.php' );
|
34 |
+
require_once( dirname( __FILE__ ) . '/class-plugin-update-manager.php' );
|
35 |
+
new MI_Plugin_Update_Manager( $this->product, $this );
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Setup hooks
|
41 |
+
*/
|
42 |
+
public function specific_hooks() {
|
43 |
+
|
44 |
+
// deactivate the license remotely on plugin deactivation
|
45 |
+
register_deactivation_hook( $this->product->get_file(), array( $this, 'deactivate_license' ) );
|
46 |
+
}
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Show a form where users can enter their license key
|
50 |
+
* Takes Multisites into account
|
51 |
+
*
|
52 |
+
* @param bool $embedded
|
53 |
+
* @return null
|
54 |
+
*/
|
55 |
+
public function show_license_form( $embedded = true ) {
|
56 |
+
|
57 |
+
// For non-multisites, always show the license form
|
58 |
+
if( ! is_multisite() ) {
|
59 |
+
parent::show_license_form( $embedded );
|
60 |
+
return;
|
61 |
+
}
|
62 |
+
|
63 |
+
// Plugin is network activated
|
64 |
+
if( $this->is_network_activated ) {
|
65 |
+
|
66 |
+
// We're on the network admin
|
67 |
+
if( is_network_admin() ) {
|
68 |
+
parent::show_license_form( $embedded );
|
69 |
+
} else {
|
70 |
+
// We're not in the network admin area, show a notice
|
71 |
+
parent::show_license_form_heading();
|
72 |
+
if ( is_super_admin() ) {
|
73 |
+
echo "<p>" . sprintf( __( '%s is network activated, you can manage your license in the <a href="%s">network admin license page</a>.', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->product->get_license_page_url() ) . "</p>";
|
74 |
+
} else {
|
75 |
+
echo "<p>" . sprintf( __( '%s is network activated, please contact your site administrator to manage the license.', $this->product->get_text_domain() ), $this->product->get_item_name() ) . "</p>";
|
76 |
+
}
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
} else {
|
81 |
+
|
82 |
+
if( false == is_network_admin() ) {
|
83 |
+
parent::show_license_form( $embedded );
|
84 |
+
}
|
85 |
+
|
86 |
+
}
|
87 |
+
}
|
88 |
+
}
|
89 |
+
|
90 |
+
}
|
vendor/yoast/license-manager/class-plugin-update-manager.php
CHANGED
@@ -1,102 +1,93 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
if
|
49 |
-
return $data;
|
50 |
-
}
|
51 |
-
|
52 |
-
//
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
}
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
*
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
$api_response
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
}
|
95 |
-
|
96 |
-
// return api response
|
97 |
-
return $api_response;
|
98 |
-
}
|
99 |
-
|
100 |
-
}
|
101 |
-
|
102 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if( class_exists( 'MI_Update_Manager' ) && ! class_exists( "MI_Plugin_Update_Manager", false ) ) {
|
4 |
+
|
5 |
+
class MI_Plugin_Update_Manager extends MI_Update_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Constructor
|
9 |
+
*
|
10 |
+
* @param MI_Product $product The Product.
|
11 |
+
* @param string $license_key The License entered.
|
12 |
+
*/
|
13 |
+
public function __construct( MI_Product $product, $license_key ) {
|
14 |
+
parent::__construct( $product, $license_key );
|
15 |
+
|
16 |
+
// setup hooks
|
17 |
+
$this->setup_hooks();
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Setup hooks
|
22 |
+
*/
|
23 |
+
private function setup_hooks() {
|
24 |
+
|
25 |
+
// check for updates
|
26 |
+
add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'set_updates_available_data' ) );
|
27 |
+
|
28 |
+
// get correct plugin information (when viewing details)
|
29 |
+
add_filter( 'plugins_api', array( $this, 'plugins_api_filter' ), 10, 3 );
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Check for updates and if so, add to "updates available" data
|
34 |
+
*
|
35 |
+
* @param object $data
|
36 |
+
* @return object $data
|
37 |
+
*/
|
38 |
+
public function set_updates_available_data( $data ) {
|
39 |
+
|
40 |
+
if ( empty( $data ) ) {
|
41 |
+
return $data;
|
42 |
+
}
|
43 |
+
|
44 |
+
// send of API request to check for updates
|
45 |
+
$remote_data = $this->get_remote_data();
|
46 |
+
|
47 |
+
// did we get a response?
|
48 |
+
if( $remote_data === false ) {
|
49 |
+
return $data;
|
50 |
+
}
|
51 |
+
|
52 |
+
// compare local version with remote version
|
53 |
+
if ( version_compare( $this->product->get_version(), $remote_data->new_version, '<' ) ) {
|
54 |
+
|
55 |
+
// remote version is newer, add to data
|
56 |
+
$data->response[ $this->product->get_file() ] = $remote_data;
|
57 |
+
|
58 |
+
}
|
59 |
+
|
60 |
+
return $data;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Gets new plugin version details (view version x.x.x details)
|
65 |
+
*
|
66 |
+
* @uses api_request()
|
67 |
+
*
|
68 |
+
* @param object $data
|
69 |
+
* @param string $action
|
70 |
+
* @param object $args (optional)
|
71 |
+
*
|
72 |
+
* @return object $data
|
73 |
+
*/
|
74 |
+
public function plugins_api_filter( $data, $action = '', $args = null ) {
|
75 |
+
|
76 |
+
// only do something if we're checking for our plugin
|
77 |
+
if ( $action !== 'plugin_information' || ! isset( $args->slug ) || $args->slug !== $this->product->get_slug() ) {
|
78 |
+
return $data;
|
79 |
+
}
|
80 |
+
|
81 |
+
$api_response = $this->get_remote_data();
|
82 |
+
|
83 |
+
// did we get a response?
|
84 |
+
if ( $api_response === false ) {
|
85 |
+
return $data;
|
86 |
+
}
|
87 |
+
|
88 |
+
// return api response
|
89 |
+
return $api_response;
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yoast/license-manager/class-product.php
CHANGED
@@ -1,228 +1,292 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( "MI_Product", false ) ) {
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Class MI_Product
|
7 |
-
*
|
8 |
-
* @todo create a license class and store an object of it in this class
|
9 |
-
*/
|
10 |
-
class MI_Product {
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var string The URL of the shop running the EDD API.
|
14 |
-
*/
|
15 |
-
protected $api_url;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string The item name in the EDD shop.
|
19 |
-
*/
|
20 |
-
protected $item_name;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var string The theme slug or plugin file
|
24 |
-
*/
|
25 |
-
protected $slug;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var string The version number of the item
|
29 |
-
*/
|
30 |
-
protected $version;
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string The absolute url on which users can purchase a license
|
34 |
-
*/
|
35 |
-
protected $item_url;
|
36 |
-
|
37 |
-
/**
|
38 |
-
* @var string Absolute admin URL on which users can enter their license key.
|
39 |
-
*/
|
40 |
-
protected $license_page_url;
|
41 |
-
|
42 |
-
/**
|
43 |
-
* @var string The text domain used for translating strings
|
44 |
-
*/
|
45 |
-
protected $text_domain;
|
46 |
-
|
47 |
-
/**
|
48 |
-
* @var string The item author
|
49 |
-
*/
|
50 |
-
protected $author;
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
$this->
|
85 |
-
}
|
86 |
-
|
87 |
-
/**
|
88 |
-
* @
|
89 |
-
*/
|
90 |
-
public function
|
91 |
-
|
92 |
-
}
|
93 |
-
|
94 |
-
/**
|
95 |
-
* @
|
96 |
-
*/
|
97 |
-
public function
|
98 |
-
$this->
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* @
|
103 |
-
*/
|
104 |
-
public function
|
105 |
-
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* @
|
110 |
-
*/
|
111 |
-
public function
|
112 |
-
$this->
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* @
|
117 |
-
*/
|
118 |
-
public function
|
119 |
-
|
120 |
-
}
|
121 |
-
|
122 |
-
/**
|
123 |
-
* @
|
124 |
-
*/
|
125 |
-
public function
|
126 |
-
$this->
|
127 |
-
}
|
128 |
-
|
129 |
-
/**
|
130 |
-
* @
|
131 |
-
*/
|
132 |
-
public function
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
$
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( "MI_Product", false ) ) {
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Class MI_Product
|
7 |
+
*
|
8 |
+
* @todo create a license class and store an object of it in this class
|
9 |
+
*/
|
10 |
+
class MI_Product {
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var string The URL of the shop running the EDD API.
|
14 |
+
*/
|
15 |
+
protected $api_url;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string The item name in the EDD shop.
|
19 |
+
*/
|
20 |
+
protected $item_name;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string The theme slug or plugin file
|
24 |
+
*/
|
25 |
+
protected $slug;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var string The version number of the item
|
29 |
+
*/
|
30 |
+
protected $version;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string The absolute url on which users can purchase a license
|
34 |
+
*/
|
35 |
+
protected $item_url;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @var string Absolute admin URL on which users can enter their license key.
|
39 |
+
*/
|
40 |
+
protected $license_page_url;
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @var string The text domain used for translating strings
|
44 |
+
*/
|
45 |
+
protected $text_domain;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @var string The item author
|
49 |
+
*/
|
50 |
+
protected $author;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* @var string Relative file path to the plugin.
|
54 |
+
*/
|
55 |
+
protected $file;
|
56 |
+
|
57 |
+
/** @var int Product ID in backend system for quick lookup */
|
58 |
+
protected $product_id;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* MI_Product constructor.
|
62 |
+
*
|
63 |
+
* @param string $api_url The URL of the shop running the EDD API.
|
64 |
+
* @param string $item_name The item name in the EDD shop.
|
65 |
+
* @param string $slug The slug of the plugin, for shiny updates this needs to be a valid HTML id.
|
66 |
+
* @param string $version The version number of the item.
|
67 |
+
* @param string $item_url The absolute url on which users can purchase a license.
|
68 |
+
* @param string $license_page_url Absolute admin URL on which users can enter their license key.
|
69 |
+
* @param string $text_domain The text domain used for translating strings.
|
70 |
+
* @param string $author The item author.
|
71 |
+
* @param string $file The relative file path to the plugin.
|
72 |
+
* @param int $product_id The ID of the product in the backend system.
|
73 |
+
*/
|
74 |
+
public function __construct( $api_url, $item_name, $slug, $version, $item_url = '', $license_page_url = '#', $text_domain = 'yoast', $author = 'MI', $file = '', $product_id = 0 ) {
|
75 |
+
$this->set_api_url( $api_url );
|
76 |
+
$this->set_item_name( $item_name );
|
77 |
+
$this->set_slug( $slug );
|
78 |
+
$this->set_version( $version );
|
79 |
+
$this->set_item_url( $item_url );
|
80 |
+
$this->set_license_page_url( $license_page_url );
|
81 |
+
$this->set_text_domain( $text_domain );
|
82 |
+
$this->set_author( $author );
|
83 |
+
$this->set_file( $file );
|
84 |
+
$this->set_product_id( $product_id );
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* @param string $api_url
|
89 |
+
*/
|
90 |
+
public function set_api_url( $api_url ) {
|
91 |
+
$this->api_url = $api_url;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* @return string
|
96 |
+
*/
|
97 |
+
public function get_api_url() {
|
98 |
+
return $this->api_url;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* @param string $author
|
103 |
+
*/
|
104 |
+
public function set_author( $author ) {
|
105 |
+
$this->author = $author;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* @return string
|
110 |
+
*/
|
111 |
+
public function get_author() {
|
112 |
+
return $this->author;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @param string $item_name
|
117 |
+
*/
|
118 |
+
public function set_item_name( $item_name ) {
|
119 |
+
$this->item_name = $item_name;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* @return string
|
124 |
+
*/
|
125 |
+
public function get_item_name() {
|
126 |
+
return $this->item_name;
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* @param string $item_url
|
131 |
+
*/
|
132 |
+
public function set_item_url( $item_url ) {
|
133 |
+
if ( empty( $item_url ) ) {
|
134 |
+
$item_url = $this->api_url;
|
135 |
+
}
|
136 |
+
|
137 |
+
$this->item_url = $item_url;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* @return string
|
142 |
+
*/
|
143 |
+
public function get_item_url() {
|
144 |
+
return $this->item_url;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* @param string $license_page_url
|
149 |
+
*/
|
150 |
+
public function set_license_page_url( $license_page_url ) {
|
151 |
+
|
152 |
+
if ( is_admin() && is_multisite() ) {
|
153 |
+
|
154 |
+
if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
|
155 |
+
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
156 |
+
}
|
157 |
+
|
158 |
+
if ( is_plugin_active_for_network( $this->get_slug() ) ) {
|
159 |
+
$this->license_page_url = network_admin_url( $license_page_url );
|
160 |
+
|
161 |
+
return;
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
$this->license_page_url = admin_url( $license_page_url );
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
public function get_license_page_url() {
|
172 |
+
return $this->license_page_url;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* @param string $slug
|
177 |
+
*/
|
178 |
+
public function set_slug( $slug ) {
|
179 |
+
$this->slug = $slug;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* @return string
|
184 |
+
*/
|
185 |
+
public function get_slug() {
|
186 |
+
return $this->slug;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Returns the dirname of the slug and limits it to 15 chars
|
191 |
+
*
|
192 |
+
* @return string
|
193 |
+
*/
|
194 |
+
public function get_transient_prefix() {
|
195 |
+
return substr( md5( $this->file ), 0, 15 );
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* @param string $text_domain
|
200 |
+
*/
|
201 |
+
public function set_text_domain( $text_domain ) {
|
202 |
+
$this->text_domain = $text_domain;
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* @return string
|
207 |
+
*/
|
208 |
+
public function get_text_domain() {
|
209 |
+
return $this->text_domain;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* @param string $version
|
214 |
+
*/
|
215 |
+
public function set_version( $version ) {
|
216 |
+
$this->version = $version;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* @return string
|
221 |
+
*/
|
222 |
+
public function get_version() {
|
223 |
+
return $this->version;
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Returns the file path relative to the plugins folder
|
228 |
+
*
|
229 |
+
* @return string
|
230 |
+
*/
|
231 |
+
public function get_file() {
|
232 |
+
/*
|
233 |
+
* Fall back to the slug for BC reasons.
|
234 |
+
*
|
235 |
+
* We used to pass the file to the slug field, but this isn't supported with the shiny updates in WordPress.
|
236 |
+
* WordPress uses the slug in the HTML as an ID and a slash isn't a valid
|
237 |
+
*/
|
238 |
+
return empty( $this->file ) ? $this->slug : $this->file;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Sets the file path relative to the plugins folder
|
243 |
+
*
|
244 |
+
* @param string $file Relative file path to the plugin.
|
245 |
+
*/
|
246 |
+
public function set_file( $file ) {
|
247 |
+
$this->file = $file;
|
248 |
+
}
|
249 |
+
|
250 |
+
/**
|
251 |
+
* Return the Product ID
|
252 |
+
*
|
253 |
+
* @return int
|
254 |
+
*/
|
255 |
+
public function get_product_id() {
|
256 |
+
return $this->product_id;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Set the product ID
|
261 |
+
*
|
262 |
+
* @param int $product_id Product ID to set.
|
263 |
+
*/
|
264 |
+
public function set_product_id( $product_id ) {
|
265 |
+
$this->product_id = (int) $product_id;
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Gets a Google Analytics Campaign url for this product
|
270 |
+
*
|
271 |
+
* @param string $link_identifier
|
272 |
+
*
|
273 |
+
* @return string The full URL
|
274 |
+
*/
|
275 |
+
public function get_tracking_url( $link_identifier = '' ) {
|
276 |
+
|
277 |
+
$tracking_vars = array(
|
278 |
+
'utm_campaign' => $this->get_item_name() . ' licensing',
|
279 |
+
'utm_medium' => 'link',
|
280 |
+
'utm_source' => $this->get_item_name(),
|
281 |
+
'utm_content' => $link_identifier
|
282 |
+
);
|
283 |
+
|
284 |
+
// URL encode tracking vars.
|
285 |
+
$tracking_vars = urlencode_deep( $tracking_vars );
|
286 |
+
$query_string = build_query( $tracking_vars );
|
287 |
+
|
288 |
+
return $this->get_item_url() . '#' . $query_string;
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
}
|
vendor/yoast/license-manager/class-theme-license-manager.php
CHANGED
@@ -1,53 +1,51 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( class_exists( 'MI_License_Manager' ) &&
|
4 |
-
|
5 |
-
class MI_Theme_License_Manager extends MI_License_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* Setup auto updater for themes
|
9 |
-
*/
|
10 |
-
public function setup_auto_updater() {
|
11 |
-
if ( $this->license_is_valid() ) {
|
12 |
-
// setup auto updater
|
13 |
-
require_once dirname( __FILE__ ) . '/class-update-manager.php';
|
14 |
-
require_once dirname( __FILE__ ) . '/class-theme-update-manager.php'; // @TODO: Autoload?
|
15 |
-
new MI_Theme_Update_Manager( $this->product, $this );
|
16 |
-
}
|
17 |
-
}
|
18 |
-
|
19 |
-
/**
|
20 |
-
* Setup hooks
|
21 |
-
*/
|
22 |
-
public function specific_hooks() {
|
23 |
-
// remotely deactivate license upon switching away from this theme
|
24 |
-
add_action( 'switch_theme', array( $this, 'deactivate_license' ) );
|
25 |
-
|
26 |
-
// Add the license menu
|
27 |
-
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Add license page and add it to Themes menu
|
32 |
-
*/
|
33 |
-
public function add_license_menu() {
|
34 |
-
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Shows license page
|
39 |
-
*/
|
40 |
-
public function show_license_page() {
|
41 |
-
?>
|
42 |
-
<div class="wrap">
|
43 |
-
<?php settings_errors(); ?>
|
44 |
-
|
45 |
-
<?php $this->show_license_form( false ); ?>
|
46 |
-
</div>
|
47 |
-
<?php
|
48 |
-
}
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( class_exists( 'MI_License_Manager' ) && ! class_exists( "MI_Theme_License_Manager", false ) ) {
|
4 |
+
|
5 |
+
class MI_Theme_License_Manager extends MI_License_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Setup auto updater for themes
|
9 |
+
*/
|
10 |
+
public function setup_auto_updater() {
|
11 |
+
if ( $this->license_is_valid() ) {
|
12 |
+
// setup auto updater
|
13 |
+
require_once dirname( __FILE__ ) . '/class-update-manager.php';
|
14 |
+
require_once dirname( __FILE__ ) . '/class-theme-update-manager.php'; // @TODO: Autoload?
|
15 |
+
new MI_Theme_Update_Manager( $this->product, $this );
|
16 |
+
}
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Setup hooks
|
21 |
+
*/
|
22 |
+
public function specific_hooks() {
|
23 |
+
// remotely deactivate license upon switching away from this theme
|
24 |
+
add_action( 'switch_theme', array( $this, 'deactivate_license' ) );
|
25 |
+
|
26 |
+
// Add the license menu
|
27 |
+
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Add license page and add it to Themes menu
|
32 |
+
*/
|
33 |
+
public function add_license_menu() {
|
34 |
+
add_theme_page( sprintf( __( '%s License', $this->product->get_text_domain() ), $this->product->get_item_name() ), __( 'Theme License', $this->product->get_text_domain() ), 'manage_options', 'theme-license', array( $this, 'show_license_page' ) );
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Shows license page
|
39 |
+
*/
|
40 |
+
public function show_license_page() {
|
41 |
+
?>
|
42 |
+
<div class="wrap">
|
43 |
+
<?php settings_errors(); ?>
|
44 |
+
|
45 |
+
<?php $this->show_license_form( false ); ?>
|
46 |
+
</div>
|
47 |
+
<?php
|
48 |
+
}
|
49 |
+
}
|
50 |
+
|
51 |
+
}
|
|
|
|
vendor/yoast/license-manager/class-theme-update-manager.php
CHANGED
@@ -1,149 +1,141 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( class_exists( 'MI_Update_Manager' ) && ! class_exists(
|
4 |
-
|
5 |
-
class MI_Theme_Update_Manager extends MI_Update_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
$
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
//
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
// an update is available
|
143 |
-
return $update_data;
|
144 |
-
}
|
145 |
-
|
146 |
-
|
147 |
-
}
|
148 |
-
|
149 |
-
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( class_exists( 'MI_Update_Manager' ) && ! class_exists( 'MI_Theme_Update_Manager', false ) ) {
|
4 |
+
|
5 |
+
class MI_Theme_Update_Manager extends MI_Update_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Constructor
|
9 |
+
*
|
10 |
+
* @param MI_Product $product The Product.
|
11 |
+
* @param string $license_key The License key.
|
12 |
+
*/
|
13 |
+
public function __construct( MI_Product $product, $license_key ) {
|
14 |
+
parent::__construct( $product, $license_key );
|
15 |
+
|
16 |
+
// setup hooks
|
17 |
+
$this->setup_hooks();
|
18 |
+
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get the current theme version
|
22 |
+
*
|
23 |
+
* @return string The version number
|
24 |
+
*/
|
25 |
+
private function get_theme_version() {
|
26 |
+
|
27 |
+
// if version was not set, get it from the Theme stylesheet
|
28 |
+
if ( $this->product->get_version() === '' ) {
|
29 |
+
$theme = wp_get_theme( $this->product->get_slug() );
|
30 |
+
|
31 |
+
return $theme->get( 'Version' );
|
32 |
+
}
|
33 |
+
|
34 |
+
return $this->product->get_version();
|
35 |
+
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Setup hooks
|
39 |
+
*/
|
40 |
+
private function setup_hooks() {
|
41 |
+
add_filter( 'site_transient_update_themes', array( $this, 'set_theme_update_transient' ) );
|
42 |
+
add_action( 'load-themes.php', array( $this, 'load_themes_screen' ) );
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Set "updates available" transient
|
47 |
+
*/
|
48 |
+
public function set_theme_update_transient( $value ) {
|
49 |
+
|
50 |
+
$update_data = $this->get_update_data();
|
51 |
+
|
52 |
+
if ( $update_data === false ) {
|
53 |
+
return $value;
|
54 |
+
}
|
55 |
+
|
56 |
+
// add update data to "updates available" array. convert object to array.
|
57 |
+
$value->response[ $this->product->get_slug() ] = (array) $update_data;
|
58 |
+
|
59 |
+
return $value;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Add hooks and scripts to the Appearance > Themes screen
|
64 |
+
*/
|
65 |
+
public function load_themes_screen() {
|
66 |
+
|
67 |
+
$update_data = $this->get_update_data();
|
68 |
+
|
69 |
+
// only do if an update is available
|
70 |
+
if ( $update_data === false ) {
|
71 |
+
return;
|
72 |
+
}
|
73 |
+
|
74 |
+
add_thickbox();
|
75 |
+
add_action( 'admin_notices', array( $this, 'show_update_details' ) );
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Show update link.
|
80 |
+
* Opens Thickbox with Changelog.
|
81 |
+
*/
|
82 |
+
public function show_update_details() {
|
83 |
+
|
84 |
+
$update_data = $this->get_update_data();
|
85 |
+
|
86 |
+
// only show if an update is available
|
87 |
+
if ( $update_data === false ) {
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
|
91 |
+
$update_url = wp_nonce_url( 'update.php?action=upgrade-theme&theme=' . urlencode( $this->product->get_slug() ), 'upgrade-theme_' . $this->product->get_slug() );
|
92 |
+
$update_onclick = ' onclick="if ( confirm(\'' . esc_js( __( "Updating this theme will lose any customizations you have made. 'Cancel' to stop, 'OK' to update." ) ) . '\') ) {return true;}return false;"';
|
93 |
+
?>
|
94 |
+
<div id="update-nag">
|
95 |
+
<?php
|
96 |
+
printf(
|
97 |
+
__( '<strong>%s version %s</strong> is available. <a href="%s" class="thickbox" title="%s">Check out what\'s new</a> or <a href="%s" %s>update now</a>.' ),
|
98 |
+
$this->product->get_item_name(),
|
99 |
+
$update_data->new_version,
|
100 |
+
'#TB_inline?width=640&inlineId=' . $this->product->get_slug() . '_changelog',
|
101 |
+
$this->get_item_name(),
|
102 |
+
$update_url,
|
103 |
+
$update_onclick
|
104 |
+
);
|
105 |
+
?>
|
106 |
+
</div>
|
107 |
+
<div id="<?php echo $this->product->get_slug(); ?>_changelog" style="display: none;">
|
108 |
+
<?php echo wpautop( $update_data->sections['changelog'] ); ?>
|
109 |
+
</div>
|
110 |
+
<?php
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Get update data
|
115 |
+
*
|
116 |
+
* This gets the update data from a transient (12 hours), if set.
|
117 |
+
* If not, it will make a remote request and get the update data.
|
118 |
+
*
|
119 |
+
* @return object $update_data Object containing the update data
|
120 |
+
*/
|
121 |
+
public function get_update_data() {
|
122 |
+
|
123 |
+
$api_response = $this->get_remote_data();
|
124 |
+
|
125 |
+
if ( false === $api_response ) {
|
126 |
+
return false;
|
127 |
+
}
|
128 |
+
|
129 |
+
$update_data = $api_response;
|
130 |
+
|
131 |
+
// check if a new version is available.
|
132 |
+
if ( version_compare( $this->get_theme_version(), $update_data->new_version, '>=' ) ) {
|
133 |
+
return false;
|
134 |
+
}
|
135 |
+
|
136 |
+
// an update is available
|
137 |
+
return $update_data;
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yoast/license-manager/class-update-manager.php
CHANGED
@@ -1,211 +1,216 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if( ! class_exists( "MI_Update_Manager", false ) ) {
|
4 |
-
|
5 |
-
class MI_Update_Manager {
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var MI_Product
|
9 |
-
*/
|
10 |
-
protected $product;
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var MI_License_Manager
|
14 |
-
*/
|
15 |
-
protected $license_manager;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string
|
19 |
-
*/
|
20 |
-
protected $error_message = '';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var object
|
24 |
-
*/
|
25 |
-
protected $update_response = null;
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var string The transient name storing the API response
|
29 |
-
*/
|
30 |
-
private $response_transient_key = '';
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string The transient name that stores failed request tries
|
34 |
-
*/
|
35 |
-
private $request_failed_transient_key = '';
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Constructor
|
39 |
-
*
|
40 |
-
* @param
|
41 |
-
* @param
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
$this->
|
49 |
-
$this->
|
50 |
-
|
51 |
-
//
|
52 |
-
$this->
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
*
|
90 |
-
*
|
91 |
-
* @
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
//
|
105 |
-
|
106 |
-
|
107 |
-
//
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
'
|
114 |
-
'
|
115 |
-
'
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
*
|
171 |
-
*
|
172 |
-
*
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
if ( ! class_exists( "MI_Update_Manager", false ) ) {
|
4 |
+
|
5 |
+
class MI_Update_Manager {
|
6 |
+
|
7 |
+
/**
|
8 |
+
* @var MI_Product
|
9 |
+
*/
|
10 |
+
protected $product;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* @var MI_License_Manager
|
14 |
+
*/
|
15 |
+
protected $license_manager;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
protected $error_message = '';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var object
|
24 |
+
*/
|
25 |
+
protected $update_response = null;
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var string The transient name storing the API response
|
29 |
+
*/
|
30 |
+
private $response_transient_key = '';
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var string The transient name that stores failed request tries
|
34 |
+
*/
|
35 |
+
private $request_failed_transient_key = '';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Constructor
|
39 |
+
*
|
40 |
+
* @param MI_Product $product The product.
|
41 |
+
* @param MI_License_Manager $license_manager The License Manager.
|
42 |
+
*/
|
43 |
+
public function __construct( MI_Product $product, $license_manager ) {
|
44 |
+
$this->product = $product;
|
45 |
+
$this->license_manager = $license_manager;
|
46 |
+
|
47 |
+
// generate transient names
|
48 |
+
$this->response_transient_key = $this->product->get_transient_prefix() . '-update-response';
|
49 |
+
$this->request_failed_transient_key = $this->product->get_transient_prefix() . '-update-request-failed';
|
50 |
+
|
51 |
+
// maybe delete transient
|
52 |
+
$this->maybe_delete_transients();
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Deletes the various transients
|
57 |
+
* If we're on the update-core.php?force-check=1 page
|
58 |
+
*/
|
59 |
+
private function maybe_delete_transients() {
|
60 |
+
global $pagenow;
|
61 |
+
|
62 |
+
if ( $pagenow === 'update-core.php' && isset( $_GET['force-check'] ) ) {
|
63 |
+
delete_transient( $this->response_transient_key );
|
64 |
+
delete_transient( $this->request_failed_transient_key );
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* If the update check returned a WP_Error, show it to the user
|
70 |
+
*/
|
71 |
+
public function show_update_error() {
|
72 |
+
|
73 |
+
if ( $this->error_message === '' ) {
|
74 |
+
return;
|
75 |
+
}
|
76 |
+
|
77 |
+
?>
|
78 |
+
<div class="error">
|
79 |
+
<p><?php printf( __( '%s failed to check for updates because of the following error: <em>%s</em>', $this->product->get_text_domain() ), $this->product->get_item_name(), $this->error_message ); ?></p>
|
80 |
+
</div>
|
81 |
+
<?php
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Calls the API and, if successfull, returns the object delivered by the API.
|
86 |
+
*
|
87 |
+
* @uses get_bloginfo()
|
88 |
+
* @uses wp_remote_post()
|
89 |
+
* @uses is_wp_error()
|
90 |
+
*
|
91 |
+
* @return false||object
|
92 |
+
*/
|
93 |
+
private function call_remote_api() {
|
94 |
+
|
95 |
+
// only check if the failed transient is not set (or if it's expired)
|
96 |
+
if ( get_transient( $this->request_failed_transient_key ) !== false ) {
|
97 |
+
return false;
|
98 |
+
}
|
99 |
+
|
100 |
+
// start request process
|
101 |
+
global $wp_version;
|
102 |
+
|
103 |
+
// set a transient to prevent failed update checks on every page load
|
104 |
+
// this transient will be removed if a request succeeds
|
105 |
+
set_transient( $this->request_failed_transient_key, 'failed', 10800 );
|
106 |
+
|
107 |
+
// setup api parameters
|
108 |
+
$api_params = array(
|
109 |
+
'edd_action' => 'get_version',
|
110 |
+
'license' => $this->license_manager->get_license_key(),
|
111 |
+
'item_name' => $this->product->get_item_name(),
|
112 |
+
'wp_version' => $wp_version,
|
113 |
+
'item_version' => $this->product->get_version(),
|
114 |
+
'url' => home_url(),
|
115 |
+
'slug' => $this->product->get_slug(),
|
116 |
+
);
|
117 |
+
|
118 |
+
// Add product ID from product if it is implemented.
|
119 |
+
if ( method_exists( $this->product, 'get_product_id' ) ) {
|
120 |
+
$product_id = $this->product->get_product_id();
|
121 |
+
if ( $product_id > 0 ) {
|
122 |
+
$api_params['product_id'] = $this->product->get_product_id();
|
123 |
+
}
|
124 |
+
}
|
125 |
+
|
126 |
+
// setup request parameters
|
127 |
+
$request_params = array(
|
128 |
+
'method' => 'POST',
|
129 |
+
'body' => $api_params
|
130 |
+
);
|
131 |
+
|
132 |
+
require_once dirname( __FILE__ ) . '/class-api-request.php';
|
133 |
+
$request = new MI_API_Request( $this->product->get_api_url(), $request_params );
|
134 |
+
|
135 |
+
if ( $request->is_valid() !== true ) {
|
136 |
+
|
137 |
+
// show error message
|
138 |
+
$this->error_message = $request->get_error_message();
|
139 |
+
add_action( 'admin_notices', array( $this, 'show_update_error' ) );
|
140 |
+
|
141 |
+
return false;
|
142 |
+
}
|
143 |
+
|
144 |
+
// request succeeded, delete transient indicating a request failed
|
145 |
+
delete_transient( $this->request_failed_transient_key );
|
146 |
+
|
147 |
+
// decode response
|
148 |
+
$response = $request->get_response();
|
149 |
+
|
150 |
+
// check if response returned that a given site was inactive
|
151 |
+
if ( isset( $response->license_check ) && ! empty( $response->license_check ) && $response->license_check != 'valid' ) {
|
152 |
+
|
153 |
+
// deactivate local license
|
154 |
+
$this->license_manager->set_license_status( 'invalid' );
|
155 |
+
|
156 |
+
// show notice to let the user know we deactivated his/her license
|
157 |
+
$this->error_message = __( "This site has not been activated properly on yoast.com and thus cannot check for future updates. Please activate your site with a valid license key.", $this->product->get_text_domain() );
|
158 |
+
add_action( 'admin_notices', array( $this, 'show_update_error' ) );
|
159 |
+
}
|
160 |
+
|
161 |
+
$response->sections = maybe_unserialize( $response->sections );
|
162 |
+
|
163 |
+
// store response
|
164 |
+
set_transient( $this->response_transient_key, $response, 10800 );
|
165 |
+
|
166 |
+
return $response;
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Gets the remote product data (from the EDD API)
|
171 |
+
*
|
172 |
+
* - If it was previously fetched in the current requests, this gets it from the instance property
|
173 |
+
* - Next, it tries the 3-hour transient
|
174 |
+
* - Next, it calls the remote API and stores the result
|
175 |
+
*
|
176 |
+
* @return object
|
177 |
+
*/
|
178 |
+
protected function get_remote_data() {
|
179 |
+
|
180 |
+
// always use property if it's set
|
181 |
+
if ( null !== $this->update_response ) {
|
182 |
+
return $this->update_response;
|
183 |
+
}
|
184 |
+
|
185 |
+
// get cached remote data
|
186 |
+
$data = $this->get_cached_remote_data();
|
187 |
+
|
188 |
+
// if cache is empty or expired, call remote api
|
189 |
+
if ( $data === false ) {
|
190 |
+
$data = $this->call_remote_api();
|
191 |
+
}
|
192 |
+
|
193 |
+
$this->update_response = $data;
|
194 |
+
|
195 |
+
return $data;
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Gets the remote product data from a 3-hour transient
|
200 |
+
*
|
201 |
+
* @return bool|mixed
|
202 |
+
*/
|
203 |
+
private function get_cached_remote_data() {
|
204 |
+
|
205 |
+
$data = get_transient( $this->response_transient_key );
|
206 |
+
|
207 |
+
if ( $data ) {
|
208 |
+
return $data;
|
209 |
+
}
|
210 |
+
|
211 |
+
return false;
|
212 |
+
}
|
213 |
+
|
214 |
+
}
|
215 |
+
|
216 |
+
}
|
vendor/yoast/license-manager/composer.json
CHANGED
@@ -1,29 +1,29 @@
|
|
1 |
-
{
|
2 |
-
"name" : "yoast/license-manager",
|
3 |
-
"description": "
|
4 |
-
"keywords" : ["wordpress"],
|
5 |
-
"homepage" : "https://github.com/
|
6 |
-
"license" : "GPL-2.0+",
|
7 |
-
"authors" : [
|
8 |
-
{
|
9 |
-
"name" : "Team
|
10 |
-
"email" : "support@yoast.com",
|
11 |
-
"homepage": "https://yoast.com"
|
12 |
-
}
|
13 |
-
],
|
14 |
-
"support" : {
|
15 |
-
"issues": "https://github.com/
|
16 |
-
},
|
17 |
-
"autoload" : {
|
18 |
-
"classmap": [
|
19 |
-
"class-api-request.php",
|
20 |
-
"class-license-manager.php",
|
21 |
-
"class-plugin-license-manager.php",
|
22 |
-
"class-plugin-update-manager.php",
|
23 |
-
"class-product.php",
|
24 |
-
"class-theme-license-manager.php",
|
25 |
-
"class-theme-update-manager.php",
|
26 |
-
"class-update-manager.php"
|
27 |
-
]
|
28 |
-
}
|
29 |
}
|
1 |
+
{
|
2 |
+
"name" : "yoast/license-manager",
|
3 |
+
"description": "MI License Manager.",
|
4 |
+
"keywords" : ["wordpress"],
|
5 |
+
"homepage" : "https://github.com/MI/License-Manager",
|
6 |
+
"license" : "GPL-2.0+",
|
7 |
+
"authors" : [
|
8 |
+
{
|
9 |
+
"name" : "Team MI",
|
10 |
+
"email" : "support@yoast.com",
|
11 |
+
"homepage": "https://yoast.com"
|
12 |
+
}
|
13 |
+
],
|
14 |
+
"support" : {
|
15 |
+
"issues": "https://github.com/MI/License-Manager/issues"
|
16 |
+
},
|
17 |
+
"autoload" : {
|
18 |
+
"classmap": [
|
19 |
+
"class-api-request.php",
|
20 |
+
"class-license-manager.php",
|
21 |
+
"class-plugin-license-manager.php",
|
22 |
+
"class-plugin-update-manager.php",
|
23 |
+
"class-product.php",
|
24 |
+
"class-theme-license-manager.php",
|
25 |
+
"class-theme-update-manager.php",
|
26 |
+
"class-update-manager.php"
|
27 |
+
]
|
28 |
+
}
|
29 |
}
|
vendor/yoast/license-manager/samples/sample-plugin.php
CHANGED
@@ -1,74 +1,74 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/*
|
4 |
-
Plugin Name: Sample Plugin
|
5 |
-
Version: 1.0
|
6 |
-
Plugin URI: https://www.monsterinsights.com/
|
7 |
-
Description: A sample plugin to test the License Manager
|
8 |
-
Author: chriscct7, msub, DvanKooten
|
9 |
-
Author URI: http://www.monsterinsights.com/
|
10 |
-
Text Domain: sample-plugin
|
11 |
-
*/
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Class Sample_Plugin
|
15 |
-
*
|
16 |
-
*/
|
17 |
-
class Sample_Plugin {
|
18 |
-
|
19 |
-
public function __construct() {
|
20 |
-
|
21 |
-
// we only need license stuff inside the admin area
|
22 |
-
if ( is_admin() ) {
|
23 |
-
|
24 |
-
// add menu item
|
25 |
-
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
26 |
-
|
27 |
-
// load license class
|
28 |
-
$this->load_license_manager();
|
29 |
-
}
|
30 |
-
|
31 |
-
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Loads the License_Plugin_Manager class
|
36 |
-
*
|
37 |
-
* The class will take care of the rest: notices, license (de)activations, updates, etc..
|
38 |
-
*/
|
39 |
-
public function load_license_manager() {
|
40 |
-
|
41 |
-
// Instantiate license class
|
42 |
-
$license_manager = new MI_Plugin_License_Manager( new Sample_Product() );
|
43 |
-
|
44 |
-
// Setup the required hooks
|
45 |
-
$license_manager->setup_hooks();
|
46 |
-
|
47 |
-
}
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Add license page and add it to Themes menu
|
51 |
-
*/
|
52 |
-
public function add_license_menu() {
|
53 |
-
$theme_page = add_options_page( sprintf( __( '%s License', $this->text_domain ), $this->item_name ), sprintf( __( '%s License', $this->text_domain ), $this->item_name ), 'manage_options', $this->text_domain . '-license', array( $this, 'show_license_page' ) );
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Shows license page
|
58 |
-
*/
|
59 |
-
public function show_license_page() {
|
60 |
-
|
61 |
-
// Instantiate license class
|
62 |
-
$license_manager = new MI_Plugin_License_Manager( new Sample_Product() );
|
63 |
-
|
64 |
-
?>
|
65 |
-
<div class="wrap">
|
66 |
-
<?php //settings_errors(); ?>
|
67 |
-
|
68 |
-
<?php $license_manager->show_license_form( false ); ?>
|
69 |
-
</div>
|
70 |
-
<?php
|
71 |
-
}
|
72 |
-
}
|
73 |
-
|
74 |
-
new Sample_Plugin();
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/*
|
4 |
+
Plugin Name: Sample Plugin
|
5 |
+
Version: 1.0
|
6 |
+
Plugin URI: https://www.monsterinsights.com/
|
7 |
+
Description: A sample plugin to test the License Manager
|
8 |
+
Author: chriscct7, msub, DvanKooten
|
9 |
+
Author URI: http://www.monsterinsights.com/
|
10 |
+
Text Domain: sample-plugin
|
11 |
+
*/
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class Sample_Plugin
|
15 |
+
*
|
16 |
+
*/
|
17 |
+
class Sample_Plugin {
|
18 |
+
|
19 |
+
public function __construct() {
|
20 |
+
|
21 |
+
// we only need license stuff inside the admin area
|
22 |
+
if ( is_admin() ) {
|
23 |
+
|
24 |
+
// add menu item
|
25 |
+
add_action( 'admin_menu', array( $this, 'add_license_menu' ) );
|
26 |
+
|
27 |
+
// load license class
|
28 |
+
$this->load_license_manager();
|
29 |
+
}
|
30 |
+
|
31 |
+
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Loads the License_Plugin_Manager class
|
36 |
+
*
|
37 |
+
* The class will take care of the rest: notices, license (de)activations, updates, etc..
|
38 |
+
*/
|
39 |
+
public function load_license_manager() {
|
40 |
+
|
41 |
+
// Instantiate license class
|
42 |
+
$license_manager = new MI_Plugin_License_Manager( new Sample_Product() );
|
43 |
+
|
44 |
+
// Setup the required hooks
|
45 |
+
$license_manager->setup_hooks();
|
46 |
+
|
47 |
+
}
|
48 |
+
|
49 |
+
/**
|
50 |
+
* Add license page and add it to Themes menu
|
51 |
+
*/
|
52 |
+
public function add_license_menu() {
|
53 |
+
$theme_page = add_options_page( sprintf( __( '%s License', $this->text_domain ), $this->item_name ), sprintf( __( '%s License', $this->text_domain ), $this->item_name ), 'manage_options', $this->text_domain . '-license', array( $this, 'show_license_page' ) );
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Shows license page
|
58 |
+
*/
|
59 |
+
public function show_license_page() {
|
60 |
+
|
61 |
+
// Instantiate license class
|
62 |
+
$license_manager = new MI_Plugin_License_Manager( new Sample_Product() );
|
63 |
+
|
64 |
+
?>
|
65 |
+
<div class="wrap">
|
66 |
+
<?php //settings_errors(); ?>
|
67 |
+
|
68 |
+
<?php $license_manager->show_license_form( false ); ?>
|
69 |
+
</div>
|
70 |
+
<?php
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
new Sample_Plugin();
|
vendor/yoast/license-manager/samples/sample-product.php
CHANGED
@@ -1,23 +1,23 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Class Sample_Product
|
5 |
-
*
|
6 |
-
* Our sample product class
|
7 |
-
*/
|
8 |
-
class Sample_Product extends MI_Product {
|
9 |
-
|
10 |
-
public function __construct() {
|
11 |
-
parent::__construct(
|
12 |
-
'https://www.monsterinsights.com',
|
13 |
-
'Sample Product',
|
14 |
-
'sample-product',
|
15 |
-
'1.0',
|
16 |
-
'https://www.monsterinsights.com/downloads/sample-product/',
|
17 |
-
'admin.php?page=sample-product',
|
18 |
-
'sample-product',
|
19 |
-
'MonsterInsights'
|
20 |
-
);
|
21 |
-
}
|
22 |
-
|
23 |
}
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class Sample_Product
|
5 |
+
*
|
6 |
+
* Our sample product class
|
7 |
+
*/
|
8 |
+
class Sample_Product extends MI_Product {
|
9 |
+
|
10 |
+
public function __construct() {
|
11 |
+
parent::__construct(
|
12 |
+
'https://www.monsterinsights.com',
|
13 |
+
'Sample Product',
|
14 |
+
'sample-product',
|
15 |
+
'1.0',
|
16 |
+
'https://www.monsterinsights.com/downloads/sample-product/',
|
17 |
+
'admin.php?page=sample-product',
|
18 |
+
'sample-product',
|
19 |
+
'MonsterInsights'
|
20 |
+
);
|
21 |
+
}
|
22 |
+
|
23 |
}
|