PluginProbe
Vimeography: Vimeo Video Gallery WordPress Plugin / 2.4.9
Vimeography: Vimeo Video Gallery WordPress Plugin v2.4.9
2.4.9 2.4.8 trunk 0.5.1 0.5.2 0.5.3 0.5.4 0.5.5 0.5.6 0.5.7 0.6 0.6.1 0.6.2 0.6.3 0.6.4 0.6.5 0.6.6 0.6.7 0.6.8 0.6.8.1 0.6.9 0.6.9.1 0.6.9.2 0.7 0.8 All 103 releases
vimeography / lib / update.php

update.php in Vimeography: Vimeo Video Gallery WordPress Plugin 2.4.9, at lib/update.php

512 lines 15.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if ( ! defined( 'ABSPATH' ) ) exit;
4
5 class Vimeography_Update {
6 /**
7 * All of the Vimeography activation keys that the user has stored.
8 *
9 * Example:
10 *
11 * array(1) {
12 * [0]=>
13 * object(stdClass)#472 (3) {
14 * ["activation_key"]=>
15 * string(16) "n0Ae9UP49sNfw5aFGxiyn7mzi09c1Ua7"
16 * ["plugin_name"]=>
17 * string(19) "vimeography-journey"
18 * ["product_name"]=>
19 * string(7) "Journey"
20 * }
21 * }
22 *
23 * @var array
24 */
25 private $_activation_keys;
26
27 /**
28 * The endpoint of the Vimeography Updater API.
29 * this is the URL our updater / license checker pings.
30 *
31 * This should be the URL of the site with EDD installed
32 *
33 * @var string
34 */
35 private $_endpoint = 'https://vimeography.com';
36
37 /**
38 * [__construct description]
39 */
40 public function __construct() {
41 //delete_site_option('vimeography_activation_keys');
42 $activation_keys = get_site_option('vimeography_activation_keys');
43 $this->_activation_keys = $activation_keys ? $activation_keys : array();
44
45 // Setup hooks
46 $this->_includes();
47 $this->_hooks();
48 $this->_vimeography_auto_updater();
49 }
50
51 /**
52 * Include the EDD updater class
53 *
54 * @access private
55 * @return void
56 */
57 private function _includes() {
58 if ( ! class_exists( 'EDD_SL_Plugin_Updater' ) ) {
59 require_once 'EDD_SL_Plugin_Updater.php';
60 }
61 }
62
63 /**
64 * Setup hooks
65 *
66 * @access private
67 * @return void
68 */
69 private function _hooks() {
70
71 // Add activation key message for plugins with missing keys
72 add_action( 'load-plugins.php', array( $this, 'vimeography_check_for_missing_activation_keys' ) );
73
74 // Force EDD Software Licensing to ignore the X-Accel-Redirect header
75 // (évite les problèmes de téléchargement de mises à jour derrière certains serveurs).
76 add_filter( 'edd_ignore_x_accel_redirect', '__return_true' );
77
78 }
79
80 /**
81 * Activate the license key
82 *
83 * @access public
84 * @return void
85 */
86 public function activate_license($license) {
87
88 $key = str_replace('-', '', strtoupper( sanitize_text_field( $license ) ) );
89
90 // Ignore if this is a duplicate incoming key.
91 if ( $this->vimeography_check_if_activation_key_exists( $key ) ) {
92 return;
93 }
94
95 // Lookup the product name associated with this license key before
96 // attempting activation. This allows activate_license to succeed even on
97 // EDD servers that require item_name (i.e. without EDD_BYPASS_NAME_CHECK).
98 $item_name = $this->_vimeography_lookup_item_name( $key );
99
100 // Data to send to the API
101 $api_params = array(
102 'edd_action' => 'activate_license',
103 'license' => $key,
104 'url' => urlencode( home_url() ),
105 );
106
107 if ( ! empty( $item_name ) ) {
108 $api_params['item_name'] = urlencode( $item_name );
109 }
110
111 // Call the API
112 $response = wp_remote_get(
113 add_query_arg( $api_params, $this->_endpoint),
114 array(
115 'timeout' => 15,
116 'sslverify' => true
117 )
118 );
119
120 // Make sure there are no errors
121 if ( is_wp_error( $response ) ) {
122 throw new Exception( wp_kses_post(__('The HTTP Request failed: ' . $response->get_error_message(), 'vimeography') ));
123 }
124
125 // Decode license data
126 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
127
128 if ( ! is_object( $license_data ) ) {
129 throw new Exception( wp_kses_post(__('The license server returned an invalid response.', 'vimeography') ));
130 }
131
132 if ( ! empty( $license_data->success ) AND isset( $license_data->license ) AND $license_data->license === 'valid' ) {
133 $this->_vimeography_add_activation_key( $key, $license_data );
134 return TRUE;
135 } else {
136 $error = isset( $license_data->error ) ? $license_data->error : '';
137 // Add failed message
138 switch ($error) {
139 case 'missing': case 'revoked':
140 throw new Exception( wp_kses_post(__('That license key could not be found in our system.', 'vimeography') ));
141 case 'no_activations_left':
142 throw new Exception( wp_kses_post(__('You have reached the max number of sites that this license can be used on.', 'vimeography') ));
143 case 'expired':
144 throw new Exception( wp_kses_post(__('The license key you entered has expired. Please visit http://vimeography.com to renew it.', 'vimeography') ));
145 case 'key_mismatch':
146 throw new Exception( wp_kses_post(__('The license key you entered does not match the one we have on file.', 'vimeography') ));
147 case 'license_not_activable':
148 throw new Exception( wp_kses_post(__('Looks like you are trying to activate your bundle license. Please activate each of the products in your bundle separately by using their respective individual licenses.', 'vimeography') ));
149 default:
150 throw new Exception( wp_kses_post(__('Unknown error: ' . $error, 'vimeography') ));
151 }
152 }
153 }
154
155 /**
156 * Ask the Vimeography EDD endpoint which product is associated with a given
157 * license key.
158 *
159 * Implementation note: the `check_license` endpoint does not return the
160 * product name on Vimeography's server (item_name is empty). However, calling
161 * `activate_license` *without* the `url` parameter triggers a `missing_url`
162 * error response that includes both `item_name` and `vimeography_product_name`
163 * in its payload — and does NOT consume an activation, since the request
164 * aborts on the server before the site count is incremented.
165 *
166 * @access protected
167 * @param string $key Normalized license key.
168 * @return string Product name, or empty string if it could not be resolved.
169 */
170 protected function _vimeography_lookup_item_name( $key ) {
171 $response = wp_remote_get(
172 add_query_arg( array(
173 'edd_action' => 'activate_license',
174 'license' => $key,
175 ), $this->_endpoint ),
176 array(
177 'timeout' => 15,
178 'sslverify' => true,
179 )
180 );
181
182 if ( is_wp_error( $response ) ) {
183 return '';
184 }
185
186 $data = json_decode( wp_remote_retrieve_body( $response ) );
187
188 if ( ! is_object( $data ) ) {
189 return '';
190 }
191
192 if ( ! empty( $data->item_name ) ) {
193 return $data->item_name;
194 }
195
196 if ( ! empty( $data->vimeography_product_name ) ) {
197 return $data->vimeography_product_name;
198 }
199
200 return '';
201 }
202
203 /**
204 * Deactivate the license key
205 *
206 * @access public
207 * @return void
208 */
209 public function deactivate_license( $license ) {
210 $key = str_replace('-', '', strtoupper( sanitize_text_field( $license ) ) );
211
212 // Data to send to the API
213 $api_params = array(
214 'edd_action' => 'deactivate_license',
215 'license' => $key,
216 //'item_name' => urlencode( $this->item_name ), // the name of our product in EDD
217 'url' => urlencode( home_url() )
218 );
219
220 // Call the API
221 $response = wp_remote_get(
222 add_query_arg( $api_params, $this->_endpoint ),
223 array(
224 'timeout' => 15,
225 'sslverify' => true
226 )
227 );
228
229 // Make sure there are no errors
230 if ( is_wp_error( $response ) ) {
231 return;
232 }
233
234 // Decode the license data
235 $license_data = json_decode( wp_remote_retrieve_body( $response ) );
236
237 // Remove the key even if deactivation fails
238 $this->_vimeography_remove_activation_key( $key );
239
240 if ( ! is_object( $license_data ) || empty( $license_data->success ) ) {
241 throw new Exception( wp_kses_post(__('That license key has been removed from your site, but could not be deactivated in our system.', 'vimeography')) );
242 }
243 }
244
245 /**
246 * [check_license description]
247 * @return [type] [description]
248 */
249 public function check_license( $license ) {
250
251 // Data to send to the API
252 $api_params = array(
253 'edd_action' => 'check_license',
254 'license' => $license->activation_key,
255 //'item_name' => urlencode( $this->item_name ), // the name of our product in EDD
256 'url' => urlencode( home_url() )
257 );
258
259 // Call the API
260 $response = wp_remote_get(
261 add_query_arg( $api_params, $this->_endpoint ),
262 array(
263 'timeout' => 15,
264 'sslverify' => true
265 )
266 );
267
268 // Make sure there are no errors
269 if ( is_wp_error( $response ) ) {
270 return FALSE;
271 }
272
273 // Decode the license data
274 return json_decode( wp_remote_retrieve_body( $response ) );
275 }
276
277 /**
278 * Add a plugins page message to any Vimeography add-ons that are installed,
279 * but that do not have an activation key associated with the installation.
280 *
281 * @return void
282 */
283 public function vimeography_check_for_missing_activation_keys() {
284
285 $addons = Vimeography::get_instance()->addons->installed_addons;
286
287 if ( ! empty( $addons ) ) {
288 // If the activation key is not found for the installed plugin,
289 // add the plugin message hook
290 $addons_with_missing_keys = array_filter($addons, array($this, 'vimeography_is_addon_missing_activation_key') );
291
292 if ( ! empty( $addons_with_missing_keys ) ) {
293 foreach ( $addons_with_missing_keys as $plugin ) {
294 $hook = 'after_plugin_row_' . $plugin['basename'];
295 add_action( $hook, array($this, 'vimeography_addon_update_message'), 10, 2 );
296 }
297 }
298 }
299 }
300
301 /**
302 * Loop through the activations keys to check if one exists for the
303 * given Vimeography addon plugin headers.
304 *
305 * @var $plugin Meta headers for a Vimeography addon plugin.
306 * @return bool TRUE if missing, FALSE if found
307 */
308 public function vimeography_is_addon_missing_activation_key($plugin) {
309 $plugins_with_keys = array();
310
311 if ( ! empty($this->_activation_keys) ) {
312 foreach ($this->_activation_keys as $key) {
313 $plugins_with_keys[] = $key->plugin_name;
314 }
315 }
316
317 return !in_array( $plugin['slug'], $plugins_with_keys );
318 }
319
320 /**
321 * Loop through the activations keys to check if one exists for the
322 * given Vimeography activation key.
323 *
324 * @var $key string Activation key.
325 * @return bool TRUE if exists, FALSE if not found
326 */
327 public function vimeography_check_if_activation_key_exists($key) {
328 $result = FALSE;
329
330 if ( ! empty($this->_activation_keys) ) {
331 foreach ( $this->_activation_keys as $entry ) {
332 if ( $entry->activation_key == $key ) {
333 $result = TRUE;
334 }
335 }
336 }
337
338 return $result;
339 }
340
341 /**
342 * Add the activation key to the database.
343 *
344 * @var $key string Activation key.
345 * @var $license_data array
346 * @return bool TRUE if successful, FALSE if failed
347 */
348 protected function _vimeography_add_activation_key( $key, $license_data ) {
349 if ( ! is_object( $license_data ) ) {
350 return FALSE;
351 }
352
353 $plugin_slug = isset( $license_data->vimeography_plugin_slug )
354 ? sanitize_key( (string) $license_data->vimeography_plugin_slug )
355 : '';
356
357 if ( empty( $plugin_slug ) ) {
358 return FALSE;
359 }
360
361 $entry = new stdClass();
362 $entry->activation_key = sanitize_text_field( (string) $key );
363 $entry->plugin_name = $plugin_slug;
364 $entry->product_name = isset( $license_data->vimeography_product_name )
365 ? sanitize_text_field( (string) $license_data->vimeography_product_name )
366 : '';
367 $entry->expires = isset( $license_data->expires )
368 ? sanitize_text_field( (string) $license_data->expires )
369 : '';
370 $entry->status = isset( $license_data->license )
371 ? sanitize_key( (string) $license_data->license )
372 : '';
373 $entry->limit = isset( $license_data->license_limit )
374 ? intval( $license_data->license_limit )
375 : 0;
376 $entry->activations_left = isset( $license_data->activations_left )
377 ? intval( $license_data->activations_left )
378 : 0;
379
380 $this->_activation_keys[] = $entry;
381 return update_site_option('vimeography_activation_keys', array_values( $this->_activation_keys ) );
382 }
383
384 /**
385 * Remove the activation key to the database.
386 *
387 * @var $key string Activation key.
388 * @return bool TRUE if successful, FALSE if failed
389 */
390 protected function _vimeography_remove_activation_key( $key ) {
391 if ( ! empty( $this->_activation_keys ) ) {
392 foreach ( $this->_activation_keys as $i => $entry ) {
393 if ( $entry->activation_key === $key ) {
394 unset( $this->_activation_keys[$i] );
395 }
396 }
397
398 return update_site_option( 'vimeography_activation_keys', array_values( $this->_activation_keys ) );
399 }
400
401 return FALSE;
402 }
403
404 /**
405 * Add a reminder to add the activation key to receives updates
406 * for the installed Vimeography theme.
407 *
408 * @param string $plugin_basename Folder and filename, eg:
409 * @return [type] [description]
410 */
411 public function vimeography_addon_update_message($plugin_basename, $plugin_data) {
412 $ineligible = array(
413 'Vimeography Theme: Bugsauce',
414 'Vimeography Theme: Ballistic',
415 'Vimeography Theme: Single'
416 );
417
418 if ( in_array( $plugin_data['Name'], $ineligible ) ) {
419 return;
420 }
421
422 echo '<tr class="plugin-update-tr"><td colspan="3" class="plugin-update"><div class="update-message notice inline notice-warning notice-alt">';
423 echo '<span style="display: block; padding: 5px;">';
424 printf(
425 wp_kses_post(
426 __(
427 'Hey! Don\'t forget to <a title="Activate my Vimeography Addon" href="%1$sadmin.php?page=vimeography-manage-activations">enter your activation key</a> to receive the latest updates for the %2$s plugin.',
428 'vimeography'
429 )
430 ),
431 esc_url(get_admin_url()), // Premier argument %1$s
432 esc_html($plugin_data['Name']) // Deuxième argument %2$s
433 );
434 echo '</span>';
435 echo '</div></td></tr>';
436 }
437
438 /**
439 * Auto updater
440 *
441 * @access protected
442 * @return void
443 */
444 protected function _vimeography_auto_updater() {
445 // We only need to check for updates if an activation key exists
446 // in the options table.
447 if ( ! empty( $this->_activation_keys ) ) {
448 foreach ( $this->_activation_keys as $plugin ) {
449
450 $plugin_path = self::_vimeography_get_plugin_path( $plugin->plugin_name );
451
452 if ( $plugin_path ) {
453 // Get the plugin headers
454 $headers = get_file_data( $plugin_path, array('version' => 'Version') );
455
456 // setup the updater
457 new EDD_SL_Plugin_Updater(
458 $this->_endpoint,
459 $plugin_path,
460 array(
461 'version' => $headers['version'],
462 'license' => trim($plugin->activation_key),
463 'item_name' => $plugin->product_name,
464 'author' => 'Dave Kiss',
465 )
466 );
467 }
468 }
469 }
470 }
471
472 /**
473 * Get the absolute path to the provided plugin name.
474 *
475 * @access protected
476 * @return string
477 */
478 protected function _vimeography_get_plugin_path( $plugin_name ) {
479 // Defense in depth: even though $plugin_name is stored via sanitize_key()
480 // in _vimeography_add_activation_key(), reject anything that isn't a
481 // strict plugin slug here to prevent any form of path traversal on the
482 // WPMU_PLUGIN_DIR / WP_PLUGIN_DIR concatenation below.
483 $plugin_name = (string) $plugin_name;
484
485 if ( ! preg_match( '/^[a-z0-9][a-z0-9_-]*$/', $plugin_name ) ) {
486 return FALSE;
487 }
488
489 $basename = '/' . trailingslashit( $plugin_name ) . $plugin_name . '.php';
490
491 if ( ! is_file( $dir = WPMU_PLUGIN_DIR . $basename ) ) {
492 if ( ! is_file( $dir = WP_PLUGIN_DIR . $basename ) ) {
493 return FALSE;
494 }
495 }
496
497 return $dir;
498 }
499
500 /**
501 * Sets the activation keys in the class
502 *
503 * @param array $keys [description]
504 * @return [type] [description]
505 */
506 public function vimeography_set_activation_keys($keys = array()) {
507 $this->_activation_keys = $keys;
508 return $this;
509 }
510
511 }
512