Passed
Push — master ( 0b7aa3...1e9d3c )
by Chris
08:25
created

monsterinsights_automatic_updates()   D

Complexity

Conditions 27
Paths 108

Size

Total Lines 72
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 27
eloc 38
c 2
b 0
f 0
nc 108
nop 2
dl 0
loc 72
rs 4.1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * Check to see if the plugin file path matches the main pro plugin or an add-on of ours
4
 *
5
 * @param $plugin_file
6
 *
7
 * @return bool
8
 */
9
function monsterinsights_is_plugin_our_addon( $plugin_file ) {
10
	$addons_data = monsterinsights_get_addons();
11
12
	foreach ( $addons_data as $type => $addons ) {
13
		foreach ( $addons as $addon ) {
14
			$slug     = 'monsterinsights-' . $addon->slug;
15
			$basename = monsterinsights_get_plugin_basename_from_slug( $slug );
16
17
			// Our eCommerce plugin uses a different slug.
18
			if ( 'm' === $slug[0] && $slug === $basename && 'monsterinsights-ecommerce' === $slug ) {
19
				$basename = monsterinsights_get_plugin_basename_from_slug( 'ga-ecommerce' );
20
			}
21
22
			if ( $plugin_file === $basename ) {
23
				return true;
24
			}
25
		}
26
	}
27
28
	return false;
29
}
30
31
/**
32
 * Add Manage Auto-updates link for MI pro and its add-ons on Plugins page
33
 *
34
 * @param $html
35
 * @param $plugin_file
36
 *
37
 * @return string
38
 */
39
function monsterinsights_modify_wordpress_autoupdater_setting( $html, $plugin_file, $plugin_data ) {
40
	$is_pro         = monsterinsights_is_pro_version();
41
	$is_addon       = monsterinsights_is_plugin_our_addon( $plugin_file );
42
	$is_main_free   = 'google-analytics-for-wordpress' === $plugin_data['slug'];
43
	$is_main_pro    = $is_pro && plugin_basename( MONSTERINSIGHTS_PLUGIN_FILE ) === $plugin_file;
44
	$has_permission = current_user_can( 'monsterinsights_save_settings' );
45
46
	if ( $is_addon && ! $is_pro ) {
47
		$html = sprintf(
48
			'<a href="%s">%s</a>',
49
			monsterinsights_get_url(
50
				'plugins-autoupdate',
51
				'upgrade-to-autoupdate',
52
				'https://www.monsterinsights.com/docs/go-lite-pro'
53
			),
54
			__( 'Enable the MonsterInsights PRO plugin to manage auto-updates', 'google-analytics-for-wordpress' )
55
		);
56
		add_filter( "monsterinsights_is_autoupdate_setting_html_filtered_${plugin_file}", '__return_true' );
57
	} elseif ( $has_permission &&
58
	           ( $is_main_free || $is_main_pro || ( $is_addon && $is_pro ) )
59
	) {
60
		$text  = __( 'Manage auto-updates', 'google-analytics-for-wordpress' );
61
		$html .= '<br>' . sprintf( '<a href="%s"">%s</a>', admin_url( 'admin.php?page=monsterinsights_settings#/advanced' ), $text );
62
		add_filter( "monsterinsights_is_autoupdate_setting_html_filtered_${plugin_file}", '__return_true' );
63
	}
64
65
	return $html;
66
}
67
68
add_filter( 'plugin_auto_update_setting_html', 'monsterinsights_modify_wordpress_autoupdater_setting', 10, 3 );
69
70
/**
71
 * Filters the auto update plugin routine to allow MonsterInsights to be
72
 * automatically updated.
73
 *
74
 * This function is hooked into `auto_update_plugin`. This hook is used in
75
 * two places:
76
 *   - Automatic plugin update routine.
77
 *   - Display the enabled / disabled state on Plugins page.
78
 *
79
 * When used in the context of automatic plugin update, this function consult
80
 * the MI auto-update opt-in setting to see if the latest update is minor / major,
81
 * and returns true or false accordingly.
82
 *
83
 * When used in the context of Plugins page, it will always return true no matter
84
 * whether the opt-in is set to minor or major. It will only return false if the
85
 * opt-in setting is disabled completely. We need to do this so that it's not confusing
86
 * to the user, because WordPress auto-update UI does not deal with the same granularity
87
 * as our opt-in setting.
88
 *
89
 * @since 6.3.0
90
 *
91
 * @param bool $update  Flag to update the plugin or not.
92
 * @param array $item   Update data about a specific plugin.
93
 * @return bool $update The new update state.
94
 */
95
function monsterinsights_automatic_updates( $update, $item ) {
96
	$item = (array) $item;
97
98
	$is_free = isset( $item['slug'] ) && 'google-analytics-for-wordpress' === $item['slug'];
99
	$is_paid = isset( $item['monsterinsights_plugin'] ); // see updater class
100
101
	$automatic_updates = monsterinsights_get_option( 'automatic_updates', false );
102
103
	// When used in the context of Plugins page.
104
	if ( function_exists( 'get_current_screen' ) ) {
105
		$screen = get_current_screen();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $screen is correct as get_current_screen() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
106
		if ( ! empty( $screen ) &&
107
		     ! empty( $screen->id ) &&
108
		     in_array( $screen->id, array( 'plugins', 'plugins-network' ) )
109
		) {
110
			$is_pro      = monsterinsights_is_pro_version();
111
			$is_addon    = monsterinsights_is_plugin_our_addon( $item['plugin'] );
112
			$is_main_pro = $is_pro && plugin_basename( MONSTERINSIGHTS_PLUGIN_FILE ) === $item['plugin'];
113
114
			if ( $is_free ||
115
			     $is_main_pro ||
116
			     ( $is_addon && $is_pro )
117
			) {
118
				return in_array( $automatic_updates, array( 'all', 'minor' ) );
119
			} elseif ( $is_addon && ! $is_pro ) {
120
				return false;
121
			}
122
		}
123
	}
124
125
    // If this is multisite and is not on the main site, return early.
126
    if ( is_multisite() && ! is_main_site() ) {
127
        return $update;
128
    }
129
130
    // When used in the context of automatic plugin update routine, the $item
131
	// variable will have `new_version`, `slug` and `monsterinsights_plugin` filled out:
132
133
    // If we don't have everything we need, return early.
134
    if ( ! isset( $item['new_version'] ) || ! isset( $item['slug'] ) ) {
135
        return $update;
136
    }
137
138
    // If the plugin isn't ours, return early.
139
    if ( ( ! $is_free && ! $is_paid ) || ( $is_free && ! defined( 'MONSTERINSIGHTS_LITE_VERSION' ) ) ) {
140
        return $update;
141
    }
142
143
    $version           = $is_free ? MONSTERINSIGHTS_LITE_VERSION : $item['old_version'];
144
    $current_major     = monsterinsights_get_major_version( $version );
145
    $new_major         = monsterinsights_get_major_version( $item['new_version'] );
146
147
    // If the opt in update allows major updates but there is no major version update, return early.
148
    if ( $current_major < $new_major ) {
149
        if ( $automatic_updates === 'all' ) {
150
            return true;
151
        } else {
152
            return $update;
153
        }
154
    }
155
156
    // If the opt in update allows minor updates but there is no minor version update, return early.
157
    if ( $current_major == $new_major ) {
158
        if ( $automatic_updates === 'all' || $automatic_updates === 'minor' ) {
159
            return true;
160
        } else {
161
            return $update;
162
        }
163
    }
164
165
    // All our checks have passed - this plugin can be updated!
166
    return true;
167
}
168
169
add_filter( 'auto_update_plugin', 'monsterinsights_automatic_updates', 10, 2 );
170
/**
171
 * Notes about autoupdater:
172
 * This runs on the normal WordPress auto-update sequence:
173
 * 1. In wp-includes/update.php, wp_version_check() is called by the WordPress update cron (every 8 or 12 hours; can be overriden to be faster/long or turned off by plugins)
174
 * 2. In wp-includes/update.php, wp_version_check() ends with a action call to do_action( 'wp_maybe_auto_update' ) if cron is running
175
 * 3. In wp-includes/update.php, wp_maybe_auto_update() hooks into wp_maybe_auto_update action, creates a new WP_Automatic_Updater instance and calls WP_Automatic_Updater->run
176
 * 4. In wp-admin/includes/class-wp-automatic-updater.php $this->run() checks to make sure we're on the main site if on a network, and also if the autoupdates are disabled (by plugin, by being on a version controlled site, etc )
177
 * 5. In wp-admin/includes/class-wp-automatic-updater.php $this->run() then checks to see which plugins have new versions (version/update check)
178
 * 6. In wp-admin/includes/class-wp-automatic-updater.php $this->run() then calls $this->update() for each plugin installed who has an upgrade.
179
 * 7 In wp-admin/includes/class-wp-automatic-updater.php $this->update() double checks filesystem access and then installs the plugin if able
180
 *
181
 * Notes:
182
 * - This autoupdater only works if WordPress core detects no version control. If you want to test this, do it on a new WP site without any .git folders anywhere.
183
 * - This autoupdater only works if the file access is able to be written to
184
 * - This autoupdater only works if a new version has been detected, and will run not the second the update is released, but whenever the cron for wp_version_check is next released. This is generally run every 8-12 hours.
185
 * - However, that cron can be disabled, the autoupdater can be turned off via constant or filter, version control or file lock can be detected, and other plugins can be installed (incl in functions of theme) that turn off all
186
 *      all automatic plugin updates.
187
 * - If you want to test this is working, you have to manually run the wp_version_check cron. Install the WP Crontrol plugin or Core Control plugin, and run the cron manually using it.
188
 * - Again, because you skimmed over it the first time, if you want to test this manually you need to test this on a new WP install without version control for core, plugins, etc, without file lock, with license key entered (for pro only)
189
 *        and use the WP Crontrol or Core Control plugin to run wp_version_check
190
 * - You may have to manually remove an option called "auto_update.lock" from the WP options table
191
 * - You may need to run wp_version_check multiple times (note though that they must be spaced at least 60 seconds apart)
192
 * - Because WP's updater asks the OS if the file is writable, make sure you do not have any files/folders for the plugin you are trying to autoupdate open when testing.
193
 * - You may need to delete the plugin info transient to get it to hard refresh the plugin info.
194
 */
195
196
197
function monsterinsights_get_major_version( $version ) {
198
    $exploded_version = explode( '.', $version );
199
    if ( isset( $exploded_version[2] ) ) {
200
        return $exploded_version[0] . '.' . $exploded_version[1] . '.' . $exploded_version[2];
201
    } else {
202
        return $exploded_version[0] . '.' . $exploded_version[1] . '.0';
203
    }
204
}
205