PluginProbe
MainWP Dashboard: Self-hosted WordPress Management for Agencies / 6.2
MainWP Dashboard: Self-hosted WordPress Management for Agencies v6.2
6.2 6.1.8 6.1.7 6.1.6 6.1.5 6.1.4 6.1.3 6.1.2 6.1.1 6.1 6.0.12 6.0.11 4.6.0.1 5.0 5.0.1 5.0.2 5.0.3 5.0.3.1 5.0.3.2 5.1 5.1.1 5.2 5.2.1 5.2.2 5.3 All 153 releases
mainwp / class / class-mainwp-api-manager-plugin-update.php

class-mainwp-api-manager-plugin-update.php in MainWP Dashboard: Self-hosted WordPress Management for Agencies 6.2, at class/class-mainwp-api-manager-plugin-update.php

246 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * MainWP API Manager Update Handler
4 *
5 * This class handles updates for MainWP Extension.
6 *
7 * @package MainWP API Manager/Update Handler
8 */
9
10 namespace MainWP\Dashboard;
11
12 // Exit if accessed directly.
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16
17 /**
18 * Class MainWP_Api_Manager_Plugin_Update
19 *
20 * MainWP API Manager Update Handler.
21 *
22 * @package MainWP API Manager/Update Handler
23 * @author Todd Lahman LLC
24 * @copyright Copyright (c) Todd Lahman LLC
25 * @since 1.0.0
26 */
27 class MainWP_Api_Manager_Plugin_Update { // phpcs:ignore Generic.Classes.OpeningBraceSameLine.ContentAfterBrace -- NOSONAR.
28
29 /**
30 * Protected static variable to hold the instance.
31 *
32 * @var null Default value.
33 */
34 protected static $instance = null;
35
36 /**
37 * Method instance()
38 *
39 * @static
40 * @return class instance
41 */
42 public static function instance() {
43 if ( is_null( static::$instance ) ) {
44 static::$instance = new self();
45 }
46
47 return static::$instance;
48 }
49
50 /**
51 * MainWP_Api_Manager_Plugin_Update constructor.
52 *
53 * Run each time the class is called.
54 */
55 public function __construct() {
56 // API data.
57 }
58
59 /**
60 * Create upgrade request API URL.
61 *
62 * @param array $args Request arguments.
63 *
64 * @return string Build URL.
65 *
66 * @uses \MainWP\Dashboard\MainWP_Api_Manager::get_upgrade_url()
67 */
68 private function create_upgrade_api_url( $args ) {
69 $upgrade_url = esc_url_raw( add_query_arg( 'mainwp-api', 'am-software-api', MainWP_Api_Manager::instance()->get_upgrade_url() ) );
70
71 $query_url = '';
72 foreach ( $args as $key => $value ) {
73 $query_url .= $key . '=' . rawurlencode( $value ) . '&';
74 }
75 $query_url = rtrim( $query_url, '&' );
76
77 return $upgrade_url . '&' . $query_url;
78 }
79
80 /**
81 * Returns plugin information in an array.
82 *
83 * @param array $plugin Plugin to check.
84 *
85 * @return array Plugin information.
86 */
87 public function update_check( $plugin ) {
88
89 $args = array(
90 'request' => 'pluginupdatecheck',
91 'plugin_name' => $plugin['plugin_name'],
92 'version' => $plugin['software_version'],
93 'product_id' => $plugin['product_id'],
94 'api_key' => $plugin['api_key'],
95 'instance' => $plugin['instance'],
96 'software_version' => $plugin['software_version'],
97 'extra' => isset( $plugin['extra'] ) ? $plugin['extra'] : '',
98 );
99
100 // Check for a plugin update.
101 return $this->plugin_information( $args ); // pluginupdatecheck.
102 }
103
104
105 /**
106 * Check if bulkupdateapi is true|false & grab domain name adn extensions list.
107 *
108 * @param array $plugins List of plugins (extensions).
109 *
110 * @return array Plugin Information & bulkupdatecheck.
111 */
112 public function bulk_update_check( $plugins ) {
113
114 $args = array(
115 'request' => 'bulkupdatecheck',
116 'extensions' => base64_encode( wp_json_encode( $plugins ) ), // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- base64_encode used for http encoding compatible.
117 'json' => true,
118 );
119
120 $mainwp_api_key = MainWP_Api_Manager_Key::instance()->get_decrypt_master_api_key();
121
122 if ( ! empty( $mainwp_api_key ) ) {
123 $args['api_key'] = $mainwp_api_key;
124 }
125
126 return $this->plugin_information( $args, true ); // bulkupdatecheck.
127 }
128
129
130 /**
131 * Check $args, if there is a response, an object exists & response is not false.
132 *
133 * @param array $args Request arguments.
134 *
135 * @return array|false $response Plugin information.
136 */
137 public function request( $args ) {
138 $args['request'] = 'plugininformation';
139
140 $response = $this->plugin_information( $args ); // plugininformation.
141
142 // If everything is okay return the response.
143 if ( isset( $response ) && is_object( $response ) && false !== $response ) {
144 return $response;
145 }
146 return false;
147 }
148
149 /**
150 * Sends and receives data to and from the server API.
151 *
152 * @access public
153 *
154 * @param array $args Request arguments.
155 * @param bool $bulk_check Check if updating in bulk true|false.
156 *
157 * @return array|false Plugin information.
158 * @since 1.0.0
159 *
160 * @uses \MainWP\Dashboard\MainWP_System_Utility::maybe_unserialyze()
161 */
162 public function plugin_information( $args, $bulk_check = false ) {
163
164 $args['object'] = MainWP_Api_Manager::instance()->get_domain();
165
166 $target_url = $this->create_upgrade_api_url( $args );
167 $default = array(
168 'timeout' => 150,
169 'sslverify' => 1,
170 );
171
172 $params = apply_filters( 'mainwp_plugin_information_sslverify', $default, $args );
173
174 // MWP-1546 (Codex follow-up): redact api_key everywhere it appears
175 // before handing data to the logger. The previous code only masked
176 // the top-level api_key; the per-extension api_keys nested inside
177 // the bulk-check `extensions` payload (and the api_key= param baked
178 // into target_url itself) were both written to the log in plaintext.
179 // For installs running the file logger that turned every cron
180 // update-check tick into a persistence path for credentials.
181 $log_args = $args;
182 if ( isset( $log_args['api_key'] ) ) {
183 $log_args['api_key'] = '***';
184 }
185
186 if ( ! empty( $log_args['extensions'] ) ) {
187 $log_exts = json_decode( base64_decode( $log_args['extensions'] ), true ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions -- NOSONAR base64_decode used for http encoding compatible.
188 if ( is_array( $log_exts ) ) {
189 foreach ( $log_exts as $log_ext_key => $log_ext ) {
190 if ( is_array( $log_ext ) && isset( $log_ext['api_key'] ) ) {
191 $log_exts[ $log_ext_key ]['api_key'] = '***';
192 }
193 }
194 } else {
195 $log_exts = array();
196 }
197 $log_args['_decoded_extensions'] = $log_exts;
198 unset( $log_args['extensions'] );
199 }
200
201 // Strip api_key from the URL query string before logging.
202 $log_target_url = preg_replace( '/(\?|&)api_key=[^&]*/', '$1api_key=***', $target_url );
203
204 MainWP_Logger::instance()->log_events( 'extension-updates-check', sprintf( '[target_url=%s] :: [params=%s] :: [bulk_check=%s]', $log_target_url, print_r( $log_args, true ), $bulk_check ? 'true' : 'false' ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- print_r used for debugging.
205
206 $request = wp_remote_get(
207 $target_url,
208 $params
209 );
210
211 if ( is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) !== 200 ) {
212 return false;
213 }
214
215 $response = wp_remote_retrieve_body( $request );
216
217 MainWP_Logger::instance()->log_events( 'extension-updates-check', sprintf( '[response=%s]', $response ) ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions -- print_r used for debugging.
218
219 if ( isset( $args['json'] ) ) { // bulkupdatecheck: json.
220 $response = json_decode( $response, true );
221 } else { // pluginupdatecheck, plugininformation : serialize.
222 $response = unserialize( $response ); // phpcs:ignore -- data from extensions, to compatible.
223 }
224
225 /**
226 * For debugging errors from the API
227 * For errors like: unserialize(): Error at offset 0 of 170 bytes
228 * Comment out $response above first
229 */
230 if ( ! $bulk_check ) {
231 if ( is_object( $response ) ) {
232 if ( isset( $response->package ) ) {
233 $response->package = apply_filters( 'mainwp_api_manager_upgrade_package_url', $response->package, $response );
234 }
235 return $response;
236 }
237 } elseif ( is_array( $response ) ) {
238 return $response;
239 }
240
241 return false;
242 }
243 }
244
245 // End of class.
246