Version Description
- 07/01/20 =
- Fix - Disable discount rules coupon will work option doesn't works for cart rules.
- Fix - Division by zero in cart rule BOGO.
- Fix - Notice: Undefined index: line_subtotal_tax.
- Fix - Wrong strikeout on product page for fixed price and set discount rules while having the tax settings as enter price excluding and display as including tax.
- Improvement - Slow query while checking for force update.
Download this release
Release Info
Developer | flycart |
Plugin | Discount Rules for WooCommerce |
Version | 1.9.2 |
Comparing to | |
See all releases |
Code changes from version 1.9.1 to 1.9.2
- helper/general-helper.php +3 -0
- helper/purchase.php +7 -5
- includes/cart-rules.php +19 -3
- includes/pricing-rules.php +3 -0
- readme.txt +8 -1
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Autoloader.php +0 -49
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/Extension.php +0 -117
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/Panel.php +0 -165
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/PluginExtension.php +0 -33
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/PluginPanel.php +0 -38
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/ThemePanel.php +0 -21
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Metadata.php +0 -132
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/OAuthSignature.php +0 -88
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Plugin/Info.php +0 -128
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Plugin/Update.php +0 -92
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Plugin/UpdateChecker.php +0 -575
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Scheduler.php +0 -177
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/StateStore.php +0 -207
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Theme/Update.php +0 -84
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Theme/UpdateChecker.php +0 -167
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Update.php +0 -34
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/UpdateChecker.php +0 -828
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/UpgraderStatus.php +0 -199
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Utils.php +0 -77
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/Api.php +0 -243
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/BaseChecker.php +0 -22
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/BitBucketApi.php +0 -253
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/GitHubApi.php +0 -286
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/PluginUpdateChecker.php +0 -198
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/Reference.php +0 -49
- vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/ThemeUpdateChecker.php +0 -101
- woo-discount-rules.php +1 -1
helper/general-helper.php
CHANGED
@@ -483,6 +483,9 @@ if ( ! class_exists( 'FlycartWooDiscountRulesGeneralHelper' ) ) {
|
|
483 |
$used_coupons = self::getUsedCouponsInRules();
|
484 |
$used_coupons[] = $coupon_code;
|
485 |
$used_coupons = apply_filters('woo_discount_rules_coupons_to_skip_while_apply_third_party_coupon_and_disable_rules', $used_coupons);
|
|
|
|
|
|
|
486 |
foreach ($appliedCoupons as $appliedCoupon){
|
487 |
if(!in_array($appliedCoupon, $used_coupons)){
|
488 |
$result = true;
|
483 |
$used_coupons = self::getUsedCouponsInRules();
|
484 |
$used_coupons[] = $coupon_code;
|
485 |
$used_coupons = apply_filters('woo_discount_rules_coupons_to_skip_while_apply_third_party_coupon_and_disable_rules', $used_coupons);
|
486 |
+
if(!empty($used_coupons)){
|
487 |
+
$used_coupons = array_map('strtolower', $used_coupons);
|
488 |
+
}
|
489 |
foreach ($appliedCoupons as $appliedCoupon){
|
490 |
if(!in_array($appliedCoupon, $used_coupons)){
|
491 |
$result = true;
|
helper/purchase.php
CHANGED
@@ -28,17 +28,19 @@ if ( ! class_exists( 'FlycartWooDiscountRulesPurchase' ) ) {
|
|
28 |
public function init()
|
29 |
{
|
30 |
|
31 |
-
$force_update =
|
32 |
// If a plugin has both a valid license and is using a CORE version then force update
|
33 |
if ( $this->isPro() === false && $this->validateLicenseKey() ) {
|
34 |
// can upgrade to PRO
|
35 |
-
$force_update =
|
36 |
}
|
37 |
-
|
38 |
-
$option_exists = (
|
39 |
|
40 |
if($option_exists){
|
41 |
-
|
|
|
|
|
42 |
}
|
43 |
else {
|
44 |
add_option($this->slug.'-force-update-pro', $force_update);
|
28 |
public function init()
|
29 |
{
|
30 |
|
31 |
+
$force_update = 0;
|
32 |
// If a plugin has both a valid license and is using a CORE version then force update
|
33 |
if ( $this->isPro() === false && $this->validateLicenseKey() ) {
|
34 |
// can upgrade to PRO
|
35 |
+
$force_update = 1;
|
36 |
}
|
37 |
+
$existing_force_update_value = get_option($this->slug.'-force-update-pro', null);
|
38 |
+
$option_exists = ($existing_force_update_value !== null);
|
39 |
|
40 |
if($option_exists){
|
41 |
+
if($existing_force_update_value != $force_update){
|
42 |
+
update_option($this->slug.'-force-update-pro', $force_update);
|
43 |
+
}
|
44 |
}
|
45 |
else {
|
46 |
add_option($this->slug.'-force-update-pro', $force_update);
|
includes/cart-rules.php
CHANGED
@@ -179,6 +179,7 @@ if (!class_exists('FlycartWooDiscountRulesCartRules')) {
|
|
179 |
$request['dynamic_coupons_to_apply'] = $result['create_dynamic_coupon'] = $validate_dynamic_coupon['coupon'];
|
180 |
if($validate_dynamic_coupon['status'] === true){
|
181 |
$request['discount_rule'][$index][$coupon_key] = $value[$coupon_key] = $validate_dynamic_coupon['coupon'];
|
|
|
182 |
} else {
|
183 |
$result['status'] = 0;
|
184 |
$result['message'] = esc_html__('Failed to save', 'woo-discount-rules');
|
@@ -2144,8 +2145,14 @@ if (!class_exists('FlycartWooDiscountRulesCartRules')) {
|
|
2144 |
* @return integer/float
|
2145 |
* */
|
2146 |
public static function getSubTotalOfCartItem($cart_item){
|
|
|
2147 |
if(get_option('woocommerce_tax_display_cart', 'incl') == 'incl'){
|
2148 |
-
$
|
|
|
|
|
|
|
|
|
|
|
2149 |
} else {
|
2150 |
$quantity = (isset($cart_item['quantity']) && $cart_item['quantity']) ? $cart_item['quantity'] : 1;
|
2151 |
$subtotal = ((float)FlycartWoocommerceProduct::get_price($cart_item['data'], true)) * $quantity;
|
@@ -2299,7 +2306,11 @@ if (!class_exists('FlycartWooDiscountRulesCartRules')) {
|
|
2299 |
}
|
2300 |
$discounted_price = ($discount_quantity * $added_products[$discounted_product_id]['item_price']);
|
2301 |
$coupon_msg = self::formatBOGOCouponCode($added_products[$discounted_product_id]['item_name'], $discount_quantity, $added_products[$discounted_product_id]['product'], $rule_text);
|
2302 |
-
$
|
|
|
|
|
|
|
|
|
2303 |
$this->bogo_coupon_codes[$coupon_msg] = array('product_id' => $discounted_product_id, 'amount' => $discounted_price);
|
2304 |
} else {
|
2305 |
//If product not in cart,then add to cart
|
@@ -2320,7 +2331,11 @@ if (!class_exists('FlycartWooDiscountRulesCartRules')) {
|
|
2320 |
do_action('woo_discount_rules_cart_rules_after_adding_free_product_to_cart');
|
2321 |
$discounted_price = ($discount_quantity * FlycartWoocommerceProduct::get_price($product, true));
|
2322 |
$coupon_msg = self::formatBOGOCouponCode(FlycartWoocommerceProduct::get_name($product), $discount_quantity, $product, $rule_text);
|
2323 |
-
$
|
|
|
|
|
|
|
|
|
2324 |
$this->bogo_coupon_codes[$coupon_msg] = array('product_id' => $discounted_product_id, 'amount' => $discounted_price);
|
2325 |
}
|
2326 |
}
|
@@ -2328,6 +2343,7 @@ if (!class_exists('FlycartWooDiscountRulesCartRules')) {
|
|
2328 |
$this->product_discount_total += $discounted_price;
|
2329 |
}
|
2330 |
}
|
|
|
2331 |
return true;
|
2332 |
}
|
2333 |
|
179 |
$request['dynamic_coupons_to_apply'] = $result['create_dynamic_coupon'] = $validate_dynamic_coupon['coupon'];
|
180 |
if($validate_dynamic_coupon['status'] === true){
|
181 |
$request['discount_rule'][$index][$coupon_key] = $value[$coupon_key] = $validate_dynamic_coupon['coupon'];
|
182 |
+
$coupons_used[] = $request['dynamic_coupons_to_apply'];
|
183 |
} else {
|
184 |
$result['status'] = 0;
|
185 |
$result['message'] = esc_html__('Failed to save', 'woo-discount-rules');
|
2145 |
* @return integer/float
|
2146 |
* */
|
2147 |
public static function getSubTotalOfCartItem($cart_item){
|
2148 |
+
$subtotal = 0;
|
2149 |
if(get_option('woocommerce_tax_display_cart', 'incl') == 'incl'){
|
2150 |
+
if(isset($cart_item['line_subtotal'])){
|
2151 |
+
$subtotal = $cart_item['line_subtotal'];
|
2152 |
+
}
|
2153 |
+
if(isset($cart_item['line_subtotal_tax'])){
|
2154 |
+
$subtotal += $cart_item['line_subtotal_tax'];
|
2155 |
+
}
|
2156 |
} else {
|
2157 |
$quantity = (isset($cart_item['quantity']) && $cart_item['quantity']) ? $cart_item['quantity'] : 1;
|
2158 |
$subtotal = ((float)FlycartWoocommerceProduct::get_price($cart_item['data'], true)) * $quantity;
|
2306 |
}
|
2307 |
$discounted_price = ($discount_quantity * $added_products[$discounted_product_id]['item_price']);
|
2308 |
$coupon_msg = self::formatBOGOCouponCode($added_products[$discounted_product_id]['item_name'], $discount_quantity, $added_products[$discounted_product_id]['product'], $rule_text);
|
2309 |
+
if(isset($added_products[$discounted_product_id]) && isset($added_products[$discounted_product_id]['item_quantity'])){
|
2310 |
+
if(!empty($added_products[$discounted_product_id]['item_quantity']) && ((int)$added_products[$discounted_product_id]['item_quantity']) > 0){
|
2311 |
+
$discounted_price = $discounted_price/$added_products[$discounted_product_id]['item_quantity'];
|
2312 |
+
}
|
2313 |
+
}
|
2314 |
$this->bogo_coupon_codes[$coupon_msg] = array('product_id' => $discounted_product_id, 'amount' => $discounted_price);
|
2315 |
} else {
|
2316 |
//If product not in cart,then add to cart
|
2331 |
do_action('woo_discount_rules_cart_rules_after_adding_free_product_to_cart');
|
2332 |
$discounted_price = ($discount_quantity * FlycartWoocommerceProduct::get_price($product, true));
|
2333 |
$coupon_msg = self::formatBOGOCouponCode(FlycartWoocommerceProduct::get_name($product), $discount_quantity, $product, $rule_text);
|
2334 |
+
if(isset($added_products[$discounted_product_id]) && isset($added_products[$discounted_product_id]['item_quantity'])){
|
2335 |
+
if(!empty($added_products[$discounted_product_id]['item_quantity']) && ((int)$added_products[$discounted_product_id]['item_quantity']) > 0){
|
2336 |
+
$discounted_price = $discounted_price/$added_products[$discounted_product_id]['item_quantity'];
|
2337 |
+
}
|
2338 |
+
}
|
2339 |
$this->bogo_coupon_codes[$coupon_msg] = array('product_id' => $discounted_product_id, 'amount' => $discounted_price);
|
2340 |
}
|
2341 |
}
|
2343 |
$this->product_discount_total += $discounted_price;
|
2344 |
}
|
2345 |
}
|
2346 |
+
|
2347 |
return true;
|
2348 |
}
|
2349 |
|
includes/pricing-rules.php
CHANGED
@@ -3566,6 +3566,7 @@ if (!class_exists('FlycartWooDiscountRulesPricingRules')) {
|
|
3566 |
if($product_page){
|
3567 |
if(get_option('woocommerce_prices_include_tax', 'no') == 'no'){
|
3568 |
if(get_option('woocommerce_tax_display_shop', 'incl') == 'incl'){
|
|
|
3569 |
$discount = FlycartWoocommerceProduct::get_price_including_tax($product, 1, $discount);
|
3570 |
}
|
3571 |
}
|
@@ -3609,6 +3610,7 @@ if (!class_exists('FlycartWooDiscountRulesPricingRules')) {
|
|
3609 |
if($product_page){
|
3610 |
if(get_option('woocommerce_prices_include_tax', 'no') == 'no'){
|
3611 |
if(get_option('woocommerce_tax_display_shop', 'incl') == 'incl'){
|
|
|
3612 |
$discount = FlycartWoocommerceProduct::get_price_including_tax($product, 1, $discount);
|
3613 |
}
|
3614 |
}
|
@@ -3658,6 +3660,7 @@ if (!class_exists('FlycartWooDiscountRulesPricingRules')) {
|
|
3658 |
if($product_page){
|
3659 |
if(get_option('woocommerce_prices_include_tax', 'no') == 'no'){
|
3660 |
if(get_option('woocommerce_tax_display_shop', 'incl') == 'incl'){
|
|
|
3661 |
$amount = FlycartWoocommerceProduct::get_price_including_tax($product, 1, $amount);
|
3662 |
}
|
3663 |
}
|
3566 |
if($product_page){
|
3567 |
if(get_option('woocommerce_prices_include_tax', 'no') == 'no'){
|
3568 |
if(get_option('woocommerce_tax_display_shop', 'incl') == 'incl'){
|
3569 |
+
$discount = (FlycartWoocommerceProduct::get_price_excluding_tax($product, 1)) - $fixed_discount_price;
|
3570 |
$discount = FlycartWoocommerceProduct::get_price_including_tax($product, 1, $discount);
|
3571 |
}
|
3572 |
}
|
3610 |
if($product_page){
|
3611 |
if(get_option('woocommerce_prices_include_tax', 'no') == 'no'){
|
3612 |
if(get_option('woocommerce_tax_display_shop', 'incl') == 'incl'){
|
3613 |
+
$discount = (FlycartWoocommerceProduct::get_price_excluding_tax($product, 1)) - $fixed_discount_price;
|
3614 |
$discount = FlycartWoocommerceProduct::get_price_including_tax($product, 1, $discount);
|
3615 |
}
|
3616 |
}
|
3660 |
if($product_page){
|
3661 |
if(get_option('woocommerce_prices_include_tax', 'no') == 'no'){
|
3662 |
if(get_option('woocommerce_tax_display_shop', 'incl') == 'incl'){
|
3663 |
+
$amount = (FlycartWoocommerceProduct::get_price_excluding_tax($product, 1)) - $discount_item['amount'][$amount_type];
|
3664 |
$amount = FlycartWoocommerceProduct::get_price_including_tax($product, 1, $amount);
|
3665 |
}
|
3666 |
}
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://flycart.org/
|
|
4 |
Tags: woocommerce, coupons, discounts, dynamic pricing, Buy One Get One Free, pricing deals, bulk discount, discount
|
5 |
Requires at least: 4.4.1
|
6 |
Tested up to: 5.3
|
7 |
-
Stable tag: 1.9.
|
8 |
License: GPLv3 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
@@ -336,6 +336,13 @@ Discount - Enter minimum & Maximum quantity -> Adjustment Type -> Product Discou
|
|
336 |
|
337 |
== Changelog ==
|
338 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
339 |
= 1.9.1 - 24/12/19 =
|
340 |
* Fix - Wrong discount calculation for the Cart free product discount.
|
341 |
|
4 |
Tags: woocommerce, coupons, discounts, dynamic pricing, Buy One Get One Free, pricing deals, bulk discount, discount
|
5 |
Requires at least: 4.4.1
|
6 |
Tested up to: 5.3
|
7 |
+
Stable tag: 1.9.2
|
8 |
License: GPLv3 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
10 |
|
336 |
|
337 |
== Changelog ==
|
338 |
|
339 |
+
= 1.9.2 - 07/01/20 =
|
340 |
+
* Fix - Disable discount rules coupon will work option doesn't works for cart rules.
|
341 |
+
* Fix - Division by zero in cart rule BOGO.
|
342 |
+
* Fix - Notice: Undefined index: line_subtotal_tax.
|
343 |
+
* Fix - Wrong strikeout on product page for fixed price and set discount rules while having the tax settings as enter price excluding and display as including tax.
|
344 |
+
* Improvement - Slow query while checking for force update.
|
345 |
+
|
346 |
= 1.9.1 - 24/12/19 =
|
347 |
* Fix - Wrong discount calculation for the Cart free product discount.
|
348 |
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Autoloader.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_Autoloader', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_Autoloader {
|
6 |
-
private $prefix = '';
|
7 |
-
private $rootDir = '';
|
8 |
-
private $libraryDir = '';
|
9 |
-
|
10 |
-
private $staticMap;
|
11 |
-
|
12 |
-
public function __construct() {
|
13 |
-
$this->rootDir = dirname(__FILE__) . '/';
|
14 |
-
$nameParts = explode('_', __CLASS__, 3);
|
15 |
-
$this->prefix = $nameParts[0] . '_' . $nameParts[1] . '_';
|
16 |
-
|
17 |
-
$this->libraryDir = realpath($this->rootDir . '../..') . '/';
|
18 |
-
$this->staticMap = array(
|
19 |
-
'PucReadmeParser' => 'vendor/readme-parser.php',
|
20 |
-
'Parsedown' => 'vendor/ParsedownLegacy.php',
|
21 |
-
);
|
22 |
-
if ( version_compare(PHP_VERSION, '5.3.0', '>=') ) {
|
23 |
-
$this->staticMap['Parsedown'] = 'vendor/Parsedown.php';
|
24 |
-
}
|
25 |
-
|
26 |
-
spl_autoload_register(array($this, 'autoload'));
|
27 |
-
}
|
28 |
-
|
29 |
-
public function autoload($className) {
|
30 |
-
if ( isset($this->staticMap[$className]) && file_exists($this->libraryDir . $this->staticMap[$className]) ) {
|
31 |
-
/** @noinspection PhpIncludeInspection */
|
32 |
-
include ($this->libraryDir . $this->staticMap[$className]);
|
33 |
-
return;
|
34 |
-
}
|
35 |
-
|
36 |
-
if (strpos($className, $this->prefix) === 0) {
|
37 |
-
$path = substr($className, strlen($this->prefix));
|
38 |
-
$path = str_replace('_', '/', $path);
|
39 |
-
$path = $this->rootDir . $path . '.php';
|
40 |
-
|
41 |
-
if (file_exists($path)) {
|
42 |
-
/** @noinspection PhpIncludeInspection */
|
43 |
-
include $path;
|
44 |
-
}
|
45 |
-
}
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/Extension.php
DELETED
@@ -1,117 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_DebugBar_Extension', false) ):
|
3 |
-
|
4 |
-
class Puc_v4_DebugBar_Extension {
|
5 |
-
/** @var Puc_v4_UpdateChecker */
|
6 |
-
protected $updateChecker;
|
7 |
-
protected $panelClass = 'Puc_v4_DebugBar_Panel';
|
8 |
-
|
9 |
-
public function __construct($updateChecker, $panelClass = null) {
|
10 |
-
$this->updateChecker = $updateChecker;
|
11 |
-
if ( isset($panelClass) ) {
|
12 |
-
$this->panelClass = $panelClass;
|
13 |
-
}
|
14 |
-
|
15 |
-
add_filter('debug_bar_panels', array($this, 'addDebugBarPanel'));
|
16 |
-
add_action('debug_bar_enqueue_scripts', array($this, 'enqueuePanelDependencies'));
|
17 |
-
|
18 |
-
add_action('wp_ajax_puc_v4_debug_check_now', array($this, 'ajaxCheckNow'));
|
19 |
-
}
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Register the PUC Debug Bar panel.
|
23 |
-
*
|
24 |
-
* @param array $panels
|
25 |
-
* @return array
|
26 |
-
*/
|
27 |
-
public function addDebugBarPanel($panels) {
|
28 |
-
if ( $this->updateChecker->userCanInstallUpdates() ) {
|
29 |
-
$panels[] = new $this->panelClass($this->updateChecker);
|
30 |
-
}
|
31 |
-
return $panels;
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* Enqueue our Debug Bar scripts and styles.
|
36 |
-
*/
|
37 |
-
public function enqueuePanelDependencies() {
|
38 |
-
wp_enqueue_style(
|
39 |
-
'puc-debug-bar-style-v4',
|
40 |
-
$this->getLibraryUrl("/css/puc-debug-bar.css"),
|
41 |
-
array('debug-bar'),
|
42 |
-
'20161217'
|
43 |
-
);
|
44 |
-
|
45 |
-
wp_enqueue_script(
|
46 |
-
'puc-debug-bar-js-v4',
|
47 |
-
$this->getLibraryUrl("/js/debug-bar.js"),
|
48 |
-
array('jquery'),
|
49 |
-
'20161219'
|
50 |
-
);
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* Run an update check and output the result. Useful for making sure that
|
55 |
-
* the update checking process works as expected.
|
56 |
-
*/
|
57 |
-
public function ajaxCheckNow() {
|
58 |
-
if ( $_POST['uid'] !== $this->updateChecker->getUniqueName('uid') ) {
|
59 |
-
return;
|
60 |
-
}
|
61 |
-
$this->preAjaxReqest();
|
62 |
-
$update = $this->updateChecker->checkForUpdates();
|
63 |
-
if ( $update !== null ) {
|
64 |
-
echo "An update is available:";
|
65 |
-
echo '<pre>', htmlentities(print_r($update, true)), '</pre>';
|
66 |
-
} else {
|
67 |
-
echo 'No updates found.';
|
68 |
-
}
|
69 |
-
exit;
|
70 |
-
}
|
71 |
-
|
72 |
-
/**
|
73 |
-
* Check access permissions and enable error display (for debugging).
|
74 |
-
*/
|
75 |
-
protected function preAjaxReqest() {
|
76 |
-
if ( !$this->updateChecker->userCanInstallUpdates() ) {
|
77 |
-
die('Access denied');
|
78 |
-
}
|
79 |
-
check_ajax_referer('puc-ajax');
|
80 |
-
|
81 |
-
error_reporting(E_ALL);
|
82 |
-
@ini_set('display_errors','On');
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @param string $filePath
|
87 |
-
* @return string
|
88 |
-
*/
|
89 |
-
private function getLibraryUrl($filePath) {
|
90 |
-
$absolutePath = realpath(dirname(__FILE__) . '/../../../' . ltrim($filePath, '/'));
|
91 |
-
|
92 |
-
//Where is the library located inside the WordPress directory structure?
|
93 |
-
$absolutePath = wp_normalize_path($absolutePath);
|
94 |
-
|
95 |
-
$pluginDir = wp_normalize_path(WP_PLUGIN_DIR);
|
96 |
-
$muPluginDir = wp_normalize_path(WPMU_PLUGIN_DIR);
|
97 |
-
$themeDir = wp_normalize_path(get_theme_root());
|
98 |
-
|
99 |
-
if ( (strpos($absolutePath, $pluginDir) === 0) || (strpos($absolutePath, $muPluginDir) === 0) ) {
|
100 |
-
//It's part of a plugin.
|
101 |
-
return plugins_url(basename($absolutePath), $absolutePath);
|
102 |
-
} else if ( strpos($absolutePath, $themeDir) === 0 ) {
|
103 |
-
//It's part of a theme.
|
104 |
-
$relativePath = substr($absolutePath, strlen($themeDir) + 1);
|
105 |
-
$template = substr($relativePath, 0, strpos($relativePath, '/'));
|
106 |
-
$baseUrl = get_theme_root_uri($template);
|
107 |
-
|
108 |
-
if ( !empty($baseUrl) && $relativePath ) {
|
109 |
-
return $baseUrl . '/' . $relativePath;
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
return '';
|
114 |
-
}
|
115 |
-
}
|
116 |
-
|
117 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/Panel.php
DELETED
@@ -1,165 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_DebugBar_Panel', false) && class_exists('Debug_Bar_Panel', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_DebugBar_Panel extends Debug_Bar_Panel {
|
6 |
-
/** @var Puc_v4_UpdateChecker */
|
7 |
-
protected $updateChecker;
|
8 |
-
|
9 |
-
private $responseBox = '<div class="puc-ajax-response" style="display: none;"></div>';
|
10 |
-
|
11 |
-
public function __construct($updateChecker) {
|
12 |
-
$this->updateChecker = $updateChecker;
|
13 |
-
$title = sprintf(
|
14 |
-
'<span id="puc-debug-menu-link-%s">PUC (%s)</span>',
|
15 |
-
esc_attr($this->updateChecker->getUniqueName('uid')),
|
16 |
-
$this->updateChecker->slug
|
17 |
-
);
|
18 |
-
parent::__construct($title);
|
19 |
-
}
|
20 |
-
|
21 |
-
public function render() {
|
22 |
-
printf(
|
23 |
-
'<div class="puc-debug-bar-panel-v4" id="%1$s" data-slug="%2$s" data-uid="%3$s" data-nonce="%4$s">',
|
24 |
-
esc_attr($this->updateChecker->getUniqueName('debug-bar-panel')),
|
25 |
-
esc_attr($this->updateChecker->slug),
|
26 |
-
esc_attr($this->updateChecker->getUniqueName('uid')),
|
27 |
-
esc_attr(wp_create_nonce('puc-ajax'))
|
28 |
-
);
|
29 |
-
|
30 |
-
$this->displayConfiguration();
|
31 |
-
$this->displayStatus();
|
32 |
-
$this->displayCurrentUpdate();
|
33 |
-
|
34 |
-
echo '</div>';
|
35 |
-
}
|
36 |
-
|
37 |
-
private function displayConfiguration() {
|
38 |
-
echo '<h3>Configuration</h3>';
|
39 |
-
echo '<table class="puc-debug-data">';
|
40 |
-
$this->displayConfigHeader();
|
41 |
-
$this->row('Slug', htmlentities($this->updateChecker->slug));
|
42 |
-
$this->row('DB option', htmlentities($this->updateChecker->optionName));
|
43 |
-
|
44 |
-
$requestInfoButton = $this->getMetadataButton();
|
45 |
-
$this->row('Metadata URL', htmlentities($this->updateChecker->metadataUrl) . ' ' . $requestInfoButton . $this->responseBox);
|
46 |
-
|
47 |
-
$scheduler = $this->updateChecker->scheduler;
|
48 |
-
if ( $scheduler->checkPeriod > 0 ) {
|
49 |
-
$this->row('Automatic checks', 'Every ' . $scheduler->checkPeriod . ' hours');
|
50 |
-
} else {
|
51 |
-
$this->row('Automatic checks', 'Disabled');
|
52 |
-
}
|
53 |
-
|
54 |
-
if ( isset($scheduler->throttleRedundantChecks) ) {
|
55 |
-
if ( $scheduler->throttleRedundantChecks && ($scheduler->checkPeriod > 0) ) {
|
56 |
-
$this->row(
|
57 |
-
'Throttling',
|
58 |
-
sprintf(
|
59 |
-
'Enabled. If an update is already available, check for updates every %1$d hours instead of every %2$d hours.',
|
60 |
-
$scheduler->throttledCheckPeriod,
|
61 |
-
$scheduler->checkPeriod
|
62 |
-
)
|
63 |
-
);
|
64 |
-
} else {
|
65 |
-
$this->row('Throttling', 'Disabled');
|
66 |
-
}
|
67 |
-
}
|
68 |
-
|
69 |
-
$this->updateChecker->onDisplayConfiguration($this);
|
70 |
-
|
71 |
-
echo '</table>';
|
72 |
-
}
|
73 |
-
|
74 |
-
protected function displayConfigHeader() {
|
75 |
-
//Do nothing. This should be implemented in subclasses.
|
76 |
-
}
|
77 |
-
|
78 |
-
protected function getMetadataButton() {
|
79 |
-
return '';
|
80 |
-
}
|
81 |
-
|
82 |
-
private function displayStatus() {
|
83 |
-
echo '<h3>Status</h3>';
|
84 |
-
echo '<table class="puc-debug-data">';
|
85 |
-
$state = $this->updateChecker->getUpdateState();
|
86 |
-
$checkNowButton = '';
|
87 |
-
if ( function_exists('get_submit_button') ) {
|
88 |
-
$checkNowButton = get_submit_button(
|
89 |
-
'Check Now',
|
90 |
-
'secondary',
|
91 |
-
'puc-check-now-button',
|
92 |
-
false,
|
93 |
-
array('id' => $this->updateChecker->getUniqueName('check-now-button'))
|
94 |
-
);
|
95 |
-
}
|
96 |
-
|
97 |
-
if ( $state->getLastCheck() > 0 ) {
|
98 |
-
$this->row('Last check', $this->formatTimeWithDelta($state->getLastCheck()) . ' ' . $checkNowButton . $this->responseBox);
|
99 |
-
} else {
|
100 |
-
$this->row('Last check', 'Never');
|
101 |
-
}
|
102 |
-
|
103 |
-
$nextCheck = wp_next_scheduled($this->updateChecker->scheduler->getCronHookName());
|
104 |
-
$this->row('Next automatic check', $this->formatTimeWithDelta($nextCheck));
|
105 |
-
|
106 |
-
if ( $state->getCheckedVersion() !== '' ) {
|
107 |
-
$this->row('Checked version', htmlentities($state->getCheckedVersion()));
|
108 |
-
$this->row('Cached update', $state->getUpdate());
|
109 |
-
}
|
110 |
-
$this->row('Update checker class', htmlentities(get_class($this->updateChecker)));
|
111 |
-
echo '</table>';
|
112 |
-
}
|
113 |
-
|
114 |
-
private function displayCurrentUpdate() {
|
115 |
-
$update = $this->updateChecker->getUpdate();
|
116 |
-
if ( $update !== null ) {
|
117 |
-
echo '<h3>An Update Is Available</h3>';
|
118 |
-
echo '<table class="puc-debug-data">';
|
119 |
-
$fields = $this->getUpdateFields();
|
120 |
-
foreach($fields as $field) {
|
121 |
-
if ( property_exists($update, $field) ) {
|
122 |
-
$this->row(ucwords(str_replace('_', ' ', $field)), htmlentities($update->$field));
|
123 |
-
}
|
124 |
-
}
|
125 |
-
echo '</table>';
|
126 |
-
} else {
|
127 |
-
echo '<h3>No updates currently available</h3>';
|
128 |
-
}
|
129 |
-
}
|
130 |
-
|
131 |
-
protected function getUpdateFields() {
|
132 |
-
return array('version', 'download_url', 'slug',);
|
133 |
-
}
|
134 |
-
|
135 |
-
private function formatTimeWithDelta($unixTime) {
|
136 |
-
if ( empty($unixTime) ) {
|
137 |
-
return 'Never';
|
138 |
-
}
|
139 |
-
|
140 |
-
$delta = time() - $unixTime;
|
141 |
-
$result = human_time_diff(time(), $unixTime);
|
142 |
-
if ( $delta < 0 ) {
|
143 |
-
$result = 'after ' . $result;
|
144 |
-
} else {
|
145 |
-
$result = $result . ' ago';
|
146 |
-
}
|
147 |
-
$result .= ' (' . $this->formatTimestamp($unixTime) . ')';
|
148 |
-
return $result;
|
149 |
-
}
|
150 |
-
|
151 |
-
private function formatTimestamp($unixTime) {
|
152 |
-
return gmdate('Y-m-d H:i:s', $unixTime + (get_option('gmt_offset') * 3600));
|
153 |
-
}
|
154 |
-
|
155 |
-
public function row($name, $value) {
|
156 |
-
if ( is_object($value) || is_array($value) ) {
|
157 |
-
$value = '<pre>' . htmlentities(print_r($value, true)) . '</pre>';
|
158 |
-
} else if ($value === null) {
|
159 |
-
$value = '<code>null</code>';
|
160 |
-
}
|
161 |
-
printf('<tr><th scope="row">%1$s</th> <td>%2$s</td></tr>', $name, $value);
|
162 |
-
}
|
163 |
-
}
|
164 |
-
|
165 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/PluginExtension.php
DELETED
@@ -1,33 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_DebugBar_PluginExtension', false) ):
|
3 |
-
|
4 |
-
class Puc_v4_DebugBar_PluginExtension extends Puc_v4_DebugBar_Extension {
|
5 |
-
/** @var Puc_v4_Plugin_UpdateChecker */
|
6 |
-
protected $updateChecker;
|
7 |
-
|
8 |
-
public function __construct($updateChecker) {
|
9 |
-
parent::__construct($updateChecker, 'Puc_v4_DebugBar_PluginPanel');
|
10 |
-
|
11 |
-
add_action('wp_ajax_puc_v4_debug_request_info', array($this, 'ajaxRequestInfo'));
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Request plugin info and output it.
|
16 |
-
*/
|
17 |
-
public function ajaxRequestInfo() {
|
18 |
-
if ( $_POST['uid'] !== $this->updateChecker->getUniqueName('uid') ) {
|
19 |
-
return;
|
20 |
-
}
|
21 |
-
$this->preAjaxReqest();
|
22 |
-
$info = $this->updateChecker->requestInfo();
|
23 |
-
if ( $info !== null ) {
|
24 |
-
echo 'Successfully retrieved plugin info from the metadata URL:';
|
25 |
-
echo '<pre>', htmlentities(print_r($info, true)), '</pre>';
|
26 |
-
} else {
|
27 |
-
echo 'Failed to retrieve plugin info from the metadata URL.';
|
28 |
-
}
|
29 |
-
exit;
|
30 |
-
}
|
31 |
-
}
|
32 |
-
|
33 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/PluginPanel.php
DELETED
@@ -1,38 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_DebugBar_PluginPanel', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_DebugBar_PluginPanel extends Puc_v4_DebugBar_Panel {
|
6 |
-
/**
|
7 |
-
* @var Puc_v4_Plugin_UpdateChecker
|
8 |
-
*/
|
9 |
-
protected $updateChecker;
|
10 |
-
|
11 |
-
protected function displayConfigHeader() {
|
12 |
-
$this->row('Plugin file', htmlentities($this->updateChecker->pluginFile));
|
13 |
-
parent::displayConfigHeader();
|
14 |
-
}
|
15 |
-
|
16 |
-
protected function getMetadataButton() {
|
17 |
-
$requestInfoButton = '';
|
18 |
-
if ( function_exists('get_submit_button') ) {
|
19 |
-
$requestInfoButton = get_submit_button(
|
20 |
-
'Request Info',
|
21 |
-
'secondary',
|
22 |
-
'puc-request-info-button',
|
23 |
-
false,
|
24 |
-
array('id' => $this->updateChecker->getUniqueName('request-info-button'))
|
25 |
-
);
|
26 |
-
}
|
27 |
-
return $requestInfoButton;
|
28 |
-
}
|
29 |
-
|
30 |
-
protected function getUpdateFields() {
|
31 |
-
return array_merge(
|
32 |
-
parent::getUpdateFields(),
|
33 |
-
array('homepage', 'upgrade_notice', 'tested',)
|
34 |
-
);
|
35 |
-
}
|
36 |
-
}
|
37 |
-
|
38 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/DebugBar/ThemePanel.php
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_DebugBar_ThemePanel', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_DebugBar_ThemePanel extends Puc_v4_DebugBar_Panel {
|
6 |
-
/**
|
7 |
-
* @var Puc_v4_Theme_UpdateChecker
|
8 |
-
*/
|
9 |
-
protected $updateChecker;
|
10 |
-
|
11 |
-
protected function displayConfigHeader() {
|
12 |
-
$this->row('Theme directory', htmlentities($this->updateChecker->directoryName));
|
13 |
-
parent::displayConfigHeader();
|
14 |
-
}
|
15 |
-
|
16 |
-
protected function getUpdateFields() {
|
17 |
-
return array_merge(parent::getUpdateFields(), array('details_url'));
|
18 |
-
}
|
19 |
-
}
|
20 |
-
|
21 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Metadata.php
DELETED
@@ -1,132 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Metadata', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A base container for holding information about updates and plugin metadata.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
abstract class Puc_v4_Metadata {
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Create an instance of this class from a JSON document.
|
15 |
-
*
|
16 |
-
* @abstract
|
17 |
-
* @param string $json
|
18 |
-
* @return self
|
19 |
-
*/
|
20 |
-
public static function fromJson(/** @noinspection PhpUnusedParameterInspection */ $json) {
|
21 |
-
throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
|
22 |
-
}
|
23 |
-
|
24 |
-
/**
|
25 |
-
* @param string $json
|
26 |
-
* @param self $target
|
27 |
-
* @return bool
|
28 |
-
*/
|
29 |
-
protected static function createFromJson($json, $target) {
|
30 |
-
/** @var StdClass $apiResponse */
|
31 |
-
$apiResponse = json_decode($json);
|
32 |
-
if ( empty($apiResponse) || !is_object($apiResponse) ){
|
33 |
-
trigger_error(
|
34 |
-
"Failed to parse update metadata. Try validating your .json file with http://jsonlint.com/",
|
35 |
-
E_USER_NOTICE
|
36 |
-
);
|
37 |
-
return false;
|
38 |
-
}
|
39 |
-
|
40 |
-
$valid = $target->validateMetadata($apiResponse);
|
41 |
-
if ( is_wp_error($valid) ){
|
42 |
-
trigger_error($valid->get_error_message(), E_USER_NOTICE);
|
43 |
-
return false;
|
44 |
-
}
|
45 |
-
|
46 |
-
foreach(get_object_vars($apiResponse) as $key => $value){
|
47 |
-
$target->$key = $value;
|
48 |
-
}
|
49 |
-
|
50 |
-
return true;
|
51 |
-
}
|
52 |
-
|
53 |
-
/**
|
54 |
-
* No validation by default! Subclasses should check that the required fields are present.
|
55 |
-
*
|
56 |
-
* @param StdClass $apiResponse
|
57 |
-
* @return bool|WP_Error
|
58 |
-
*/
|
59 |
-
protected function validateMetadata(/** @noinspection PhpUnusedParameterInspection */ $apiResponse) {
|
60 |
-
return true;
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Create a new instance by copying the necessary fields from another object.
|
65 |
-
*
|
66 |
-
* @abstract
|
67 |
-
* @param StdClass|self $object The source object.
|
68 |
-
* @return self The new copy.
|
69 |
-
*/
|
70 |
-
public static function fromObject(/** @noinspection PhpUnusedParameterInspection */ $object) {
|
71 |
-
throw new LogicException('The ' . __METHOD__ . ' method must be implemented by subclasses');
|
72 |
-
}
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Create an instance of StdClass that can later be converted back to an
|
76 |
-
* update or info container. Useful for serialization and caching, as it
|
77 |
-
* avoids the "incomplete object" problem if the cached value is loaded
|
78 |
-
* before this class.
|
79 |
-
*
|
80 |
-
* @return StdClass
|
81 |
-
*/
|
82 |
-
public function toStdClass() {
|
83 |
-
$object = new stdClass();
|
84 |
-
$this->copyFields($this, $object);
|
85 |
-
return $object;
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Transform the metadata into the format used by WordPress core.
|
90 |
-
*
|
91 |
-
* @return object
|
92 |
-
*/
|
93 |
-
abstract public function toWpFormat();
|
94 |
-
|
95 |
-
/**
|
96 |
-
* Copy known fields from one object to another.
|
97 |
-
*
|
98 |
-
* @param StdClass|self $from
|
99 |
-
* @param StdClass|self $to
|
100 |
-
*/
|
101 |
-
protected function copyFields($from, $to) {
|
102 |
-
$fields = $this->getFieldNames();
|
103 |
-
|
104 |
-
if ( property_exists($from, 'slug') && !empty($from->slug) ) {
|
105 |
-
//Let plugins add extra fields without having to create subclasses.
|
106 |
-
$fields = apply_filters($this->getPrefixedFilter('retain_fields') . '-' . $from->slug, $fields);
|
107 |
-
}
|
108 |
-
|
109 |
-
foreach ($fields as $field) {
|
110 |
-
if ( property_exists($from, $field) ) {
|
111 |
-
$to->$field = $from->$field;
|
112 |
-
}
|
113 |
-
}
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* @return string[]
|
118 |
-
*/
|
119 |
-
protected function getFieldNames() {
|
120 |
-
return array();
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* @param string $tag
|
125 |
-
* @return string
|
126 |
-
*/
|
127 |
-
protected function getPrefixedFilter($tag) {
|
128 |
-
return 'puc_' . $tag;
|
129 |
-
}
|
130 |
-
}
|
131 |
-
|
132 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/OAuthSignature.php
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_OAuthSignature', false) ):
|
4 |
-
|
5 |
-
/**
|
6 |
-
* A basic signature generator for zero-legged OAuth 1.0.
|
7 |
-
*/
|
8 |
-
class Puc_v4_OAuthSignature {
|
9 |
-
private $consumerKey = '';
|
10 |
-
private $consumerSecret = '';
|
11 |
-
|
12 |
-
public function __construct($consumerKey, $consumerSecret) {
|
13 |
-
$this->consumerKey = $consumerKey;
|
14 |
-
$this->consumerSecret = $consumerSecret;
|
15 |
-
}
|
16 |
-
|
17 |
-
/**
|
18 |
-
* Sign a URL using OAuth 1.0.
|
19 |
-
*
|
20 |
-
* @param string $url The URL to be signed. It may contain query parameters.
|
21 |
-
* @param string $method HTTP method such as "GET", "POST" and so on.
|
22 |
-
* @return string The signed URL.
|
23 |
-
*/
|
24 |
-
public function sign($url, $method = 'GET') {
|
25 |
-
$parameters = array();
|
26 |
-
|
27 |
-
//Parse query parameters.
|
28 |
-
$query = @parse_url($url, PHP_URL_QUERY);
|
29 |
-
if ( !empty($query) ) {
|
30 |
-
parse_str($query, $parsedParams);
|
31 |
-
if ( is_array($parameters) ) {
|
32 |
-
$parameters = $parsedParams;
|
33 |
-
}
|
34 |
-
//Remove the query string from the URL. We'll replace it later.
|
35 |
-
$url = substr($url, 0, strpos($url, '?'));
|
36 |
-
}
|
37 |
-
|
38 |
-
$parameters = array_merge(
|
39 |
-
$parameters,
|
40 |
-
array(
|
41 |
-
'oauth_consumer_key' => $this->consumerKey,
|
42 |
-
'oauth_nonce' => $this->nonce(),
|
43 |
-
'oauth_signature_method' => 'HMAC-SHA1',
|
44 |
-
'oauth_timestamp' => time(),
|
45 |
-
'oauth_version' => '1.0',
|
46 |
-
)
|
47 |
-
);
|
48 |
-
unset($parameters['oauth_signature']);
|
49 |
-
|
50 |
-
//Parameters must be sorted alphabetically before signing.
|
51 |
-
ksort($parameters);
|
52 |
-
|
53 |
-
//The most complicated part of the request - generating the signature.
|
54 |
-
//The string to sign contains the HTTP method, the URL path, and all of
|
55 |
-
//our query parameters. Everything is URL encoded. Then we concatenate
|
56 |
-
//them with ampersands into a single string to hash.
|
57 |
-
$encodedVerb = urlencode($method);
|
58 |
-
$encodedUrl = urlencode($url);
|
59 |
-
$encodedParams = urlencode(http_build_query($parameters, '', '&'));
|
60 |
-
|
61 |
-
$stringToSign = $encodedVerb . '&' . $encodedUrl . '&' . $encodedParams;
|
62 |
-
|
63 |
-
//Since we only have one OAuth token (the consumer secret) we only have
|
64 |
-
//to use it as our HMAC key. However, we still have to append an & to it
|
65 |
-
//as if we were using it with additional tokens.
|
66 |
-
$secret = urlencode($this->consumerSecret) . '&';
|
67 |
-
|
68 |
-
//The signature is a hash of the consumer key and the base string. Note
|
69 |
-
//that we have to get the raw output from hash_hmac and base64 encode
|
70 |
-
//the binary data result.
|
71 |
-
$parameters['oauth_signature'] = base64_encode(hash_hmac('sha1', $stringToSign, $secret, true));
|
72 |
-
|
73 |
-
return ($url . '?' . http_build_query($parameters));
|
74 |
-
}
|
75 |
-
|
76 |
-
/**
|
77 |
-
* Generate a random nonce.
|
78 |
-
*
|
79 |
-
* @return string
|
80 |
-
*/
|
81 |
-
private function nonce() {
|
82 |
-
$mt = microtime();
|
83 |
-
$rand = mt_rand();
|
84 |
-
return md5($mt . '_' . $rand);
|
85 |
-
}
|
86 |
-
}
|
87 |
-
|
88 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Plugin/Info.php
DELETED
@@ -1,128 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Plugin_Info', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A container class for holding and transforming various plugin metadata.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
class Puc_v4_Plugin_Info extends Puc_v4_Metadata {
|
12 |
-
//Most fields map directly to the contents of the plugin's info.json file.
|
13 |
-
//See the relevant docs for a description of their meaning.
|
14 |
-
public $name;
|
15 |
-
public $slug;
|
16 |
-
public $version;
|
17 |
-
public $homepage;
|
18 |
-
public $sections = array();
|
19 |
-
public $banners;
|
20 |
-
public $translations = array();
|
21 |
-
public $download_url;
|
22 |
-
|
23 |
-
public $author;
|
24 |
-
public $author_homepage;
|
25 |
-
|
26 |
-
public $requires;
|
27 |
-
public $tested;
|
28 |
-
public $upgrade_notice;
|
29 |
-
|
30 |
-
public $rating;
|
31 |
-
public $num_ratings;
|
32 |
-
public $downloaded;
|
33 |
-
public $active_installs;
|
34 |
-
public $last_updated;
|
35 |
-
|
36 |
-
public $id = 0; //The native WP.org API returns numeric plugin IDs, but they're not used for anything.
|
37 |
-
|
38 |
-
public $filename; //Plugin filename relative to the plugins directory.
|
39 |
-
|
40 |
-
/**
|
41 |
-
* Create a new instance of Plugin Info from JSON-encoded plugin info
|
42 |
-
* returned by an external update API.
|
43 |
-
*
|
44 |
-
* @param string $json Valid JSON string representing plugin info.
|
45 |
-
* @return self|null New instance of Plugin Info, or NULL on error.
|
46 |
-
*/
|
47 |
-
public static function fromJson($json){
|
48 |
-
$instance = new self();
|
49 |
-
|
50 |
-
if ( !parent::createFromJson($json, $instance) ) {
|
51 |
-
return null;
|
52 |
-
}
|
53 |
-
|
54 |
-
//json_decode decodes assoc. arrays as objects. We want it as an array.
|
55 |
-
$instance->sections = (array)$instance->sections;
|
56 |
-
|
57 |
-
return $instance;
|
58 |
-
}
|
59 |
-
|
60 |
-
/**
|
61 |
-
* Very, very basic validation.
|
62 |
-
*
|
63 |
-
* @param StdClass $apiResponse
|
64 |
-
* @return bool|WP_Error
|
65 |
-
*/
|
66 |
-
protected function validateMetadata($apiResponse) {
|
67 |
-
if (
|
68 |
-
!isset($apiResponse->name, $apiResponse->version)
|
69 |
-
|| empty($apiResponse->name)
|
70 |
-
|| empty($apiResponse->version)
|
71 |
-
) {
|
72 |
-
return false;//Added by ashlin due to displaying error message while check update by Wordpress
|
73 |
-
return new WP_Error(
|
74 |
-
'puc-invalid-metadata',
|
75 |
-
"The plugin metadata file does not contain the required 'name' and/or 'version' keys."
|
76 |
-
);
|
77 |
-
}
|
78 |
-
return true;
|
79 |
-
}
|
80 |
-
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Transform plugin info into the format used by the native WordPress.org API
|
84 |
-
*
|
85 |
-
* @return object
|
86 |
-
*/
|
87 |
-
public function toWpFormat(){
|
88 |
-
$info = new stdClass;
|
89 |
-
|
90 |
-
//The custom update API is built so that many fields have the same name and format
|
91 |
-
//as those returned by the native WordPress.org API. These can be assigned directly.
|
92 |
-
$sameFormat = array(
|
93 |
-
'name', 'slug', 'version', 'requires', 'tested', 'rating', 'upgrade_notice',
|
94 |
-
'num_ratings', 'downloaded', 'active_installs', 'homepage', 'last_updated',
|
95 |
-
);
|
96 |
-
foreach($sameFormat as $field){
|
97 |
-
if ( isset($this->$field) ) {
|
98 |
-
$info->$field = $this->$field;
|
99 |
-
} else {
|
100 |
-
$info->$field = null;
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
//Other fields need to be renamed and/or transformed.
|
105 |
-
$info->download_link = $this->download_url;
|
106 |
-
$info->author = $this->getFormattedAuthor();
|
107 |
-
$info->sections = array_merge(array('description' => ''), $this->sections);
|
108 |
-
|
109 |
-
if ( !empty($this->banners) ) {
|
110 |
-
//WP expects an array with two keys: "high" and "low". Both are optional.
|
111 |
-
//Docs: https://wordpress.org/plugins/about/faq/#banners
|
112 |
-
$info->banners = is_object($this->banners) ? get_object_vars($this->banners) : $this->banners;
|
113 |
-
$info->banners = array_intersect_key($info->banners, array('high' => true, 'low' => true));
|
114 |
-
}
|
115 |
-
|
116 |
-
return $info;
|
117 |
-
}
|
118 |
-
|
119 |
-
protected function getFormattedAuthor() {
|
120 |
-
if ( !empty($this->author_homepage) ){
|
121 |
-
/** @noinspection HtmlUnknownTarget */
|
122 |
-
return sprintf('<a href="%s">%s</a>', $this->author_homepage, $this->author);
|
123 |
-
}
|
124 |
-
return $this->author;
|
125 |
-
}
|
126 |
-
}
|
127 |
-
|
128 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Plugin/Update.php
DELETED
@@ -1,92 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Plugin_Update', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A simple container class for holding information about an available update.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @version 3.2
|
10 |
-
* @access public
|
11 |
-
*/
|
12 |
-
class Puc_v4_Plugin_Update extends Puc_v4_Update {
|
13 |
-
public $id = 0;
|
14 |
-
public $homepage;
|
15 |
-
public $upgrade_notice;
|
16 |
-
public $tested;
|
17 |
-
public $filename; //Plugin filename relative to the plugins directory.
|
18 |
-
|
19 |
-
protected static $extraFields = array(
|
20 |
-
'id', 'homepage', 'tested', 'upgrade_notice', 'filename',
|
21 |
-
);
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Create a new instance of PluginUpdate from its JSON-encoded representation.
|
25 |
-
*
|
26 |
-
* @param string $json
|
27 |
-
* @return Puc_v4_Plugin_Update|null
|
28 |
-
*/
|
29 |
-
public static function fromJson($json){
|
30 |
-
//Since update-related information is simply a subset of the full plugin info,
|
31 |
-
//we can parse the update JSON as if it was a plugin info string, then copy over
|
32 |
-
//the parts that we care about.
|
33 |
-
$pluginInfo = Puc_v4_Plugin_Info::fromJson($json);
|
34 |
-
if ( $pluginInfo != null ) {
|
35 |
-
return self::fromPluginInfo($pluginInfo);
|
36 |
-
} else {
|
37 |
-
return null;
|
38 |
-
}
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Create a new instance of PluginUpdate based on an instance of PluginInfo.
|
43 |
-
* Basically, this just copies a subset of fields from one object to another.
|
44 |
-
*
|
45 |
-
* @param Puc_v4_Plugin_Info $info
|
46 |
-
* @return Puc_v4_Plugin_Update
|
47 |
-
*/
|
48 |
-
public static function fromPluginInfo($info){
|
49 |
-
return self::fromObject($info);
|
50 |
-
}
|
51 |
-
|
52 |
-
/**
|
53 |
-
* Create a new instance by copying the necessary fields from another object.
|
54 |
-
*
|
55 |
-
* @param StdClass|Puc_v4_Plugin_Info|Puc_v4_Plugin_Update $object The source object.
|
56 |
-
* @return Puc_v4_Plugin_Update The new copy.
|
57 |
-
*/
|
58 |
-
public static function fromObject($object) {
|
59 |
-
$update = new self();
|
60 |
-
$update->copyFields($object, $update);
|
61 |
-
return $update;
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* @return string[]
|
66 |
-
*/
|
67 |
-
protected function getFieldNames() {
|
68 |
-
return array_merge(parent::getFieldNames(), self::$extraFields);
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Transform the update into the format used by WordPress native plugin API.
|
73 |
-
*
|
74 |
-
* @return object
|
75 |
-
*/
|
76 |
-
public function toWpFormat(){
|
77 |
-
$update = parent::toWpFormat();
|
78 |
-
|
79 |
-
$update->id = $this->id;
|
80 |
-
$update->url = $this->homepage;
|
81 |
-
$update->tested = $this->tested;
|
82 |
-
$update->plugin = $this->filename;
|
83 |
-
|
84 |
-
if ( !empty($this->upgrade_notice) ){
|
85 |
-
$update->upgrade_notice = $this->upgrade_notice;
|
86 |
-
}
|
87 |
-
|
88 |
-
return $update;
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Plugin/UpdateChecker.php
DELETED
@@ -1,575 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Plugin_UpdateChecker', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A custom plugin update checker.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @copyright 2016
|
9 |
-
* @access public
|
10 |
-
*/
|
11 |
-
class Puc_v4_Plugin_UpdateChecker extends Puc_v4_UpdateChecker {
|
12 |
-
protected $updateTransient = 'update_plugins';
|
13 |
-
protected $translationType = 'plugin';
|
14 |
-
|
15 |
-
public $pluginAbsolutePath = ''; //Full path of the main plugin file.
|
16 |
-
public $pluginFile = ''; //Plugin filename relative to the plugins directory. Many WP APIs use this to identify plugins.
|
17 |
-
public $muPluginFile = ''; //For MU plugins, the plugin filename relative to the mu-plugins directory.
|
18 |
-
|
19 |
-
private $cachedInstalledVersion = null;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* Class constructor.
|
23 |
-
*
|
24 |
-
* @param string $metadataUrl The URL of the plugin's metadata file.
|
25 |
-
* @param string $pluginFile Fully qualified path to the main plugin file.
|
26 |
-
* @param string $slug The plugin's 'slug'. If not specified, the filename part of $pluginFile sans '.php' will be used as the slug.
|
27 |
-
* @param integer $checkPeriod How often to check for updates (in hours). Defaults to checking every 12 hours. Set to 0 to disable automatic update checks.
|
28 |
-
* @param string $optionName Where to store book-keeping info about update checks. Defaults to 'external_updates-$slug'.
|
29 |
-
* @param string $muPluginFile Optional. The plugin filename relative to the mu-plugins directory.
|
30 |
-
*/
|
31 |
-
public function __construct($metadataUrl, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = ''){
|
32 |
-
$this->pluginAbsolutePath = $pluginFile;
|
33 |
-
$this->pluginFile = plugin_basename($this->pluginAbsolutePath);
|
34 |
-
$this->muPluginFile = $muPluginFile;
|
35 |
-
|
36 |
-
//If no slug is specified, use the name of the main plugin file as the slug.
|
37 |
-
//For example, 'my-cool-plugin/cool-plugin.php' becomes 'cool-plugin'.
|
38 |
-
if ( empty($slug) ){
|
39 |
-
$slug = basename($this->pluginFile, '.php');
|
40 |
-
}
|
41 |
-
|
42 |
-
//Plugin slugs must be unique.
|
43 |
-
$slugCheckFilter = 'puc_is_slug_in_use-' . $this->slug;
|
44 |
-
$slugUsedBy = apply_filters($slugCheckFilter, false);
|
45 |
-
if ( $slugUsedBy ) {
|
46 |
-
$this->triggerError(sprintf(
|
47 |
-
'Plugin slug "%s" is already in use by %s. Slugs must be unique.',
|
48 |
-
htmlentities($this->slug),
|
49 |
-
htmlentities($slugUsedBy)
|
50 |
-
), E_USER_ERROR);
|
51 |
-
}
|
52 |
-
add_filter($slugCheckFilter, array($this, 'getAbsolutePath'));
|
53 |
-
|
54 |
-
//Backwards compatibility: If the plugin is a mu-plugin but no $muPluginFile is specified, assume
|
55 |
-
//it's the same as $pluginFile given that it's not in a subdirectory (WP only looks in the base dir).
|
56 |
-
if ( (strpbrk($this->pluginFile, '/\\') === false) && $this->isUnknownMuPlugin() ) {
|
57 |
-
$this->muPluginFile = $this->pluginFile;
|
58 |
-
}
|
59 |
-
|
60 |
-
parent::__construct($metadataUrl, dirname($this->pluginFile), $slug, $checkPeriod, $optionName);
|
61 |
-
}
|
62 |
-
|
63 |
-
/**
|
64 |
-
* Create an instance of the scheduler.
|
65 |
-
*
|
66 |
-
* @param int $checkPeriod
|
67 |
-
* @return Puc_v4_Scheduler
|
68 |
-
*/
|
69 |
-
protected function createScheduler($checkPeriod) {
|
70 |
-
$scheduler = new Puc_v4_Scheduler($this, $checkPeriod, array('load-plugins.php'));
|
71 |
-
register_deactivation_hook($this->pluginFile, array($scheduler, 'removeUpdaterCron'));
|
72 |
-
return $scheduler;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Install the hooks required to run periodic update checks and inject update info
|
77 |
-
* into WP data structures.
|
78 |
-
*
|
79 |
-
* @return void
|
80 |
-
*/
|
81 |
-
protected function installHooks(){
|
82 |
-
//Override requests for plugin information
|
83 |
-
add_filter('plugins_api', array($this, 'injectInfo'), 20, 3);
|
84 |
-
|
85 |
-
add_filter('plugin_row_meta', array($this, 'addCheckForUpdatesLink'), 10, 2);
|
86 |
-
add_action('admin_init', array($this, 'handleManualCheck'));
|
87 |
-
add_action('all_admin_notices', array($this, 'displayManualCheckResult'));
|
88 |
-
|
89 |
-
//Clear the version number cache when something - anything - is upgraded or WP clears the update cache.
|
90 |
-
add_filter('upgrader_post_install', array($this, 'clearCachedVersion'));
|
91 |
-
add_action('delete_site_transient_update_plugins', array($this, 'clearCachedVersion'));
|
92 |
-
|
93 |
-
parent::installHooks();
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Retrieve plugin info from the configured API endpoint.
|
98 |
-
*
|
99 |
-
* @uses wp_remote_get()
|
100 |
-
*
|
101 |
-
* @param array $queryArgs Additional query arguments to append to the request. Optional.
|
102 |
-
* @return Puc_v4_Plugin_Info
|
103 |
-
*/
|
104 |
-
public function requestInfo($queryArgs = array()) {
|
105 |
-
list($pluginInfo, $result) = $this->requestMetadata('Puc_v4_Plugin_Info', 'request_info', $queryArgs);
|
106 |
-
|
107 |
-
if ( $pluginInfo !== null ) {
|
108 |
-
/** @var Puc_v4_Plugin_Info $pluginInfo */
|
109 |
-
$pluginInfo->filename = $this->pluginFile;
|
110 |
-
$pluginInfo->slug = $this->slug;
|
111 |
-
}
|
112 |
-
|
113 |
-
/* Edited By CartRabbit starts here */
|
114 |
-
try{
|
115 |
-
global $wp_version;
|
116 |
-
// include an unmodified $wp_version
|
117 |
-
include( ABSPATH . WPINC . '/version.php' );
|
118 |
-
$args = array('slug' => $this->slug, 'fields' => array('active_installs'));
|
119 |
-
$response = wp_remote_post(
|
120 |
-
'http://api.wordpress.org/plugins/info/1.0/',
|
121 |
-
array(
|
122 |
-
'user-agent' => 'WordPress/' . $wp_version . '; ' . home_url( '/' ),
|
123 |
-
'body' => array(
|
124 |
-
'action' => 'plugin_information',
|
125 |
-
'request'=>serialize((object)$args)
|
126 |
-
)
|
127 |
-
)
|
128 |
-
);
|
129 |
-
|
130 |
-
if(!empty($response)){
|
131 |
-
$returned_object = maybe_unserialize(wp_remote_retrieve_body($response));
|
132 |
-
if(!empty($returned_object)){
|
133 |
-
if(!empty($returned_object->name)) $pluginInfo->name = $returned_object->name;
|
134 |
-
if(!empty($returned_object->sections)) $pluginInfo->sections = $returned_object->sections;
|
135 |
-
if(!empty($returned_object->author)) $pluginInfo->author = $returned_object->author;
|
136 |
-
if(!empty($returned_object->author_profile)) $pluginInfo->author_profile = $returned_object->author_profile;
|
137 |
-
if(!empty($returned_object->requires)) $pluginInfo->requires = $returned_object->requires;
|
138 |
-
if(!empty($returned_object->tested)) $pluginInfo->tested = $returned_object->tested;
|
139 |
-
if(!empty($returned_object->rating)) $pluginInfo->rating = $returned_object->rating;
|
140 |
-
if(!empty($returned_object->ratings)) $pluginInfo->ratings = $returned_object->ratings;
|
141 |
-
if(!empty($returned_object->num_ratings)) $pluginInfo->num_ratings = $returned_object->num_ratings;
|
142 |
-
if(!empty($returned_object->support_threads)) $pluginInfo->support_threads = $returned_object->support_threads;
|
143 |
-
if(!empty($returned_object->support_threads_resolved)) $pluginInfo->support_threads_resolved = $returned_object->support_threads_resolved;
|
144 |
-
if(!empty($returned_object->downloaded)) $pluginInfo->downloaded = $returned_object->downloaded;
|
145 |
-
if(!empty($returned_object->last_updated)) $pluginInfo->last_updated = $returned_object->last_updated;
|
146 |
-
if(!empty($returned_object->added)) $pluginInfo->added = $returned_object->added;
|
147 |
-
if(!empty($returned_object->versions)) $pluginInfo->versions = $returned_object->versions;
|
148 |
-
if(!empty($returned_object->tags)) $pluginInfo->tags = $returned_object->tags;
|
149 |
-
if(!empty($returned_object->screenshots)) $pluginInfo->screenshots = $returned_object->screenshots;
|
150 |
-
if(!empty($returned_object->active_installs)) $pluginInfo->active_installs = $returned_object->active_installs;
|
151 |
-
}
|
152 |
-
}
|
153 |
-
} catch (Exception $e){}
|
154 |
-
|
155 |
-
/* Edited By CartRabbit Ends here */
|
156 |
-
|
157 |
-
$pluginInfo = apply_filters($this->getUniqueName('request_info_result'), $pluginInfo, $result);
|
158 |
-
return $pluginInfo;
|
159 |
-
}
|
160 |
-
|
161 |
-
/**
|
162 |
-
* Retrieve the latest update (if any) from the configured API endpoint.
|
163 |
-
*
|
164 |
-
* @uses PluginUpdateChecker::requestInfo()
|
165 |
-
*
|
166 |
-
* @return Puc_v4_Update|null An instance of Plugin_Update, or NULL when no updates are available.
|
167 |
-
*/
|
168 |
-
public function requestUpdate() {
|
169 |
-
//For the sake of simplicity, this function just calls requestInfo()
|
170 |
-
//and transforms the result accordingly.
|
171 |
-
$pluginInfo = $this->requestInfo(array('checking_for_updates' => '1'));
|
172 |
-
if ( $pluginInfo == null ){
|
173 |
-
return null;
|
174 |
-
}
|
175 |
-
$update = Puc_v4_Plugin_Update::fromPluginInfo($pluginInfo);
|
176 |
-
|
177 |
-
$update = $this->filterUpdateResult($update);
|
178 |
-
|
179 |
-
return $update;
|
180 |
-
}
|
181 |
-
|
182 |
-
/**
|
183 |
-
* Get the currently installed version of the plugin.
|
184 |
-
*
|
185 |
-
* @return string Version number.
|
186 |
-
*/
|
187 |
-
public function getInstalledVersion(){
|
188 |
-
if ( isset($this->cachedInstalledVersion) ) {
|
189 |
-
return $this->cachedInstalledVersion;
|
190 |
-
}
|
191 |
-
|
192 |
-
$pluginHeader = $this->getPluginHeader();
|
193 |
-
if ( isset($pluginHeader['Version']) ) {
|
194 |
-
$this->cachedInstalledVersion = $pluginHeader['Version'];
|
195 |
-
return $pluginHeader['Version'];
|
196 |
-
} else {
|
197 |
-
//This can happen if the filename points to something that is not a plugin.
|
198 |
-
$this->triggerError(
|
199 |
-
sprintf(
|
200 |
-
"Can't to read the Version header for '%s'. The filename is incorrect or is not a plugin.",
|
201 |
-
$this->pluginFile
|
202 |
-
),
|
203 |
-
E_USER_WARNING
|
204 |
-
);
|
205 |
-
return null;
|
206 |
-
}
|
207 |
-
}
|
208 |
-
|
209 |
-
/**
|
210 |
-
* Get plugin's metadata from its file header.
|
211 |
-
*
|
212 |
-
* @return array
|
213 |
-
*/
|
214 |
-
protected function getPluginHeader() {
|
215 |
-
if ( !is_file($this->pluginAbsolutePath) ) {
|
216 |
-
//This can happen if the plugin filename is wrong.
|
217 |
-
$this->triggerError(
|
218 |
-
sprintf(
|
219 |
-
"Can't to read the plugin header for '%s'. The file does not exist.",
|
220 |
-
$this->pluginFile
|
221 |
-
),
|
222 |
-
E_USER_WARNING
|
223 |
-
);
|
224 |
-
return array();
|
225 |
-
}
|
226 |
-
|
227 |
-
if ( !function_exists('get_plugin_data') ){
|
228 |
-
/** @noinspection PhpIncludeInspection */
|
229 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
230 |
-
}
|
231 |
-
return get_plugin_data($this->pluginAbsolutePath, false, false);
|
232 |
-
}
|
233 |
-
|
234 |
-
/**
|
235 |
-
* @return array
|
236 |
-
*/
|
237 |
-
protected function getHeaderNames() {
|
238 |
-
return array(
|
239 |
-
'Name' => 'Plugin Name',
|
240 |
-
'PluginURI' => 'Plugin URI',
|
241 |
-
'Version' => 'Version',
|
242 |
-
'Description' => 'Description',
|
243 |
-
'Author' => 'Author',
|
244 |
-
'AuthorURI' => 'Author URI',
|
245 |
-
'TextDomain' => 'Text Domain',
|
246 |
-
'DomainPath' => 'Domain Path',
|
247 |
-
'Network' => 'Network',
|
248 |
-
|
249 |
-
//The newest WordPress version that this plugin requires or has been tested with.
|
250 |
-
//We support several different formats for compatibility with other libraries.
|
251 |
-
'Tested WP' => 'Tested WP',
|
252 |
-
'Requires WP' => 'Requires WP',
|
253 |
-
'Tested up to' => 'Tested up to',
|
254 |
-
'Requires at least' => 'Requires at least',
|
255 |
-
);
|
256 |
-
}
|
257 |
-
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Intercept plugins_api() calls that request information about our plugin and
|
261 |
-
* use the configured API endpoint to satisfy them.
|
262 |
-
*
|
263 |
-
* @see plugins_api()
|
264 |
-
*
|
265 |
-
* @param mixed $result
|
266 |
-
* @param string $action
|
267 |
-
* @param array|object $args
|
268 |
-
* @return mixed
|
269 |
-
*/
|
270 |
-
public function injectInfo($result, $action = null, $args = null){
|
271 |
-
$relevant = ($action == 'plugin_information') && isset($args->slug) && (
|
272 |
-
($args->slug == $this->slug) || ($args->slug == dirname($this->pluginFile))
|
273 |
-
);
|
274 |
-
if ( !$relevant ) {
|
275 |
-
return $result;
|
276 |
-
}
|
277 |
-
|
278 |
-
$pluginInfo = $this->requestInfo();
|
279 |
-
$pluginInfo = apply_filters($this->getUniqueName('pre_inject_info'), $pluginInfo);
|
280 |
-
if ( $pluginInfo ) {
|
281 |
-
return $pluginInfo->toWpFormat();
|
282 |
-
}
|
283 |
-
|
284 |
-
return $result;
|
285 |
-
}
|
286 |
-
|
287 |
-
protected function shouldShowUpdates() {
|
288 |
-
//No update notifications for mu-plugins unless explicitly enabled. The MU plugin file
|
289 |
-
//is usually different from the main plugin file so the update wouldn't show up properly anyway.
|
290 |
-
return !$this->isUnknownMuPlugin();
|
291 |
-
}
|
292 |
-
|
293 |
-
/**
|
294 |
-
* @param stdClass|null $updates
|
295 |
-
* @param stdClass $updateToAdd
|
296 |
-
* @return stdClass
|
297 |
-
*/
|
298 |
-
protected function addUpdateToList($updates, $updateToAdd) {
|
299 |
-
if ( $this->isMuPlugin() ) {
|
300 |
-
//WP does not support automatic update installation for mu-plugins, but we can
|
301 |
-
//still display a notice.
|
302 |
-
$updateToAdd->package = null;
|
303 |
-
}
|
304 |
-
return parent::addUpdateToList($updates, $updateToAdd);
|
305 |
-
}
|
306 |
-
|
307 |
-
/**
|
308 |
-
* @param stdClass|null $updates
|
309 |
-
* @return stdClass|null
|
310 |
-
*/
|
311 |
-
protected function removeUpdateFromList($updates) {
|
312 |
-
$updates = parent::removeUpdateFromList($updates);
|
313 |
-
if ( !empty($this->muPluginFile) && isset($updates, $updates->response) ) {
|
314 |
-
unset($updates->response[$this->muPluginFile]);
|
315 |
-
}
|
316 |
-
return $updates;
|
317 |
-
}
|
318 |
-
|
319 |
-
/**
|
320 |
-
* For plugins, the update array is indexed by the plugin filename relative to the "plugins"
|
321 |
-
* directory. Example: "plugin-name/plugin.php".
|
322 |
-
*
|
323 |
-
* @return string
|
324 |
-
*/
|
325 |
-
protected function getUpdateListKey() {
|
326 |
-
if ( $this->isMuPlugin() ) {
|
327 |
-
return $this->muPluginFile;
|
328 |
-
}
|
329 |
-
return $this->pluginFile;
|
330 |
-
}
|
331 |
-
|
332 |
-
/**
|
333 |
-
* Alias for isBeingUpgraded().
|
334 |
-
*
|
335 |
-
* @deprecated
|
336 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
337 |
-
* @return bool
|
338 |
-
*/
|
339 |
-
public function isPluginBeingUpgraded($upgrader = null) {
|
340 |
-
return $this->isBeingUpgraded($upgrader);
|
341 |
-
}
|
342 |
-
|
343 |
-
/**
|
344 |
-
* Is there an update being installed for this plugin, right now?
|
345 |
-
*
|
346 |
-
* @param WP_Upgrader|null $upgrader
|
347 |
-
* @return bool
|
348 |
-
*/
|
349 |
-
public function isBeingUpgraded($upgrader = null) {
|
350 |
-
return $this->upgraderStatus->isPluginBeingUpgraded($this->pluginFile, $upgrader);
|
351 |
-
}
|
352 |
-
|
353 |
-
/**
|
354 |
-
* Get the details of the currently available update, if any.
|
355 |
-
*
|
356 |
-
* If no updates are available, or if the last known update version is below or equal
|
357 |
-
* to the currently installed version, this method will return NULL.
|
358 |
-
*
|
359 |
-
* Uses cached update data. To retrieve update information straight from
|
360 |
-
* the metadata URL, call requestUpdate() instead.
|
361 |
-
*
|
362 |
-
* @return Puc_v4_Plugin_Update|null
|
363 |
-
*/
|
364 |
-
public function getUpdate() {
|
365 |
-
$update = parent::getUpdate();
|
366 |
-
if ( isset($update) ) {
|
367 |
-
/** @var Puc_v4_Plugin_Update $update */
|
368 |
-
$update->filename = $this->pluginFile;
|
369 |
-
}
|
370 |
-
return $update;
|
371 |
-
}
|
372 |
-
|
373 |
-
/**
|
374 |
-
* Add a "Check for updates" link to the plugin row in the "Plugins" page. By default,
|
375 |
-
* the new link will appear after the "Visit plugin site" link.
|
376 |
-
*
|
377 |
-
* You can change the link text by using the "puc_manual_check_link-$slug" filter.
|
378 |
-
* Returning an empty string from the filter will disable the link.
|
379 |
-
*
|
380 |
-
* @param array $pluginMeta Array of meta links.
|
381 |
-
* @param string $pluginFile
|
382 |
-
* @return array
|
383 |
-
*/
|
384 |
-
public function addCheckForUpdatesLink($pluginMeta, $pluginFile) {
|
385 |
-
$isRelevant = ($pluginFile == $this->pluginFile)
|
386 |
-
|| (!empty($this->muPluginFile) && $pluginFile == $this->muPluginFile);
|
387 |
-
|
388 |
-
if ( $isRelevant && $this->userCanInstallUpdates() ) {
|
389 |
-
$linkUrl = wp_nonce_url(
|
390 |
-
add_query_arg(
|
391 |
-
array(
|
392 |
-
'puc_check_for_updates' => 1,
|
393 |
-
'puc_slug' => $this->slug,
|
394 |
-
),
|
395 |
-
self_admin_url('plugins.php')
|
396 |
-
),
|
397 |
-
'puc_check_for_updates'
|
398 |
-
);
|
399 |
-
|
400 |
-
$linkText = apply_filters(
|
401 |
-
$this->getUniqueName('manual_check_link'),
|
402 |
-
__('Check for updates', 'plugin-update-checker')
|
403 |
-
);
|
404 |
-
if ( !empty($linkText) ) {
|
405 |
-
/** @noinspection HtmlUnknownTarget */
|
406 |
-
$pluginMeta[] = sprintf('<a href="%s">%s</a>', esc_attr($linkUrl), $linkText);
|
407 |
-
}
|
408 |
-
}
|
409 |
-
return $pluginMeta;
|
410 |
-
}
|
411 |
-
|
412 |
-
/**
|
413 |
-
* Check for updates when the user clicks the "Check for updates" link.
|
414 |
-
* @see self::addCheckForUpdatesLink()
|
415 |
-
*
|
416 |
-
* @return void
|
417 |
-
*/
|
418 |
-
public function handleManualCheck() {
|
419 |
-
$shouldCheck =
|
420 |
-
isset($_GET['puc_check_for_updates'], $_GET['puc_slug'])
|
421 |
-
&& $_GET['puc_slug'] == $this->slug
|
422 |
-
&& $this->userCanInstallUpdates()
|
423 |
-
&& check_admin_referer('puc_check_for_updates');
|
424 |
-
|
425 |
-
if ( $shouldCheck ) {
|
426 |
-
$update = $this->checkForUpdates();
|
427 |
-
$status = ($update === null) ? 'no_update' : 'update_available';
|
428 |
-
wp_redirect(add_query_arg(
|
429 |
-
array(
|
430 |
-
'puc_update_check_result' => $status,
|
431 |
-
'puc_slug' => $this->slug,
|
432 |
-
),
|
433 |
-
self_admin_url('plugins.php')
|
434 |
-
));
|
435 |
-
}
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Display the results of a manual update check.
|
440 |
-
* @see self::handleManualCheck()
|
441 |
-
*
|
442 |
-
* You can change the result message by using the "puc_manual_check_message-$slug" filter.
|
443 |
-
*/
|
444 |
-
public function displayManualCheckResult() {
|
445 |
-
if ( isset($_GET['puc_update_check_result'], $_GET['puc_slug']) && ($_GET['puc_slug'] == $this->slug) ) {
|
446 |
-
$status = strval($_GET['puc_update_check_result']);
|
447 |
-
if ( $status == 'no_update' ) {
|
448 |
-
$message = __('This plugin is up to date.', 'plugin-update-checker');
|
449 |
-
} else if ( $status == 'update_available' ) {
|
450 |
-
$message = __('A new version of this plugin is available.', 'plugin-update-checker');
|
451 |
-
} else {
|
452 |
-
$message = sprintf(__('Unknown update checker status "%s"', 'plugin-update-checker'), htmlentities($status));
|
453 |
-
}
|
454 |
-
printf(
|
455 |
-
'<div class="updated notice is-dismissible"><p>%s</p></div>',
|
456 |
-
apply_filters($this->getUniqueName('manual_check_message'), $message, $status)
|
457 |
-
);
|
458 |
-
}
|
459 |
-
}
|
460 |
-
|
461 |
-
/**
|
462 |
-
* Check if the current user has the required permissions to install updates.
|
463 |
-
*
|
464 |
-
* @return bool
|
465 |
-
*/
|
466 |
-
public function userCanInstallUpdates() {
|
467 |
-
return current_user_can('update_plugins');
|
468 |
-
}
|
469 |
-
|
470 |
-
/**
|
471 |
-
* Check if the plugin file is inside the mu-plugins directory.
|
472 |
-
*
|
473 |
-
* @return bool
|
474 |
-
*/
|
475 |
-
protected function isMuPlugin() {
|
476 |
-
static $cachedResult = null;
|
477 |
-
|
478 |
-
if ( $cachedResult === null ) {
|
479 |
-
//Convert both paths to the canonical form before comparison.
|
480 |
-
$muPluginDir = realpath(WPMU_PLUGIN_DIR);
|
481 |
-
$pluginPath = realpath($this->pluginAbsolutePath);
|
482 |
-
|
483 |
-
$cachedResult = (strpos($pluginPath, $muPluginDir) === 0);
|
484 |
-
}
|
485 |
-
|
486 |
-
return $cachedResult;
|
487 |
-
}
|
488 |
-
|
489 |
-
/**
|
490 |
-
* MU plugins are partially supported, but only when we know which file in mu-plugins
|
491 |
-
* corresponds to this plugin.
|
492 |
-
*
|
493 |
-
* @return bool
|
494 |
-
*/
|
495 |
-
protected function isUnknownMuPlugin() {
|
496 |
-
return empty($this->muPluginFile) && $this->isMuPlugin();
|
497 |
-
}
|
498 |
-
|
499 |
-
/**
|
500 |
-
* Clear the cached plugin version. This method can be set up as a filter (hook) and will
|
501 |
-
* return the filter argument unmodified.
|
502 |
-
*
|
503 |
-
* @param mixed $filterArgument
|
504 |
-
* @return mixed
|
505 |
-
*/
|
506 |
-
public function clearCachedVersion($filterArgument = null) {
|
507 |
-
$this->cachedInstalledVersion = null;
|
508 |
-
return $filterArgument;
|
509 |
-
}
|
510 |
-
|
511 |
-
/**
|
512 |
-
* Get absolute path to the main plugin file.
|
513 |
-
*
|
514 |
-
* @return string
|
515 |
-
*/
|
516 |
-
public function getAbsolutePath() {
|
517 |
-
return $this->pluginAbsolutePath;
|
518 |
-
}
|
519 |
-
|
520 |
-
/**
|
521 |
-
* Register a callback for filtering query arguments.
|
522 |
-
*
|
523 |
-
* The callback function should take one argument - an associative array of query arguments.
|
524 |
-
* It should return a modified array of query arguments.
|
525 |
-
*
|
526 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
527 |
-
*
|
528 |
-
* @param callable $callback
|
529 |
-
* @return void
|
530 |
-
*/
|
531 |
-
public function addQueryArgFilter($callback){
|
532 |
-
$this->addFilter('request_info_query_args', $callback);
|
533 |
-
}
|
534 |
-
|
535 |
-
/**
|
536 |
-
* Register a callback for filtering arguments passed to wp_remote_get().
|
537 |
-
*
|
538 |
-
* The callback function should take one argument - an associative array of arguments -
|
539 |
-
* and return a modified array or arguments. See the WP documentation on wp_remote_get()
|
540 |
-
* for details on what arguments are available and how they work.
|
541 |
-
*
|
542 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
543 |
-
*
|
544 |
-
* @param callable $callback
|
545 |
-
* @return void
|
546 |
-
*/
|
547 |
-
public function addHttpRequestArgFilter($callback) {
|
548 |
-
$this->addFilter('request_info_options', $callback);
|
549 |
-
}
|
550 |
-
|
551 |
-
/**
|
552 |
-
* Register a callback for filtering the plugin info retrieved from the external API.
|
553 |
-
*
|
554 |
-
* The callback function should take two arguments. If the plugin info was retrieved
|
555 |
-
* successfully, the first argument passed will be an instance of PluginInfo. Otherwise,
|
556 |
-
* it will be NULL. The second argument will be the corresponding return value of
|
557 |
-
* wp_remote_get (see WP docs for details).
|
558 |
-
*
|
559 |
-
* The callback function should return a new or modified instance of PluginInfo or NULL.
|
560 |
-
*
|
561 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
562 |
-
*
|
563 |
-
* @param callable $callback
|
564 |
-
* @return void
|
565 |
-
*/
|
566 |
-
public function addResultFilter($callback) {
|
567 |
-
$this->addFilter('request_info_result', $callback, 10, 2);
|
568 |
-
}
|
569 |
-
|
570 |
-
protected function createDebugBarExtension() {
|
571 |
-
return new Puc_v4_DebugBar_PluginExtension($this);
|
572 |
-
}
|
573 |
-
}
|
574 |
-
|
575 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Scheduler.php
DELETED
@@ -1,177 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Scheduler', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* The scheduler decides when and how often to check for updates.
|
6 |
-
* It calls @see Puc_v4_UpdateChecker::checkForUpdates() to perform the actual checks.
|
7 |
-
*/
|
8 |
-
class Puc_v4_Scheduler {
|
9 |
-
public $checkPeriod = 12; //How often to check for updates (in hours).
|
10 |
-
public $throttleRedundantChecks = false; //Check less often if we already know that an update is available.
|
11 |
-
public $throttledCheckPeriod = 72;
|
12 |
-
|
13 |
-
protected $hourlyCheckHooks = array('load-update.php');
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var Puc_v4_UpdateChecker
|
17 |
-
*/
|
18 |
-
protected $updateChecker;
|
19 |
-
|
20 |
-
private $cronHook = null;
|
21 |
-
|
22 |
-
/**
|
23 |
-
* Scheduler constructor.
|
24 |
-
*
|
25 |
-
* @param Puc_v4_UpdateChecker $updateChecker
|
26 |
-
* @param int $checkPeriod How often to check for updates (in hours).
|
27 |
-
* @param array $hourlyHooks
|
28 |
-
*/
|
29 |
-
public function __construct($updateChecker, $checkPeriod, $hourlyHooks = array('load-plugins.php')) {
|
30 |
-
$this->updateChecker = $updateChecker;
|
31 |
-
$this->checkPeriod = $checkPeriod;
|
32 |
-
|
33 |
-
//Set up the periodic update checks
|
34 |
-
$this->cronHook = $this->updateChecker->getUniqueName('cron_check_updates');
|
35 |
-
if ( $this->checkPeriod > 0 ){
|
36 |
-
|
37 |
-
//Trigger the check via Cron.
|
38 |
-
//Try to use one of the default schedules if possible as it's less likely to conflict
|
39 |
-
//with other plugins and their custom schedules.
|
40 |
-
$defaultSchedules = array(
|
41 |
-
1 => 'hourly',
|
42 |
-
12 => 'twicedaily',
|
43 |
-
24 => 'daily',
|
44 |
-
);
|
45 |
-
if ( array_key_exists($this->checkPeriod, $defaultSchedules) ) {
|
46 |
-
$scheduleName = $defaultSchedules[$this->checkPeriod];
|
47 |
-
} else {
|
48 |
-
//Use a custom cron schedule.
|
49 |
-
$scheduleName = 'every' . $this->checkPeriod . 'hours';
|
50 |
-
add_filter('cron_schedules', array($this, '_addCustomSchedule'));
|
51 |
-
}
|
52 |
-
|
53 |
-
if ( !wp_next_scheduled($this->cronHook) && !defined('WP_INSTALLING') ) {
|
54 |
-
wp_schedule_event(time(), $scheduleName, $this->cronHook);
|
55 |
-
}
|
56 |
-
add_action($this->cronHook, array($this, 'maybeCheckForUpdates'));
|
57 |
-
|
58 |
-
//In case Cron is disabled or unreliable, we also manually trigger
|
59 |
-
//the periodic checks while the user is browsing the Dashboard.
|
60 |
-
add_action( 'admin_init', array($this, 'maybeCheckForUpdates') );
|
61 |
-
|
62 |
-
//Like WordPress itself, we check more often on certain pages.
|
63 |
-
/** @see wp_update_plugins */
|
64 |
-
add_action('load-update-core.php', array($this, 'maybeCheckForUpdates'));
|
65 |
-
//"load-update.php" and "load-plugins.php" or "load-themes.php".
|
66 |
-
$this->hourlyCheckHooks = array_merge($this->hourlyCheckHooks, $hourlyHooks);
|
67 |
-
foreach($this->hourlyCheckHooks as $hook) {
|
68 |
-
add_action($hook, array($this, 'maybeCheckForUpdates'));
|
69 |
-
}
|
70 |
-
//This hook fires after a bulk update is complete.
|
71 |
-
add_action('upgrader_process_complete', array($this, 'maybeCheckForUpdates'), 11, 0);
|
72 |
-
|
73 |
-
} else {
|
74 |
-
//Periodic checks are disabled.
|
75 |
-
wp_clear_scheduled_hook($this->cronHook);
|
76 |
-
}
|
77 |
-
}
|
78 |
-
|
79 |
-
/**
|
80 |
-
* Check for updates if the configured check interval has already elapsed.
|
81 |
-
* Will use a shorter check interval on certain admin pages like "Dashboard -> Updates" or when doing cron.
|
82 |
-
*
|
83 |
-
* You can override the default behaviour by using the "puc_check_now-$slug" filter.
|
84 |
-
* The filter callback will be passed three parameters:
|
85 |
-
* - Current decision. TRUE = check updates now, FALSE = don't check now.
|
86 |
-
* - Last check time as a Unix timestamp.
|
87 |
-
* - Configured check period in hours.
|
88 |
-
* Return TRUE to check for updates immediately, or FALSE to cancel.
|
89 |
-
*
|
90 |
-
* This method is declared public because it's a hook callback. Calling it directly is not recommended.
|
91 |
-
*/
|
92 |
-
public function maybeCheckForUpdates(){
|
93 |
-
if ( empty($this->checkPeriod) ){
|
94 |
-
return;
|
95 |
-
}
|
96 |
-
|
97 |
-
$state = $this->updateChecker->getUpdateState();
|
98 |
-
$shouldCheck = ($state->timeSinceLastCheck() >= $this->getEffectiveCheckPeriod());
|
99 |
-
|
100 |
-
//Let plugin authors substitute their own algorithm.
|
101 |
-
$shouldCheck = apply_filters(
|
102 |
-
$this->updateChecker->getUniqueName('check_now'),
|
103 |
-
$shouldCheck,
|
104 |
-
$state->getLastCheck(),
|
105 |
-
$this->checkPeriod
|
106 |
-
);
|
107 |
-
|
108 |
-
if ( $shouldCheck ) {
|
109 |
-
$this->updateChecker->checkForUpdates();
|
110 |
-
}
|
111 |
-
}
|
112 |
-
|
113 |
-
/**
|
114 |
-
* Calculate the actual check period based on the current status and environment.
|
115 |
-
*
|
116 |
-
* @return int Check period in seconds.
|
117 |
-
*/
|
118 |
-
protected function getEffectiveCheckPeriod() {
|
119 |
-
$currentFilter = current_filter();
|
120 |
-
if ( in_array($currentFilter, array('load-update-core.php', 'upgrader_process_complete')) ) {
|
121 |
-
//Check more often when the user visits "Dashboard -> Updates" or does a bulk update.
|
122 |
-
$period = 60;
|
123 |
-
} else if ( in_array($currentFilter, $this->hourlyCheckHooks) ) {
|
124 |
-
//Also check more often on /wp-admin/update.php and the "Plugins" or "Themes" page.
|
125 |
-
$period = 3600;
|
126 |
-
} else if ( $this->throttleRedundantChecks && ($this->updateChecker->getUpdate() !== null) ) {
|
127 |
-
//Check less frequently if it's already known that an update is available.
|
128 |
-
$period = $this->throttledCheckPeriod * 3600;
|
129 |
-
} else if ( defined('DOING_CRON') && constant('DOING_CRON') ) {
|
130 |
-
//WordPress cron schedules are not exact, so lets do an update check even
|
131 |
-
//if slightly less than $checkPeriod hours have elapsed since the last check.
|
132 |
-
$cronFuzziness = 20 * 60;
|
133 |
-
$period = $this->checkPeriod * 3600 - $cronFuzziness;
|
134 |
-
} else {
|
135 |
-
$period = $this->checkPeriod * 3600;
|
136 |
-
}
|
137 |
-
|
138 |
-
return $period;
|
139 |
-
}
|
140 |
-
|
141 |
-
/**
|
142 |
-
* Add our custom schedule to the array of Cron schedules used by WP.
|
143 |
-
*
|
144 |
-
* @param array $schedules
|
145 |
-
* @return array
|
146 |
-
*/
|
147 |
-
public function _addCustomSchedule($schedules){
|
148 |
-
if ( $this->checkPeriod && ($this->checkPeriod > 0) ){
|
149 |
-
$scheduleName = 'every' . $this->checkPeriod . 'hours';
|
150 |
-
$schedules[$scheduleName] = array(
|
151 |
-
'interval' => $this->checkPeriod * 3600,
|
152 |
-
'display' => sprintf('Every %d hours', $this->checkPeriod),
|
153 |
-
);
|
154 |
-
}
|
155 |
-
return $schedules;
|
156 |
-
}
|
157 |
-
|
158 |
-
/**
|
159 |
-
* Remove the scheduled cron event that the library uses to check for updates.
|
160 |
-
*
|
161 |
-
* @return void
|
162 |
-
*/
|
163 |
-
public function removeUpdaterCron(){
|
164 |
-
wp_clear_scheduled_hook($this->cronHook);
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Get the name of the update checker's WP-cron hook. Mostly useful for debugging.
|
169 |
-
*
|
170 |
-
* @return string
|
171 |
-
*/
|
172 |
-
public function getCronHookName() {
|
173 |
-
return $this->cronHook;
|
174 |
-
}
|
175 |
-
}
|
176 |
-
|
177 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/StateStore.php
DELETED
@@ -1,207 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_StateStore', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_StateStore {
|
6 |
-
/**
|
7 |
-
* @var int Last update check timestamp.
|
8 |
-
*/
|
9 |
-
protected $lastCheck = 0;
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @var string Version number.
|
13 |
-
*/
|
14 |
-
protected $checkedVersion = '';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @var Puc_v4_Update|null Cached update.
|
18 |
-
*/
|
19 |
-
protected $update = null;
|
20 |
-
|
21 |
-
/**
|
22 |
-
* @var string Site option name.
|
23 |
-
*/
|
24 |
-
private $optionName = '';
|
25 |
-
|
26 |
-
/**
|
27 |
-
* @var bool Whether we've already tried to load the state from the database.
|
28 |
-
*/
|
29 |
-
private $isLoaded = false;
|
30 |
-
|
31 |
-
public function __construct($optionName) {
|
32 |
-
$this->optionName = $optionName;
|
33 |
-
}
|
34 |
-
|
35 |
-
/**
|
36 |
-
* Get time elapsed since the last update check.
|
37 |
-
*
|
38 |
-
* If there are no recorded update checks, this method returns a large arbitrary number
|
39 |
-
* (i.e. time since the Unix epoch).
|
40 |
-
*
|
41 |
-
* @return int Elapsed time in seconds.
|
42 |
-
*/
|
43 |
-
public function timeSinceLastCheck() {
|
44 |
-
$this->lazyLoad();
|
45 |
-
return time() - $this->lastCheck;
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @return int
|
50 |
-
*/
|
51 |
-
public function getLastCheck() {
|
52 |
-
$this->lazyLoad();
|
53 |
-
return $this->lastCheck;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Set the time of the last update check to the current timestamp.
|
58 |
-
*
|
59 |
-
* @return $this
|
60 |
-
*/
|
61 |
-
public function setLastCheckToNow() {
|
62 |
-
$this->lazyLoad();
|
63 |
-
$this->lastCheck = time();
|
64 |
-
return $this;
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* @return null|Puc_v4_Update
|
69 |
-
*/
|
70 |
-
public function getUpdate() {
|
71 |
-
$this->lazyLoad();
|
72 |
-
return $this->update;
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* @param Puc_v4_Update|null $update
|
77 |
-
* @return $this
|
78 |
-
*/
|
79 |
-
public function setUpdate(Puc_v4_Update $update = null) {
|
80 |
-
$this->lazyLoad();
|
81 |
-
$this->update = $update;
|
82 |
-
return $this;
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* @return string
|
87 |
-
*/
|
88 |
-
public function getCheckedVersion() {
|
89 |
-
$this->lazyLoad();
|
90 |
-
return $this->checkedVersion;
|
91 |
-
}
|
92 |
-
|
93 |
-
/**
|
94 |
-
* @param string $version
|
95 |
-
* @return $this
|
96 |
-
*/
|
97 |
-
public function setCheckedVersion($version) {
|
98 |
-
$this->lazyLoad();
|
99 |
-
$this->checkedVersion = strval($version);
|
100 |
-
return $this;
|
101 |
-
}
|
102 |
-
|
103 |
-
/**
|
104 |
-
* Get translation updates.
|
105 |
-
*
|
106 |
-
* @return array
|
107 |
-
*/
|
108 |
-
public function getTranslations() {
|
109 |
-
$this->lazyLoad();
|
110 |
-
if ( isset($this->update, $this->update->translations) ) {
|
111 |
-
return $this->update->translations;
|
112 |
-
}
|
113 |
-
return array();
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Set translation updates.
|
118 |
-
*
|
119 |
-
* @param array $translationUpdates
|
120 |
-
*/
|
121 |
-
public function setTranslations($translationUpdates) {
|
122 |
-
$this->lazyLoad();
|
123 |
-
if ( isset($this->update) ) {
|
124 |
-
$this->update->translations = $translationUpdates;
|
125 |
-
$this->save();
|
126 |
-
}
|
127 |
-
}
|
128 |
-
|
129 |
-
public function save() {
|
130 |
-
$state = new stdClass();
|
131 |
-
|
132 |
-
$state->lastCheck = $this->lastCheck;
|
133 |
-
$state->checkedVersion = $this->checkedVersion;
|
134 |
-
|
135 |
-
if ( isset($this->update)) {
|
136 |
-
$state->update = $this->update->toStdClass();
|
137 |
-
|
138 |
-
$updateClass = get_class($this->update);
|
139 |
-
$state->updateClass = $updateClass;
|
140 |
-
$prefix = $this->getLibPrefix();
|
141 |
-
if ( Puc_v4_Utils::startsWith($updateClass, $prefix) ) {
|
142 |
-
$state->updateBaseClass = substr($updateClass, strlen($prefix));
|
143 |
-
}
|
144 |
-
}
|
145 |
-
|
146 |
-
update_site_option($this->optionName, $state);
|
147 |
-
$this->isLoaded = true;
|
148 |
-
}
|
149 |
-
|
150 |
-
/**
|
151 |
-
* @return $this
|
152 |
-
*/
|
153 |
-
public function lazyLoad() {
|
154 |
-
if ( !$this->isLoaded ) {
|
155 |
-
$this->load();
|
156 |
-
}
|
157 |
-
return $this;
|
158 |
-
}
|
159 |
-
|
160 |
-
protected function load() {
|
161 |
-
$this->isLoaded = true;
|
162 |
-
|
163 |
-
$state = get_site_option($this->optionName, null);
|
164 |
-
|
165 |
-
if ( !is_object($state) ) {
|
166 |
-
$this->lastCheck = 0;
|
167 |
-
$this->checkedVersion = '';
|
168 |
-
$this->update = null;
|
169 |
-
return;
|
170 |
-
}
|
171 |
-
|
172 |
-
$this->lastCheck = intval(Puc_v4_Utils::get($state, 'lastCheck', 0));
|
173 |
-
$this->checkedVersion = Puc_v4_Utils::get($state, 'checkedVersion', '');
|
174 |
-
$this->update = null;
|
175 |
-
|
176 |
-
if ( isset($state->update) ) {
|
177 |
-
//This mess is due to the fact that the want the update class from this version
|
178 |
-
//of the library, not the version that saved the update.
|
179 |
-
|
180 |
-
$updateClass = null;
|
181 |
-
if ( isset($state->updateBaseClass) ) {
|
182 |
-
$updateClass = $this->getLibPrefix() . $state->updateBaseClass;
|
183 |
-
} else if ( isset($state->updateClass) && class_exists($state->updateClass) ) {
|
184 |
-
$updateClass = $state->updateClass;
|
185 |
-
}
|
186 |
-
|
187 |
-
if ( $updateClass !== null ) {
|
188 |
-
$this->update = call_user_func(array($updateClass, 'fromObject'), $state->update);
|
189 |
-
}
|
190 |
-
}
|
191 |
-
}
|
192 |
-
|
193 |
-
public function delete() {
|
194 |
-
delete_site_option($this->optionName);
|
195 |
-
|
196 |
-
$this->lastCheck = 0;
|
197 |
-
$this->checkedVersion = '';
|
198 |
-
$this->update = null;
|
199 |
-
}
|
200 |
-
|
201 |
-
private function getLibPrefix() {
|
202 |
-
$parts = explode('_', __CLASS__, 3);
|
203 |
-
return $parts[0] . '_' . $parts[1] . '_';
|
204 |
-
}
|
205 |
-
}
|
206 |
-
|
207 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Theme/Update.php
DELETED
@@ -1,84 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_Theme_Update', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_Theme_Update extends Puc_v4_Update {
|
6 |
-
public $details_url = '';
|
7 |
-
|
8 |
-
protected static $extraFields = array('details_url');
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Transform the metadata into the format used by WordPress core.
|
12 |
-
* Note the inconsistency: WP stores plugin updates as objects and theme updates as arrays.
|
13 |
-
*
|
14 |
-
* @return array
|
15 |
-
*/
|
16 |
-
public function toWpFormat() {
|
17 |
-
$update = array(
|
18 |
-
'theme' => $this->slug,
|
19 |
-
'new_version' => $this->version,
|
20 |
-
'url' => $this->details_url,
|
21 |
-
);
|
22 |
-
|
23 |
-
if ( !empty($this->download_url) ) {
|
24 |
-
$update['package'] = $this->download_url;
|
25 |
-
}
|
26 |
-
|
27 |
-
return $update;
|
28 |
-
}
|
29 |
-
|
30 |
-
/**
|
31 |
-
* Create a new instance of Theme_Update from its JSON-encoded representation.
|
32 |
-
*
|
33 |
-
* @param string $json Valid JSON string representing a theme information object.
|
34 |
-
* @return self New instance of ThemeUpdate, or NULL on error.
|
35 |
-
*/
|
36 |
-
public static function fromJson($json) {
|
37 |
-
$instance = new self();
|
38 |
-
if ( !parent::createFromJson($json, $instance) ) {
|
39 |
-
return null;
|
40 |
-
}
|
41 |
-
return $instance;
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Create a new instance by copying the necessary fields from another object.
|
46 |
-
*
|
47 |
-
* @param StdClass|Puc_v4_Theme_Update $object The source object.
|
48 |
-
* @return Puc_v4_Theme_Update The new copy.
|
49 |
-
*/
|
50 |
-
public static function fromObject($object) {
|
51 |
-
$update = new self();
|
52 |
-
$update->copyFields($object, $update);
|
53 |
-
return $update;
|
54 |
-
}
|
55 |
-
|
56 |
-
/**
|
57 |
-
* Basic validation.
|
58 |
-
*
|
59 |
-
* @param StdClass $apiResponse
|
60 |
-
* @return bool|WP_Error
|
61 |
-
*/
|
62 |
-
protected function validateMetadata($apiResponse) {
|
63 |
-
$required = array('version', 'details_url');
|
64 |
-
foreach($required as $key) {
|
65 |
-
if ( !isset($apiResponse->$key) || empty($apiResponse->$key) ) {
|
66 |
-
return new WP_Error(
|
67 |
-
'tuc-invalid-metadata',
|
68 |
-
sprintf('The theme metadata is missing the required "%s" key.', $key)
|
69 |
-
);
|
70 |
-
}
|
71 |
-
}
|
72 |
-
return true;
|
73 |
-
}
|
74 |
-
|
75 |
-
protected function getFieldNames() {
|
76 |
-
return array_merge(parent::getFieldNames(), self::$extraFields);
|
77 |
-
}
|
78 |
-
|
79 |
-
protected function getPrefixedFilter($tag) {
|
80 |
-
return parent::getPrefixedFilter($tag) . '_theme';
|
81 |
-
}
|
82 |
-
}
|
83 |
-
|
84 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Theme/UpdateChecker.php
DELETED
@@ -1,167 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_Theme_UpdateChecker', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_Theme_UpdateChecker extends Puc_v4_UpdateChecker {
|
6 |
-
protected $filterSuffix = 'theme';
|
7 |
-
protected $updateTransient = 'update_themes';
|
8 |
-
protected $translationType = 'theme';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string Theme directory name.
|
12 |
-
*/
|
13 |
-
protected $stylesheet;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var WP_Theme Theme object.
|
17 |
-
*/
|
18 |
-
protected $theme;
|
19 |
-
|
20 |
-
public function __construct($metadataUrl, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
|
21 |
-
if ( $stylesheet === null ) {
|
22 |
-
$stylesheet = get_stylesheet();
|
23 |
-
}
|
24 |
-
$this->stylesheet = $stylesheet;
|
25 |
-
$this->theme = wp_get_theme($this->stylesheet);
|
26 |
-
|
27 |
-
parent::__construct(
|
28 |
-
$metadataUrl,
|
29 |
-
$stylesheet,
|
30 |
-
$customSlug ? $customSlug : $stylesheet,
|
31 |
-
$checkPeriod,
|
32 |
-
$optionName
|
33 |
-
);
|
34 |
-
}
|
35 |
-
|
36 |
-
/**
|
37 |
-
* For themes, the update array is indexed by theme directory name.
|
38 |
-
*
|
39 |
-
* @return string
|
40 |
-
*/
|
41 |
-
protected function getUpdateListKey() {
|
42 |
-
return $this->directoryName;
|
43 |
-
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* Retrieve the latest update (if any) from the configured API endpoint.
|
47 |
-
*
|
48 |
-
* @return Puc_v4_Update|null An instance of Update, or NULL when no updates are available.
|
49 |
-
*/
|
50 |
-
public function requestUpdate() {
|
51 |
-
list($themeUpdate, $result) = $this->requestMetadata('Puc_v4_Theme_Update', 'request_update');
|
52 |
-
|
53 |
-
if ( $themeUpdate !== null ) {
|
54 |
-
/** @var Puc_v4_Theme_Update $themeUpdate */
|
55 |
-
$themeUpdate->slug = $this->slug;
|
56 |
-
}
|
57 |
-
|
58 |
-
$themeUpdate = $this->filterUpdateResult($themeUpdate, $result);
|
59 |
-
return $themeUpdate;
|
60 |
-
}
|
61 |
-
|
62 |
-
public function userCanInstallUpdates() {
|
63 |
-
return current_user_can('update_themes');
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Get the currently installed version of the plugin or theme.
|
68 |
-
*
|
69 |
-
* @return string Version number.
|
70 |
-
*/
|
71 |
-
public function getInstalledVersion() {
|
72 |
-
return $this->theme->get('Version');
|
73 |
-
}
|
74 |
-
|
75 |
-
/**
|
76 |
-
* Create an instance of the scheduler.
|
77 |
-
*
|
78 |
-
* @param int $checkPeriod
|
79 |
-
* @return Puc_v4_Scheduler
|
80 |
-
*/
|
81 |
-
protected function createScheduler($checkPeriod) {
|
82 |
-
return new Puc_v4_Scheduler($this, $checkPeriod, array('load-themes.php'));
|
83 |
-
}
|
84 |
-
|
85 |
-
/**
|
86 |
-
* Is there an update being installed right now for this theme?
|
87 |
-
*
|
88 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
89 |
-
* @return bool
|
90 |
-
*/
|
91 |
-
public function isBeingUpgraded($upgrader = null) {
|
92 |
-
return $this->upgraderStatus->isThemeBeingUpgraded($this->stylesheet, $upgrader);
|
93 |
-
}
|
94 |
-
|
95 |
-
protected function createDebugBarExtension() {
|
96 |
-
return new Puc_v4_DebugBar_Extension($this, 'Puc_v4_DebugBar_ThemePanel');
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Register a callback for filtering query arguments.
|
101 |
-
*
|
102 |
-
* The callback function should take one argument - an associative array of query arguments.
|
103 |
-
* It should return a modified array of query arguments.
|
104 |
-
*
|
105 |
-
* @param callable $callback
|
106 |
-
* @return void
|
107 |
-
*/
|
108 |
-
public function addQueryArgFilter($callback){
|
109 |
-
$this->addFilter('request_update_query_args', $callback);
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Register a callback for filtering arguments passed to wp_remote_get().
|
114 |
-
*
|
115 |
-
* The callback function should take one argument - an associative array of arguments -
|
116 |
-
* and return a modified array or arguments. See the WP documentation on wp_remote_get()
|
117 |
-
* for details on what arguments are available and how they work.
|
118 |
-
*
|
119 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
120 |
-
*
|
121 |
-
* @param callable $callback
|
122 |
-
* @return void
|
123 |
-
*/
|
124 |
-
public function addHttpRequestArgFilter($callback) {
|
125 |
-
$this->addFilter('request_update_options', $callback);
|
126 |
-
}
|
127 |
-
|
128 |
-
/**
|
129 |
-
* Register a callback for filtering theme updates retrieved from the external API.
|
130 |
-
*
|
131 |
-
* The callback function should take two arguments. If the theme update was retrieved
|
132 |
-
* successfully, the first argument passed will be an instance of Theme_Update. Otherwise,
|
133 |
-
* it will be NULL. The second argument will be the corresponding return value of
|
134 |
-
* wp_remote_get (see WP docs for details).
|
135 |
-
*
|
136 |
-
* The callback function should return a new or modified instance of Theme_Update or NULL.
|
137 |
-
*
|
138 |
-
* @uses add_filter() This method is a convenience wrapper for add_filter().
|
139 |
-
*
|
140 |
-
* @param callable $callback
|
141 |
-
* @return void
|
142 |
-
*/
|
143 |
-
public function addResultFilter($callback) {
|
144 |
-
$this->addFilter('request_update_result', $callback, 10, 2);
|
145 |
-
}
|
146 |
-
|
147 |
-
/**
|
148 |
-
* @return array
|
149 |
-
*/
|
150 |
-
protected function getHeaderNames() {
|
151 |
-
return array(
|
152 |
-
'Name' => 'Theme Name',
|
153 |
-
'ThemeURI' => 'Theme URI',
|
154 |
-
'Description' => 'Description',
|
155 |
-
'Author' => 'Author',
|
156 |
-
'AuthorURI' => 'Author URI',
|
157 |
-
'Version' => 'Version',
|
158 |
-
'Template' => 'Template',
|
159 |
-
'Status' => 'Status',
|
160 |
-
'Tags' => 'Tags',
|
161 |
-
'TextDomain' => 'Text Domain',
|
162 |
-
'DomainPath' => 'Domain Path',
|
163 |
-
);
|
164 |
-
}
|
165 |
-
}
|
166 |
-
|
167 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Update.php
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Update', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A simple container class for holding information about an available update.
|
6 |
-
*
|
7 |
-
* @author Janis Elsts
|
8 |
-
* @access public
|
9 |
-
*/
|
10 |
-
abstract class Puc_v4_Update extends Puc_v4_Metadata {
|
11 |
-
public $slug;
|
12 |
-
public $version;
|
13 |
-
public $download_url;
|
14 |
-
public $translations = array();
|
15 |
-
|
16 |
-
/**
|
17 |
-
* @return string[]
|
18 |
-
*/
|
19 |
-
protected function getFieldNames() {
|
20 |
-
return array('slug', 'version', 'download_url', 'translations');
|
21 |
-
}
|
22 |
-
|
23 |
-
public function toWpFormat() {
|
24 |
-
$update = new stdClass();
|
25 |
-
|
26 |
-
$update->slug = $this->slug;
|
27 |
-
$update->new_version = $this->version;
|
28 |
-
$update->package = $this->download_url;
|
29 |
-
|
30 |
-
return $update;
|
31 |
-
}
|
32 |
-
}
|
33 |
-
|
34 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/UpdateChecker.php
DELETED
@@ -1,828 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_UpdateChecker', false) ):
|
4 |
-
|
5 |
-
abstract class Puc_v4_UpdateChecker {
|
6 |
-
protected $filterSuffix = '';
|
7 |
-
protected $updateTransient = '';
|
8 |
-
protected $translationType = ''; //"plugin" or "theme".
|
9 |
-
|
10 |
-
/**
|
11 |
-
* Set to TRUE to enable error reporting. Errors are raised using trigger_error()
|
12 |
-
* and should be logged to the standard PHP error log.
|
13 |
-
* @var bool
|
14 |
-
*/
|
15 |
-
public $debugMode = false;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string Where to store the update info.
|
19 |
-
*/
|
20 |
-
public $optionName = '';
|
21 |
-
|
22 |
-
/**
|
23 |
-
* @var string The URL of the metadata file.
|
24 |
-
*/
|
25 |
-
public $metadataUrl = '';
|
26 |
-
|
27 |
-
/**
|
28 |
-
* @var string Plugin or theme directory name.
|
29 |
-
*/
|
30 |
-
public $directoryName = '';
|
31 |
-
|
32 |
-
/**
|
33 |
-
* @var string The slug that will be used in update checker hooks and remote API requests.
|
34 |
-
* Usually matches the directory name unless the plugin/theme directory has been renamed.
|
35 |
-
*/
|
36 |
-
public $slug = '';
|
37 |
-
|
38 |
-
/**
|
39 |
-
* @var Puc_v4_Scheduler
|
40 |
-
*/
|
41 |
-
public $scheduler;
|
42 |
-
|
43 |
-
/**
|
44 |
-
* @var Puc_v4_UpgraderStatus
|
45 |
-
*/
|
46 |
-
protected $upgraderStatus;
|
47 |
-
|
48 |
-
/**
|
49 |
-
* @var Puc_v4_StateStore
|
50 |
-
*/
|
51 |
-
protected $updateState;
|
52 |
-
|
53 |
-
public function __construct($metadataUrl, $directoryName, $slug = null, $checkPeriod = 12, $optionName = '') {
|
54 |
-
$this->debugMode = (bool)(constant('WP_DEBUG'));
|
55 |
-
$this->metadataUrl = $metadataUrl;
|
56 |
-
$this->directoryName = $directoryName;
|
57 |
-
$this->slug = !empty($slug) ? $slug : $this->directoryName;
|
58 |
-
|
59 |
-
$this->optionName = $optionName;
|
60 |
-
if ( empty($this->optionName) ) {
|
61 |
-
//BC: Initially the library only supported plugin updates and didn't use type prefixes
|
62 |
-
//in the option name. Lets use the same prefix-less name when possible.
|
63 |
-
if ( $this->filterSuffix === '' ) {
|
64 |
-
$this->optionName = 'external_updates-' . $this->slug;
|
65 |
-
} else {
|
66 |
-
$this->optionName = $this->getUniqueName('external_updates');
|
67 |
-
}
|
68 |
-
}
|
69 |
-
|
70 |
-
$this->scheduler = $this->createScheduler($checkPeriod);
|
71 |
-
$this->upgraderStatus = new Puc_v4_UpgraderStatus();
|
72 |
-
$this->updateState = new Puc_v4_StateStore($this->optionName);
|
73 |
-
|
74 |
-
if ( did_action('init') ) {
|
75 |
-
$this->loadTextDomain();
|
76 |
-
} else {
|
77 |
-
add_action('init', array($this, 'loadTextDomain'));
|
78 |
-
}
|
79 |
-
|
80 |
-
$this->installHooks();
|
81 |
-
}
|
82 |
-
|
83 |
-
/**
|
84 |
-
* @internal
|
85 |
-
*/
|
86 |
-
public function loadTextDomain() {
|
87 |
-
//We're not using load_plugin_textdomain() or its siblings because figuring out where
|
88 |
-
//the library is located (plugin, mu-plugin, theme, custom wp-content paths) is messy.
|
89 |
-
$domain = 'plugin-update-checker';
|
90 |
-
$locale = apply_filters(
|
91 |
-
'plugin_locale',
|
92 |
-
(is_admin() && function_exists('get_user_locale')) ? get_user_locale() : get_locale(),
|
93 |
-
$domain
|
94 |
-
);
|
95 |
-
|
96 |
-
$moFile = $domain . '-' . $locale . '.mo';
|
97 |
-
$path = realpath(dirname(__FILE__) . '/../../languages');
|
98 |
-
|
99 |
-
if ($path && file_exists($path)) {
|
100 |
-
load_textdomain($domain, $path . '/' . $moFile);
|
101 |
-
}
|
102 |
-
}
|
103 |
-
|
104 |
-
protected function installHooks() {
|
105 |
-
//Insert our update info into the update array maintained by WP.
|
106 |
-
add_filter('site_transient_' . $this->updateTransient, array($this,'injectUpdate'));
|
107 |
-
|
108 |
-
//Insert translation updates into the update list.
|
109 |
-
add_filter('site_transient_' . $this->updateTransient, array($this, 'injectTranslationUpdates'));
|
110 |
-
|
111 |
-
//Clear translation updates when WP clears the update cache.
|
112 |
-
//This needs to be done directly because the library doesn't actually remove obsolete plugin updates,
|
113 |
-
//it just hides them (see getUpdate()). We can't do that with translations - too much disk I/O.
|
114 |
-
add_action(
|
115 |
-
'delete_site_transient_' . $this->updateTransient,
|
116 |
-
array($this, 'clearCachedTranslationUpdates')
|
117 |
-
);
|
118 |
-
|
119 |
-
//Rename the update directory to be the same as the existing directory.
|
120 |
-
if ( $this->directoryName !== '.' ) {
|
121 |
-
add_filter('upgrader_source_selection', array($this, 'fixDirectoryName'), 10, 3);
|
122 |
-
}
|
123 |
-
|
124 |
-
//Allow HTTP requests to the metadata URL even if it's on a local host.
|
125 |
-
add_filter('http_request_host_is_external', array($this, 'allowMetadataHost'), 10, 2);
|
126 |
-
|
127 |
-
//DebugBar integration.
|
128 |
-
if ( did_action('plugins_loaded') ) {
|
129 |
-
$this->maybeInitDebugBar();
|
130 |
-
} else {
|
131 |
-
add_action('plugins_loaded', array($this, 'maybeInitDebugBar'));
|
132 |
-
}
|
133 |
-
}
|
134 |
-
|
135 |
-
/**
|
136 |
-
* Check if the current user has the required permissions to install updates.
|
137 |
-
*
|
138 |
-
* @return bool
|
139 |
-
*/
|
140 |
-
abstract public function userCanInstallUpdates();
|
141 |
-
|
142 |
-
/**
|
143 |
-
* Explicitly allow HTTP requests to the metadata URL.
|
144 |
-
*
|
145 |
-
* WordPress has a security feature where the HTTP API will reject all requests that are sent to
|
146 |
-
* another site hosted on the same server as the current site (IP match), a local host, or a local
|
147 |
-
* IP, unless the host exactly matches the current site.
|
148 |
-
*
|
149 |
-
* This feature is opt-in (at least in WP 4.4). Apparently some people enable it.
|
150 |
-
*
|
151 |
-
* That can be a problem when you're developing your plugin and you decide to host the update information
|
152 |
-
* on the same server as your test site. Update requests will mysteriously fail.
|
153 |
-
*
|
154 |
-
* We fix that by adding an exception for the metadata host.
|
155 |
-
*
|
156 |
-
* @param bool $allow
|
157 |
-
* @param string $host
|
158 |
-
* @return bool
|
159 |
-
*/
|
160 |
-
public function allowMetadataHost($allow, $host) {
|
161 |
-
static $metadataHost = 0; //Using 0 instead of NULL because parse_url can return NULL.
|
162 |
-
if ( $metadataHost === 0 ) {
|
163 |
-
$metadataHost = @parse_url($this->metadataUrl, PHP_URL_HOST);
|
164 |
-
}
|
165 |
-
|
166 |
-
if ( is_string($metadataHost) && (strtolower($host) === strtolower($metadataHost)) ) {
|
167 |
-
return true;
|
168 |
-
}
|
169 |
-
return $allow;
|
170 |
-
}
|
171 |
-
|
172 |
-
/**
|
173 |
-
* Create an instance of the scheduler.
|
174 |
-
*
|
175 |
-
* This is implemented as a method to make it possible for plugins to subclass the update checker
|
176 |
-
* and substitute their own scheduler.
|
177 |
-
*
|
178 |
-
* @param int $checkPeriod
|
179 |
-
* @return Puc_v4_Scheduler
|
180 |
-
*/
|
181 |
-
abstract protected function createScheduler($checkPeriod);
|
182 |
-
|
183 |
-
/**
|
184 |
-
* Check for updates. The results are stored in the DB option specified in $optionName.
|
185 |
-
*
|
186 |
-
* @return Puc_v4_Update|null
|
187 |
-
*/
|
188 |
-
public function checkForUpdates() {
|
189 |
-
$installedVersion = $this->getInstalledVersion();
|
190 |
-
//Fail silently if we can't find the plugin/theme or read its header.
|
191 |
-
if ( $installedVersion === null ) {
|
192 |
-
$this->triggerError(
|
193 |
-
sprintf('Skipping update check for %s - installed version unknown.', $this->slug),
|
194 |
-
E_USER_WARNING
|
195 |
-
);
|
196 |
-
return null;
|
197 |
-
}
|
198 |
-
|
199 |
-
$state = $this->updateState;
|
200 |
-
$state->setLastCheckToNow()
|
201 |
-
->setCheckedVersion($installedVersion)
|
202 |
-
->save(); //Save before checking in case something goes wrong
|
203 |
-
|
204 |
-
$state->setUpdate($this->requestUpdate());
|
205 |
-
$state->save();
|
206 |
-
|
207 |
-
return $this->getUpdate();
|
208 |
-
}
|
209 |
-
|
210 |
-
/**
|
211 |
-
* Load the update checker state from the DB.
|
212 |
-
*
|
213 |
-
* @return Puc_v4_StateStore
|
214 |
-
*/
|
215 |
-
public function getUpdateState() {
|
216 |
-
return $this->updateState->lazyLoad();
|
217 |
-
}
|
218 |
-
|
219 |
-
/**
|
220 |
-
* Reset update checker state - i.e. last check time, cached update data and so on.
|
221 |
-
*
|
222 |
-
* Call this when your plugin is being uninstalled, or if you want to
|
223 |
-
* clear the update cache.
|
224 |
-
*/
|
225 |
-
public function resetUpdateState() {
|
226 |
-
$this->updateState->delete();
|
227 |
-
}
|
228 |
-
|
229 |
-
/**
|
230 |
-
* Get the details of the currently available update, if any.
|
231 |
-
*
|
232 |
-
* If no updates are available, or if the last known update version is below or equal
|
233 |
-
* to the currently installed version, this method will return NULL.
|
234 |
-
*
|
235 |
-
* Uses cached update data. To retrieve update information straight from
|
236 |
-
* the metadata URL, call requestUpdate() instead.
|
237 |
-
*
|
238 |
-
* @return Puc_v4_Update|null
|
239 |
-
*/
|
240 |
-
public function getUpdate() {
|
241 |
-
$update = $this->updateState->getUpdate();
|
242 |
-
|
243 |
-
//Is there an update available?
|
244 |
-
if ( isset($update) ) {
|
245 |
-
//Check if the update is actually newer than the currently installed version.
|
246 |
-
$installedVersion = $this->getInstalledVersion();
|
247 |
-
|
248 |
-
/***************************** FORCE AN UPDATE ****************************************/
|
249 |
-
$force_updates = get_option($update->slug.'-force-update-pro', true);
|
250 |
-
|
251 |
-
if ($force_updates) {
|
252 |
-
return $update;
|
253 |
-
}
|
254 |
-
/****************************** FORCE AN UPDATE ***************************************/
|
255 |
-
|
256 |
-
if ( ($installedVersion !== null) && version_compare($update->version, $installedVersion, '>') ){
|
257 |
-
return $update;
|
258 |
-
}
|
259 |
-
}
|
260 |
-
return null;
|
261 |
-
}
|
262 |
-
|
263 |
-
/**
|
264 |
-
* Retrieve the latest update (if any) from the configured API endpoint.
|
265 |
-
*
|
266 |
-
* Subclasses should run the update through filterUpdateResult before returning it.
|
267 |
-
*
|
268 |
-
* @return Puc_v4_Update An instance of Update, or NULL when no updates are available.
|
269 |
-
*/
|
270 |
-
abstract public function requestUpdate();
|
271 |
-
|
272 |
-
/**
|
273 |
-
* Filter the result of a requestUpdate() call.
|
274 |
-
*
|
275 |
-
* @param Puc_v4_Update|null $update
|
276 |
-
* @param array|WP_Error|null $httpResult The value returned by wp_remote_get(), if any.
|
277 |
-
* @return Puc_v4_Update
|
278 |
-
*/
|
279 |
-
protected function filterUpdateResult($update, $httpResult = null) {
|
280 |
-
//Let plugins/themes modify the update.
|
281 |
-
$update = apply_filters($this->getUniqueName('request_update_result'), $update, $httpResult);
|
282 |
-
|
283 |
-
if ( isset($update, $update->translations) ) {
|
284 |
-
//Keep only those translation updates that apply to this site.
|
285 |
-
$update->translations = $this->filterApplicableTranslations($update->translations);
|
286 |
-
}
|
287 |
-
|
288 |
-
return $update;
|
289 |
-
}
|
290 |
-
|
291 |
-
/**
|
292 |
-
* Get the currently installed version of the plugin or theme.
|
293 |
-
*
|
294 |
-
* @return string Version number.
|
295 |
-
*/
|
296 |
-
abstract public function getInstalledVersion();
|
297 |
-
|
298 |
-
/**
|
299 |
-
* Trigger a PHP error, but only when $debugMode is enabled.
|
300 |
-
*
|
301 |
-
* @param string $message
|
302 |
-
* @param int $errorType
|
303 |
-
*/
|
304 |
-
protected function triggerError($message, $errorType) {
|
305 |
-
if ($this->debugMode) {
|
306 |
-
trigger_error($message, $errorType);
|
307 |
-
}
|
308 |
-
}
|
309 |
-
|
310 |
-
/**
|
311 |
-
* Get the full name of an update checker filter, action or DB entry.
|
312 |
-
*
|
313 |
-
* This method adds the "puc_" prefix and the "-$slug" suffix to the filter name.
|
314 |
-
* For example, "pre_inject_update" becomes "puc_pre_inject_update-plugin-slug".
|
315 |
-
*
|
316 |
-
* @param string $baseTag
|
317 |
-
* @return string
|
318 |
-
*/
|
319 |
-
public function getUniqueName($baseTag) {
|
320 |
-
$name = 'puc_' . $baseTag;
|
321 |
-
if ($this->filterSuffix !== '') {
|
322 |
-
$name .= '_' . $this->filterSuffix;
|
323 |
-
}
|
324 |
-
return $name . '-' . $this->slug;
|
325 |
-
}
|
326 |
-
|
327 |
-
/* -------------------------------------------------------------------
|
328 |
-
* PUC filters and filter utilities
|
329 |
-
* -------------------------------------------------------------------
|
330 |
-
*/
|
331 |
-
|
332 |
-
/**
|
333 |
-
* Register a callback for one of the update checker filters.
|
334 |
-
*
|
335 |
-
* Identical to add_filter(), except it automatically adds the "puc_" prefix
|
336 |
-
* and the "-$slug" suffix to the filter name. For example, "request_info_result"
|
337 |
-
* becomes "puc_request_info_result-your_plugin_slug".
|
338 |
-
*
|
339 |
-
* @param string $tag
|
340 |
-
* @param callable $callback
|
341 |
-
* @param int $priority
|
342 |
-
* @param int $acceptedArgs
|
343 |
-
*/
|
344 |
-
public function addFilter($tag, $callback, $priority = 10, $acceptedArgs = 1) {
|
345 |
-
add_filter($this->getUniqueName($tag), $callback, $priority, $acceptedArgs);
|
346 |
-
}
|
347 |
-
|
348 |
-
/* -------------------------------------------------------------------
|
349 |
-
* Inject updates
|
350 |
-
* -------------------------------------------------------------------
|
351 |
-
*/
|
352 |
-
|
353 |
-
/**
|
354 |
-
* Insert the latest update (if any) into the update list maintained by WP.
|
355 |
-
*
|
356 |
-
* @param stdClass $updates Update list.
|
357 |
-
* @return stdClass Modified update list.
|
358 |
-
*/
|
359 |
-
public function injectUpdate($updates) {
|
360 |
-
//Is there an update to insert?
|
361 |
-
$update = $this->getUpdate();
|
362 |
-
|
363 |
-
if ( !$this->shouldShowUpdates() ) {
|
364 |
-
$update = null;
|
365 |
-
}
|
366 |
-
|
367 |
-
if ( !empty($update) ) {
|
368 |
-
//Let plugins filter the update info before it's passed on to WordPress.
|
369 |
-
$update = apply_filters($this->getUniqueName('pre_inject_update'), $update);
|
370 |
-
$updates = $this->addUpdateToList($updates, $update->toWpFormat());
|
371 |
-
} else {
|
372 |
-
//Clean up any stale update info.
|
373 |
-
$updates = $this->removeUpdateFromList($updates);
|
374 |
-
}
|
375 |
-
|
376 |
-
return $updates;
|
377 |
-
}
|
378 |
-
|
379 |
-
/**
|
380 |
-
* @param stdClass|null $updates
|
381 |
-
* @param stdClass|array $updateToAdd
|
382 |
-
* @return stdClass
|
383 |
-
*/
|
384 |
-
protected function addUpdateToList($updates, $updateToAdd) {
|
385 |
-
if ( !is_object($updates) ) {
|
386 |
-
$updates = new stdClass();
|
387 |
-
$updates->response = array();
|
388 |
-
}
|
389 |
-
|
390 |
-
$updates->response[$this->getUpdateListKey()] = $updateToAdd;
|
391 |
-
return $updates;
|
392 |
-
}
|
393 |
-
|
394 |
-
/**
|
395 |
-
* @param stdClass|null $updates
|
396 |
-
* @return stdClass|null
|
397 |
-
*/
|
398 |
-
protected function removeUpdateFromList($updates) {
|
399 |
-
if ( isset($updates, $updates->response) ) {
|
400 |
-
unset($updates->response[$this->getUpdateListKey()]);
|
401 |
-
}
|
402 |
-
return $updates;
|
403 |
-
}
|
404 |
-
|
405 |
-
/**
|
406 |
-
* Get the key that will be used when adding updates to the update list that's maintained
|
407 |
-
* by the WordPress core. The list is always an associative array, but the key is different
|
408 |
-
* for plugins and themes.
|
409 |
-
*
|
410 |
-
* @return string
|
411 |
-
*/
|
412 |
-
abstract protected function getUpdateListKey();
|
413 |
-
|
414 |
-
/**
|
415 |
-
* Should we show available updates?
|
416 |
-
*
|
417 |
-
* Usually the answer is "yes", but there are exceptions. For example, WordPress doesn't
|
418 |
-
* support automatic updates installation for mu-plugins, so PUC usually won't show update
|
419 |
-
* notifications in that case. See the plugin-specific subclass for details.
|
420 |
-
*
|
421 |
-
* Note: This method only applies to updates that are displayed (or not) in the WordPress
|
422 |
-
* admin. It doesn't affect APIs like requestUpdate and getUpdate.
|
423 |
-
*
|
424 |
-
* @return bool
|
425 |
-
*/
|
426 |
-
protected function shouldShowUpdates() {
|
427 |
-
return true;
|
428 |
-
}
|
429 |
-
|
430 |
-
/* -------------------------------------------------------------------
|
431 |
-
* JSON-based update API
|
432 |
-
* -------------------------------------------------------------------
|
433 |
-
*/
|
434 |
-
|
435 |
-
/**
|
436 |
-
* Retrieve plugin or theme metadata from the JSON document at $this->metadataUrl.
|
437 |
-
*
|
438 |
-
* @param string $metaClass Parse the JSON as an instance of this class. It must have a static fromJson method.
|
439 |
-
* @param string $filterRoot
|
440 |
-
* @param array $queryArgs Additional query arguments.
|
441 |
-
* @return array [Puc_v4_Metadata|null, array|WP_Error] A metadata instance and the value returned by wp_remote_get().
|
442 |
-
*/
|
443 |
-
protected function requestMetadata($metaClass, $filterRoot, $queryArgs = array()) {
|
444 |
-
//Query args to append to the URL. Plugins can add their own by using a filter callback (see addQueryArgFilter()).
|
445 |
-
$installedVersion = $this->getInstalledVersion();
|
446 |
-
$queryArgs['installed_version'] = ($installedVersion !== null) ? $installedVersion : '';
|
447 |
-
$queryArgs = apply_filters($this->getUniqueName($filterRoot . '_query_args'), $queryArgs);
|
448 |
-
|
449 |
-
//Various options for the wp_remote_get() call. Plugins can filter these, too.
|
450 |
-
$options = array(
|
451 |
-
'timeout' => 10, //seconds
|
452 |
-
'headers' => array(
|
453 |
-
'Accept' => 'application/json',
|
454 |
-
),
|
455 |
-
);
|
456 |
-
$options = apply_filters($this->getUniqueName($filterRoot . '_options'), $options);
|
457 |
-
|
458 |
-
//The metadata file should be at 'http://your-api.com/url/here/$slug/info.json'
|
459 |
-
$url = $this->metadataUrl;
|
460 |
-
if ( !empty($queryArgs) ){
|
461 |
-
$url = add_query_arg($queryArgs, $url);
|
462 |
-
}
|
463 |
-
|
464 |
-
$result = wp_remote_get($url, $options);
|
465 |
-
|
466 |
-
//Try to parse the response
|
467 |
-
$status = $this->validateApiResponse($result);
|
468 |
-
$metadata = null;
|
469 |
-
if ( !is_wp_error($status) ){
|
470 |
-
$metadata = call_user_func(array($metaClass, 'fromJson'), $result['body']);
|
471 |
-
} else {
|
472 |
-
$this->triggerError(
|
473 |
-
sprintf('The URL %s does not point to a valid metadata file. ', $url)
|
474 |
-
. $status->get_error_message(),
|
475 |
-
E_USER_WARNING
|
476 |
-
);
|
477 |
-
}
|
478 |
-
|
479 |
-
return array($metadata, $result);
|
480 |
-
}
|
481 |
-
|
482 |
-
/**
|
483 |
-
* Check if $result is a successful update API response.
|
484 |
-
*
|
485 |
-
* @param array|WP_Error $result
|
486 |
-
* @return true|WP_Error
|
487 |
-
*/
|
488 |
-
protected function validateApiResponse($result) {
|
489 |
-
if ( is_wp_error($result) ) { /** @var WP_Error $result */
|
490 |
-
return new WP_Error($result->get_error_code(), 'WP HTTP Error: ' . $result->get_error_message());
|
491 |
-
}
|
492 |
-
|
493 |
-
if ( !isset($result['response']['code']) ) {
|
494 |
-
return new WP_Error(
|
495 |
-
'puc_no_response_code',
|
496 |
-
'wp_remote_get() returned an unexpected result.'
|
497 |
-
);
|
498 |
-
}
|
499 |
-
|
500 |
-
if ( $result['response']['code'] !== 200 ) {
|
501 |
-
return new WP_Error(
|
502 |
-
'puc_unexpected_response_code',
|
503 |
-
'HTTP response code is ' . $result['response']['code'] . ' (expected: 200)'
|
504 |
-
);
|
505 |
-
}
|
506 |
-
|
507 |
-
if ( empty($result['body']) ) {
|
508 |
-
return new WP_Error('puc_empty_response', 'The metadata file appears to be empty.');
|
509 |
-
}
|
510 |
-
|
511 |
-
return true;
|
512 |
-
}
|
513 |
-
|
514 |
-
/* -------------------------------------------------------------------
|
515 |
-
* Language packs / Translation updates
|
516 |
-
* -------------------------------------------------------------------
|
517 |
-
*/
|
518 |
-
|
519 |
-
/**
|
520 |
-
* Filter a list of translation updates and return a new list that contains only updates
|
521 |
-
* that apply to the current site.
|
522 |
-
*
|
523 |
-
* @param array $translations
|
524 |
-
* @return array
|
525 |
-
*/
|
526 |
-
protected function filterApplicableTranslations($translations) {
|
527 |
-
$languages = array_flip(array_values(get_available_languages()));
|
528 |
-
$installedTranslations = $this->getInstalledTranslations();
|
529 |
-
|
530 |
-
$applicableTranslations = array();
|
531 |
-
foreach($translations as $translation) {
|
532 |
-
//Does it match one of the available core languages?
|
533 |
-
$isApplicable = array_key_exists($translation->language, $languages);
|
534 |
-
//Is it more recent than an already-installed translation?
|
535 |
-
if ( isset($installedTranslations[$translation->language]) ) {
|
536 |
-
$updateTimestamp = strtotime($translation->updated);
|
537 |
-
$installedTimestamp = strtotime($installedTranslations[$translation->language]['PO-Revision-Date']);
|
538 |
-
$isApplicable = $updateTimestamp > $installedTimestamp;
|
539 |
-
}
|
540 |
-
|
541 |
-
if ( $isApplicable ) {
|
542 |
-
$applicableTranslations[] = $translation;
|
543 |
-
}
|
544 |
-
}
|
545 |
-
|
546 |
-
return $applicableTranslations;
|
547 |
-
}
|
548 |
-
|
549 |
-
/**
|
550 |
-
* Get a list of installed translations for this plugin or theme.
|
551 |
-
*
|
552 |
-
* @return array
|
553 |
-
*/
|
554 |
-
protected function getInstalledTranslations() {
|
555 |
-
$installedTranslations = wp_get_installed_translations($this->translationType . 's');
|
556 |
-
if ( isset($installedTranslations[$this->directoryName]) ) {
|
557 |
-
$installedTranslations = $installedTranslations[$this->directoryName];
|
558 |
-
} else {
|
559 |
-
$installedTranslations = array();
|
560 |
-
}
|
561 |
-
return $installedTranslations;
|
562 |
-
}
|
563 |
-
|
564 |
-
/**
|
565 |
-
* Insert translation updates into the list maintained by WordPress.
|
566 |
-
*
|
567 |
-
* @param stdClass $updates
|
568 |
-
* @return stdClass
|
569 |
-
*/
|
570 |
-
public function injectTranslationUpdates($updates) {
|
571 |
-
$translationUpdates = $this->getTranslationUpdates();
|
572 |
-
if ( empty($translationUpdates) ) {
|
573 |
-
return $updates;
|
574 |
-
}
|
575 |
-
|
576 |
-
//Being defensive.
|
577 |
-
if ( !is_object($updates) ) {
|
578 |
-
$updates = new stdClass();
|
579 |
-
}
|
580 |
-
if ( !isset($updates->translations) ) {
|
581 |
-
$updates->translations = array();
|
582 |
-
}
|
583 |
-
|
584 |
-
//In case there's a name collision with a plugin or theme hosted on wordpress.org,
|
585 |
-
//remove any preexisting updates that match our thing.
|
586 |
-
$updates->translations = array_values(array_filter(
|
587 |
-
$updates->translations,
|
588 |
-
array($this, 'isNotMyTranslation')
|
589 |
-
));
|
590 |
-
|
591 |
-
//Add our updates to the list.
|
592 |
-
foreach($translationUpdates as $update) {
|
593 |
-
$convertedUpdate = array_merge(
|
594 |
-
array(
|
595 |
-
'type' => $this->translationType,
|
596 |
-
'slug' => $this->directoryName,
|
597 |
-
'autoupdate' => 0,
|
598 |
-
//AFAICT, WordPress doesn't actually use the "version" field for anything.
|
599 |
-
//But lets make sure it's there, just in case.
|
600 |
-
'version' => isset($update->version) ? $update->version : ('1.' . strtotime($update->updated)),
|
601 |
-
),
|
602 |
-
(array)$update
|
603 |
-
);
|
604 |
-
|
605 |
-
$updates->translations[] = $convertedUpdate;
|
606 |
-
}
|
607 |
-
|
608 |
-
return $updates;
|
609 |
-
}
|
610 |
-
|
611 |
-
/**
|
612 |
-
* Get a list of available translation updates.
|
613 |
-
*
|
614 |
-
* This method will return an empty array if there are no updates.
|
615 |
-
* Uses cached update data.
|
616 |
-
*
|
617 |
-
* @return array
|
618 |
-
*/
|
619 |
-
public function getTranslationUpdates() {
|
620 |
-
return $this->updateState->getTranslations();
|
621 |
-
}
|
622 |
-
|
623 |
-
/**
|
624 |
-
* Remove all cached translation updates.
|
625 |
-
*
|
626 |
-
* @see wp_clean_update_cache
|
627 |
-
*/
|
628 |
-
public function clearCachedTranslationUpdates() {
|
629 |
-
$this->updateState->setTranslations(array());
|
630 |
-
}
|
631 |
-
|
632 |
-
/**
|
633 |
-
* Filter callback. Keeps only translations that *don't* match this plugin or theme.
|
634 |
-
*
|
635 |
-
* @param array $translation
|
636 |
-
* @return bool
|
637 |
-
*/
|
638 |
-
protected function isNotMyTranslation($translation) {
|
639 |
-
$isMatch = isset($translation['type'], $translation['slug'])
|
640 |
-
&& ($translation['type'] === $this->translationType)
|
641 |
-
&& ($translation['slug'] === $this->directoryName);
|
642 |
-
|
643 |
-
return !$isMatch;
|
644 |
-
}
|
645 |
-
|
646 |
-
/* -------------------------------------------------------------------
|
647 |
-
* Fix directory name when installing updates
|
648 |
-
* -------------------------------------------------------------------
|
649 |
-
*/
|
650 |
-
|
651 |
-
/**
|
652 |
-
* Rename the update directory to match the existing plugin/theme directory.
|
653 |
-
*
|
654 |
-
* When WordPress installs a plugin or theme update, it assumes that the ZIP file will contain
|
655 |
-
* exactly one directory, and that the directory name will be the same as the directory where
|
656 |
-
* the plugin or theme is currently installed.
|
657 |
-
*
|
658 |
-
* GitHub and other repositories provide ZIP downloads, but they often use directory names like
|
659 |
-
* "project-branch" or "project-tag-hash". We need to change the name to the actual plugin folder.
|
660 |
-
*
|
661 |
-
* This is a hook callback. Don't call it from a plugin.
|
662 |
-
*
|
663 |
-
* @access protected
|
664 |
-
*
|
665 |
-
* @param string $source The directory to copy to /wp-content/plugins or /wp-content/themes. Usually a subdirectory of $remoteSource.
|
666 |
-
* @param string $remoteSource WordPress has extracted the update to this directory.
|
667 |
-
* @param WP_Upgrader $upgrader
|
668 |
-
* @return string|WP_Error
|
669 |
-
*/
|
670 |
-
public function fixDirectoryName($source, $remoteSource, $upgrader) {
|
671 |
-
global $wp_filesystem;
|
672 |
-
/** @var WP_Filesystem_Base $wp_filesystem */
|
673 |
-
|
674 |
-
//Basic sanity checks.
|
675 |
-
if ( !isset($source, $remoteSource, $upgrader, $upgrader->skin, $wp_filesystem) ) {
|
676 |
-
return $source;
|
677 |
-
}
|
678 |
-
|
679 |
-
//If WordPress is upgrading anything other than our plugin/theme, leave the directory name unchanged.
|
680 |
-
if ( !$this->isBeingUpgraded($upgrader) ) {
|
681 |
-
return $source;
|
682 |
-
}
|
683 |
-
|
684 |
-
//Rename the source to match the existing directory.
|
685 |
-
$correctedSource = trailingslashit($remoteSource) . $this->directoryName . '/';
|
686 |
-
if ( $source !== $correctedSource ) {
|
687 |
-
//The update archive should contain a single directory that contains the rest of plugin/theme files.
|
688 |
-
//Otherwise, WordPress will try to copy the entire working directory ($source == $remoteSource).
|
689 |
-
//We can't rename $remoteSource because that would break WordPress code that cleans up temporary files
|
690 |
-
//after update.
|
691 |
-
if ( $this->isBadDirectoryStructure($remoteSource) ) {
|
692 |
-
return new WP_Error(
|
693 |
-
'puc-incorrect-directory-structure',
|
694 |
-
sprintf(
|
695 |
-
'The directory structure of the update is incorrect. All files should be inside ' .
|
696 |
-
'a directory named <span class="code">%s</span>, not at the root of the ZIP archive.',
|
697 |
-
htmlentities($this->slug)
|
698 |
-
)
|
699 |
-
);
|
700 |
-
}
|
701 |
-
|
702 |
-
/** @var WP_Upgrader_Skin $upgrader ->skin */
|
703 |
-
$upgrader->skin->feedback(sprintf(
|
704 |
-
'Renaming %s to %s…',
|
705 |
-
'<span class="code">' . basename($source) . '</span>',
|
706 |
-
'<span class="code">' . $this->directoryName . '</span>'
|
707 |
-
));
|
708 |
-
|
709 |
-
if ( $wp_filesystem->move($source, $correctedSource, true) ) {
|
710 |
-
$upgrader->skin->feedback('Directory successfully renamed.');
|
711 |
-
return $correctedSource;
|
712 |
-
} else {
|
713 |
-
return new WP_Error(
|
714 |
-
'puc-rename-failed',
|
715 |
-
'Unable to rename the update to match the existing directory.'
|
716 |
-
);
|
717 |
-
}
|
718 |
-
}
|
719 |
-
|
720 |
-
return $source;
|
721 |
-
}
|
722 |
-
|
723 |
-
/**
|
724 |
-
* Is there an update being installed right now, for this plugin or theme?
|
725 |
-
*
|
726 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
727 |
-
* @return bool
|
728 |
-
*/
|
729 |
-
abstract public function isBeingUpgraded($upgrader = null);
|
730 |
-
|
731 |
-
/**
|
732 |
-
* Check for incorrect update directory structure. An update must contain a single directory,
|
733 |
-
* all other files should be inside that directory.
|
734 |
-
*
|
735 |
-
* @param string $remoteSource Directory path.
|
736 |
-
* @return bool
|
737 |
-
*/
|
738 |
-
protected function isBadDirectoryStructure($remoteSource) {
|
739 |
-
global $wp_filesystem;
|
740 |
-
/** @var WP_Filesystem_Base $wp_filesystem */
|
741 |
-
|
742 |
-
$sourceFiles = $wp_filesystem->dirlist($remoteSource);
|
743 |
-
if ( is_array($sourceFiles) ) {
|
744 |
-
$sourceFiles = array_keys($sourceFiles);
|
745 |
-
$firstFilePath = trailingslashit($remoteSource) . $sourceFiles[0];
|
746 |
-
return (count($sourceFiles) > 1) || (!$wp_filesystem->is_dir($firstFilePath));
|
747 |
-
}
|
748 |
-
|
749 |
-
//Assume it's fine.
|
750 |
-
return false;
|
751 |
-
}
|
752 |
-
|
753 |
-
/* -------------------------------------------------------------------
|
754 |
-
* File header parsing
|
755 |
-
* -------------------------------------------------------------------
|
756 |
-
*/
|
757 |
-
|
758 |
-
/**
|
759 |
-
* Parse plugin or theme metadata from the header comment.
|
760 |
-
*
|
761 |
-
* This is basically a simplified version of the get_file_data() function from /wp-includes/functions.php.
|
762 |
-
* It's intended as a utility for subclasses that detect updates by parsing files in a VCS.
|
763 |
-
*
|
764 |
-
* @param string|null $content File contents.
|
765 |
-
* @return string[]
|
766 |
-
*/
|
767 |
-
public function getFileHeader($content) {
|
768 |
-
$content = (string) $content;
|
769 |
-
|
770 |
-
//WordPress only looks at the first 8 KiB of the file, so we do the same.
|
771 |
-
$content = substr($content, 0, 8192);
|
772 |
-
//Normalize line endings.
|
773 |
-
$content = str_replace("\r", "\n", $content);
|
774 |
-
|
775 |
-
$headers = $this->getHeaderNames();
|
776 |
-
$results = array();
|
777 |
-
foreach ($headers as $field => $name) {
|
778 |
-
$success = preg_match('/^[ \t\/*#@]*' . preg_quote($name, '/') . ':(.*)$/mi', $content, $matches);
|
779 |
-
|
780 |
-
if ( ($success === 1) && $matches[1] ) {
|
781 |
-
$value = $matches[1];
|
782 |
-
if ( function_exists('_cleanup_header_comment') ) {
|
783 |
-
$value = _cleanup_header_comment($value);
|
784 |
-
}
|
785 |
-
$results[$field] = $value;
|
786 |
-
} else {
|
787 |
-
$results[$field] = '';
|
788 |
-
}
|
789 |
-
}
|
790 |
-
|
791 |
-
return $results;
|
792 |
-
}
|
793 |
-
|
794 |
-
/**
|
795 |
-
* @return array Format: ['HeaderKey' => 'Header Name']
|
796 |
-
*/
|
797 |
-
abstract protected function getHeaderNames();
|
798 |
-
|
799 |
-
/* -------------------------------------------------------------------
|
800 |
-
* DebugBar integration
|
801 |
-
* -------------------------------------------------------------------
|
802 |
-
*/
|
803 |
-
|
804 |
-
/**
|
805 |
-
* Initialize the update checker Debug Bar plugin/add-on thingy.
|
806 |
-
*/
|
807 |
-
public function maybeInitDebugBar() {
|
808 |
-
if ( class_exists('Debug_Bar', false) && file_exists(dirname(__FILE__ . '/DebugBar')) ) {
|
809 |
-
$this->createDebugBarExtension();
|
810 |
-
}
|
811 |
-
}
|
812 |
-
|
813 |
-
protected function createDebugBarExtension() {
|
814 |
-
return new Puc_v4_DebugBar_Extension($this);
|
815 |
-
}
|
816 |
-
|
817 |
-
/**
|
818 |
-
* Display additional configuration details in the Debug Bar panel.
|
819 |
-
*
|
820 |
-
* @param Puc_v4_DebugBar_Panel $panel
|
821 |
-
*/
|
822 |
-
public function onDisplayConfiguration($panel) {
|
823 |
-
//Do nothing. Subclasses can use this to add additional info to the panel.
|
824 |
-
}
|
825 |
-
|
826 |
-
}
|
827 |
-
|
828 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/UpgraderStatus.php
DELETED
@@ -1,199 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_UpgraderStatus', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* A utility class that helps figure out which plugin or theme WordPress is upgrading.
|
6 |
-
*
|
7 |
-
* It may seem strange to have a separate class just for that, but the task is surprisingly complicated.
|
8 |
-
* Core classes like Plugin_Upgrader don't expose the plugin file name during an in-progress update (AFAICT).
|
9 |
-
* This class uses a few workarounds and heuristics to get the file name.
|
10 |
-
*/
|
11 |
-
class Puc_v4_UpgraderStatus {
|
12 |
-
private $currentType = null; //"plugin" or "theme".
|
13 |
-
private $currentId = null; //Plugin basename or theme directory name.
|
14 |
-
|
15 |
-
public function __construct() {
|
16 |
-
//Keep track of which plugin/theme WordPress is currently upgrading.
|
17 |
-
add_filter('upgrader_pre_install', array($this, 'setUpgradedThing'), 10, 2);
|
18 |
-
add_filter('upgrader_package_options', array($this, 'setUpgradedPluginFromOptions'), 10, 1);
|
19 |
-
add_filter('upgrader_post_install', array($this, 'clearUpgradedThing'), 10, 1);
|
20 |
-
add_action('upgrader_process_complete', array($this, 'clearUpgradedThing'), 10, 1);
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Is there and update being installed RIGHT NOW, for a specific plugin?
|
25 |
-
*
|
26 |
-
* Caution: This method is unreliable. WordPress doesn't make it easy to figure out what it is upgrading,
|
27 |
-
* and upgrader implementations are liable to change without notice.
|
28 |
-
*
|
29 |
-
* @param string $pluginFile The plugin to check.
|
30 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
31 |
-
* @return bool True if the plugin identified by $pluginFile is being upgraded.
|
32 |
-
*/
|
33 |
-
public function isPluginBeingUpgraded($pluginFile, $upgrader = null) {
|
34 |
-
return $this->isBeingUpgraded('plugin', $pluginFile, $upgrader);
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Is there an update being installed for a specific theme?
|
39 |
-
*
|
40 |
-
* @param string $stylesheet Theme directory name.
|
41 |
-
* @param WP_Upgrader|null $upgrader The upgrader that's performing the current update.
|
42 |
-
* @return bool
|
43 |
-
*/
|
44 |
-
public function isThemeBeingUpgraded($stylesheet, $upgrader = null) {
|
45 |
-
return $this->isBeingUpgraded('theme', $stylesheet, $upgrader);
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Check if a specific theme or plugin is being upgraded.
|
50 |
-
*
|
51 |
-
* @param string $type
|
52 |
-
* @param string $id
|
53 |
-
* @param Plugin_Upgrader|WP_Upgrader|null $upgrader
|
54 |
-
* @return bool
|
55 |
-
*/
|
56 |
-
protected function isBeingUpgraded($type, $id, $upgrader = null) {
|
57 |
-
if ( isset($upgrader) ) {
|
58 |
-
list($currentType, $currentId) = $this->getThingBeingUpgradedBy($upgrader);
|
59 |
-
if ( $currentType !== null ) {
|
60 |
-
$this->currentType = $currentType;
|
61 |
-
$this->currentId = $currentId;
|
62 |
-
}
|
63 |
-
}
|
64 |
-
return ($this->currentType === $type) && ($this->currentId === $id);
|
65 |
-
}
|
66 |
-
|
67 |
-
/**
|
68 |
-
* Figure out which theme or plugin is being upgraded by a WP_Upgrader instance.
|
69 |
-
*
|
70 |
-
* Returns an array with two items. The first item is the type of the thing that's being
|
71 |
-
* upgraded: "plugin" or "theme". The second item is either the plugin basename or
|
72 |
-
* the theme directory name. If we can't determine what the upgrader is doing, both items
|
73 |
-
* will be NULL.
|
74 |
-
*
|
75 |
-
* Examples:
|
76 |
-
* ['plugin', 'plugin-dir-name/plugin.php']
|
77 |
-
* ['theme', 'theme-dir-name']
|
78 |
-
*
|
79 |
-
* @param Plugin_Upgrader|WP_Upgrader $upgrader
|
80 |
-
* @return array
|
81 |
-
*/
|
82 |
-
private function getThingBeingUpgradedBy($upgrader) {
|
83 |
-
if ( !isset($upgrader, $upgrader->skin) ) {
|
84 |
-
return array(null, null);
|
85 |
-
}
|
86 |
-
|
87 |
-
//Figure out which plugin or theme is being upgraded.
|
88 |
-
$pluginFile = null;
|
89 |
-
$themeDirectoryName = null;
|
90 |
-
|
91 |
-
$skin = $upgrader->skin;
|
92 |
-
if ( isset($skin->theme_info) && ($skin->theme_info instanceof WP_Theme) ) {
|
93 |
-
$themeDirectoryName = $skin->theme_info->get_stylesheet();
|
94 |
-
} elseif ( $skin instanceof Plugin_Upgrader_Skin ) {
|
95 |
-
if ( isset($skin->plugin) && is_string($skin->plugin) && ($skin->plugin !== '') ) {
|
96 |
-
$pluginFile = $skin->plugin;
|
97 |
-
}
|
98 |
-
} elseif ( $skin instanceof Theme_Upgrader_Skin ) {
|
99 |
-
if ( isset($skin->theme) && is_string($skin->theme) && ($skin->theme !== '') ) {
|
100 |
-
$themeDirectoryName = $skin->theme;
|
101 |
-
}
|
102 |
-
} elseif ( isset($skin->plugin_info) && is_array($skin->plugin_info) ) {
|
103 |
-
//This case is tricky because Bulk_Plugin_Upgrader_Skin (etc) doesn't actually store the plugin
|
104 |
-
//filename anywhere. Instead, it has the plugin headers in $plugin_info. So the best we can
|
105 |
-
//do is compare those headers to the headers of installed plugins.
|
106 |
-
$pluginFile = $this->identifyPluginByHeaders($skin->plugin_info);
|
107 |
-
}
|
108 |
-
|
109 |
-
if ( $pluginFile !== null ) {
|
110 |
-
return array('plugin', $pluginFile);
|
111 |
-
} elseif ( $themeDirectoryName !== null ) {
|
112 |
-
return array('theme', $themeDirectoryName);
|
113 |
-
}
|
114 |
-
return array(null, null);
|
115 |
-
}
|
116 |
-
|
117 |
-
/**
|
118 |
-
* Identify an installed plugin based on its headers.
|
119 |
-
*
|
120 |
-
* @param array $searchHeaders The plugin file header to look for.
|
121 |
-
* @return string|null Plugin basename ("foo/bar.php"), or NULL if we can't identify the plugin.
|
122 |
-
*/
|
123 |
-
private function identifyPluginByHeaders($searchHeaders) {
|
124 |
-
if ( !function_exists('get_plugins') ){
|
125 |
-
/** @noinspection PhpIncludeInspection */
|
126 |
-
require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
|
127 |
-
}
|
128 |
-
|
129 |
-
$installedPlugins = get_plugins();
|
130 |
-
$matches = array();
|
131 |
-
foreach($installedPlugins as $pluginBasename => $headers) {
|
132 |
-
$diff1 = array_diff_assoc($headers, $searchHeaders);
|
133 |
-
$diff2 = array_diff_assoc($searchHeaders, $headers);
|
134 |
-
if ( empty($diff1) && empty($diff2) ) {
|
135 |
-
$matches[] = $pluginBasename;
|
136 |
-
}
|
137 |
-
}
|
138 |
-
|
139 |
-
//It's possible (though very unlikely) that there could be two plugins with identical
|
140 |
-
//headers. In that case, we can't unambiguously identify the plugin that's being upgraded.
|
141 |
-
if ( count($matches) !== 1 ) {
|
142 |
-
return null;
|
143 |
-
}
|
144 |
-
|
145 |
-
return reset($matches);
|
146 |
-
}
|
147 |
-
|
148 |
-
/**
|
149 |
-
* @access private
|
150 |
-
*
|
151 |
-
* @param mixed $input
|
152 |
-
* @param array $hookExtra
|
153 |
-
* @return mixed Returns $input unaltered.
|
154 |
-
*/
|
155 |
-
public function setUpgradedThing($input, $hookExtra) {
|
156 |
-
if ( !empty($hookExtra['plugin']) && is_string($hookExtra['plugin']) ) {
|
157 |
-
$this->currentId = $hookExtra['plugin'];
|
158 |
-
$this->currentType = 'plugin';
|
159 |
-
} elseif ( !empty($hookExtra['theme']) && is_string($hookExtra['theme']) ) {
|
160 |
-
$this->currentId = $hookExtra['theme'];
|
161 |
-
$this->currentType = 'theme';
|
162 |
-
} else {
|
163 |
-
$this->currentType = null;
|
164 |
-
$this->currentId = null;
|
165 |
-
}
|
166 |
-
return $input;
|
167 |
-
}
|
168 |
-
|
169 |
-
/**
|
170 |
-
* @access private
|
171 |
-
*
|
172 |
-
* @param array $options
|
173 |
-
* @return array
|
174 |
-
*/
|
175 |
-
public function setUpgradedPluginFromOptions($options) {
|
176 |
-
if ( isset($options['hook_extra']['plugin']) && is_string($options['hook_extra']['plugin']) ) {
|
177 |
-
$this->currentType = 'plugin';
|
178 |
-
$this->currentId = $options['hook_extra']['plugin'];
|
179 |
-
} else {
|
180 |
-
$this->currentType = null;
|
181 |
-
$this->currentId = null;
|
182 |
-
}
|
183 |
-
return $options;
|
184 |
-
}
|
185 |
-
|
186 |
-
/**
|
187 |
-
* @access private
|
188 |
-
*
|
189 |
-
* @param mixed $input
|
190 |
-
* @return mixed Returns $input unaltered.
|
191 |
-
*/
|
192 |
-
public function clearUpgradedThing($input = null) {
|
193 |
-
$this->currentId = null;
|
194 |
-
$this->currentType = null;
|
195 |
-
return $input;
|
196 |
-
}
|
197 |
-
}
|
198 |
-
|
199 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Utils.php
DELETED
@@ -1,77 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_Utils', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_Utils {
|
6 |
-
/**
|
7 |
-
* Get a value from a nested array or object based on a path.
|
8 |
-
*
|
9 |
-
* @param array|object|null $collection Get an entry from this array.
|
10 |
-
* @param array|string $path A list of array keys in hierarchy order, or a string path like "foo.bar.baz".
|
11 |
-
* @param mixed $default The value to return if the specified path is not found.
|
12 |
-
* @param string $separator Path element separator. Only applies to string paths.
|
13 |
-
* @return mixed
|
14 |
-
*/
|
15 |
-
public static function get($collection, $path, $default = null, $separator = '.') {
|
16 |
-
if ( is_string($path) ) {
|
17 |
-
$path = explode($separator, $path);
|
18 |
-
}
|
19 |
-
if ( empty($path) ) {
|
20 |
-
return $default;
|
21 |
-
}
|
22 |
-
|
23 |
-
//Follow the $path into $input as far as possible.
|
24 |
-
$currentValue = $collection;
|
25 |
-
$pathExists = true;
|
26 |
-
foreach ($path as $node) {
|
27 |
-
if ( is_array($currentValue) && isset($currentValue[$node]) ) {
|
28 |
-
$currentValue = $currentValue[$node];
|
29 |
-
} else if ( is_object($currentValue) && isset($currentValue->$node) ) {
|
30 |
-
$currentValue = $currentValue->$node;
|
31 |
-
} else {
|
32 |
-
$pathExists = false;
|
33 |
-
break;
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
if ( $pathExists ) {
|
38 |
-
return $currentValue;
|
39 |
-
}
|
40 |
-
return $default;
|
41 |
-
}
|
42 |
-
|
43 |
-
/**
|
44 |
-
* Get the first array element that is not empty.
|
45 |
-
*
|
46 |
-
* @param array $values
|
47 |
-
* @param mixed|null $default Returns this value if there are no non-empty elements.
|
48 |
-
* @return mixed|null
|
49 |
-
*/
|
50 |
-
public static function findNotEmpty($values, $default = null) {
|
51 |
-
if ( empty($values) ) {
|
52 |
-
return $default;
|
53 |
-
}
|
54 |
-
|
55 |
-
foreach ($values as $value) {
|
56 |
-
if ( !empty($value) ) {
|
57 |
-
return $value;
|
58 |
-
}
|
59 |
-
}
|
60 |
-
|
61 |
-
return $default;
|
62 |
-
}
|
63 |
-
|
64 |
-
/**
|
65 |
-
* Check if the input string starts with the specified prefix.
|
66 |
-
*
|
67 |
-
* @param string $input
|
68 |
-
* @param string $prefix
|
69 |
-
* @return bool
|
70 |
-
*/
|
71 |
-
public static function startsWith($input, $prefix) {
|
72 |
-
$length = strlen($prefix);
|
73 |
-
return (substr($input, 0, $length) === $prefix);
|
74 |
-
}
|
75 |
-
}
|
76 |
-
|
77 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/Api.php
DELETED
@@ -1,243 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Vcs_Api') ):
|
3 |
-
|
4 |
-
abstract class Puc_v4_Vcs_Api {
|
5 |
-
protected $tagNameProperty = 'name';
|
6 |
-
|
7 |
-
/**
|
8 |
-
* @var string
|
9 |
-
*/
|
10 |
-
protected $repositoryUrl = '';
|
11 |
-
|
12 |
-
/**
|
13 |
-
* @var mixed Authentication details for private repositories. Format depends on service.
|
14 |
-
*/
|
15 |
-
protected $credentials = null;
|
16 |
-
|
17 |
-
/**
|
18 |
-
* @var string The filter tag that's used to filter options passed to wp_remote_get.
|
19 |
-
* For example, "puc_request_info_options-slug" or "puc_request_update_options_theme-slug".
|
20 |
-
*/
|
21 |
-
protected $httpFilterName = '';
|
22 |
-
|
23 |
-
/**
|
24 |
-
* Puc_v4_Vcs_Api constructor.
|
25 |
-
*
|
26 |
-
* @param string $repositoryUrl
|
27 |
-
* @param array|string|null $credentials
|
28 |
-
*/
|
29 |
-
public function __construct($repositoryUrl, $credentials = null) {
|
30 |
-
$this->repositoryUrl = $repositoryUrl;
|
31 |
-
$this->setAuthentication($credentials);
|
32 |
-
}
|
33 |
-
|
34 |
-
/**
|
35 |
-
* @return string
|
36 |
-
*/
|
37 |
-
public function getRepositoryUrl() {
|
38 |
-
return $this->repositoryUrl;
|
39 |
-
}
|
40 |
-
|
41 |
-
/**
|
42 |
-
* Figure out which reference (i.e tag or branch) contains the latest version.
|
43 |
-
*
|
44 |
-
* @param string $configBranch Start looking in this branch.
|
45 |
-
* @return null|Puc_v4_Vcs_Reference
|
46 |
-
*/
|
47 |
-
abstract public function chooseReference($configBranch);
|
48 |
-
|
49 |
-
/**
|
50 |
-
* Get the readme.txt file from the remote repository and parse it
|
51 |
-
* according to the plugin readme standard.
|
52 |
-
*
|
53 |
-
* @param string $ref Tag or branch name.
|
54 |
-
* @return array Parsed readme.
|
55 |
-
*/
|
56 |
-
public function getRemoteReadme($ref = 'master') {
|
57 |
-
$fileContents = $this->getRemoteFile('readme.txt', $ref);
|
58 |
-
if ( empty($fileContents) ) {
|
59 |
-
return array();
|
60 |
-
}
|
61 |
-
|
62 |
-
$parser = new PucReadmeParser();
|
63 |
-
return $parser->parse_readme_contents($fileContents);
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Get a branch.
|
68 |
-
*
|
69 |
-
* @param string $branchName
|
70 |
-
* @return Puc_v4_Vcs_Reference|null
|
71 |
-
*/
|
72 |
-
abstract public function getBranch($branchName);
|
73 |
-
|
74 |
-
/**
|
75 |
-
* Get a specific tag.
|
76 |
-
*
|
77 |
-
* @param string $tagName
|
78 |
-
* @return Puc_v4_Vcs_Reference|null
|
79 |
-
*/
|
80 |
-
abstract public function getTag($tagName);
|
81 |
-
|
82 |
-
/**
|
83 |
-
* Get the tag that looks like the highest version number.
|
84 |
-
* (Implementations should skip pre-release versions if possible.)
|
85 |
-
*
|
86 |
-
* @return Puc_v4_Vcs_Reference|null
|
87 |
-
*/
|
88 |
-
abstract public function getLatestTag();
|
89 |
-
|
90 |
-
/**
|
91 |
-
* Check if a tag name string looks like a version number.
|
92 |
-
*
|
93 |
-
* @param string $name
|
94 |
-
* @return bool
|
95 |
-
*/
|
96 |
-
protected function looksLikeVersion($name) {
|
97 |
-
//Tag names may be prefixed with "v", e.g. "v1.2.3".
|
98 |
-
$name = ltrim($name, 'v');
|
99 |
-
|
100 |
-
//The version string must start with a number.
|
101 |
-
if ( !is_numeric(substr($name, 0, 1)) ) {
|
102 |
-
return false;
|
103 |
-
}
|
104 |
-
|
105 |
-
//The goal is to accept any SemVer-compatible or "PHP-standardized" version number.
|
106 |
-
return (preg_match('@^(\d{1,5}?)(\.\d{1,10}?){0,4}?($|[abrdp+_\-]|\s)@i', $name) === 1);
|
107 |
-
}
|
108 |
-
|
109 |
-
/**
|
110 |
-
* Check if a tag appears to be named like a version number.
|
111 |
-
*
|
112 |
-
* @param stdClass $tag
|
113 |
-
* @return bool
|
114 |
-
*/
|
115 |
-
protected function isVersionTag($tag) {
|
116 |
-
$property = $this->tagNameProperty;
|
117 |
-
return isset($tag->$property) && $this->looksLikeVersion($tag->$property);
|
118 |
-
}
|
119 |
-
|
120 |
-
/**
|
121 |
-
* Sort a list of tags as if they were version numbers.
|
122 |
-
* Tags that don't look like version number will be removed.
|
123 |
-
*
|
124 |
-
* @param stdClass[] $tags Array of tag objects.
|
125 |
-
* @return stdClass[] Filtered array of tags sorted in descending order.
|
126 |
-
*/
|
127 |
-
protected function sortTagsByVersion($tags) {
|
128 |
-
//Keep only those tags that look like version numbers.
|
129 |
-
$versionTags = array_filter($tags, array($this, 'isVersionTag'));
|
130 |
-
//Sort them in descending order.
|
131 |
-
usort($versionTags, array($this, 'compareTagNames'));
|
132 |
-
|
133 |
-
return $versionTags;
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Compare two tags as if they were version number.
|
138 |
-
*
|
139 |
-
* @param stdClass $tag1 Tag object.
|
140 |
-
* @param stdClass $tag2 Another tag object.
|
141 |
-
* @return int
|
142 |
-
*/
|
143 |
-
protected function compareTagNames($tag1, $tag2) {
|
144 |
-
$property = $this->tagNameProperty;
|
145 |
-
if ( !isset($tag1->$property) ) {
|
146 |
-
return 1;
|
147 |
-
}
|
148 |
-
if ( !isset($tag2->$property) ) {
|
149 |
-
return -1;
|
150 |
-
}
|
151 |
-
return -version_compare(ltrim($tag1->$property, 'v'), ltrim($tag2->$property, 'v'));
|
152 |
-
}
|
153 |
-
|
154 |
-
/**
|
155 |
-
* Get the contents of a file from a specific branch or tag.
|
156 |
-
*
|
157 |
-
* @param string $path File name.
|
158 |
-
* @param string $ref
|
159 |
-
* @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
|
160 |
-
*/
|
161 |
-
abstract public function getRemoteFile($path, $ref = 'master');
|
162 |
-
|
163 |
-
/**
|
164 |
-
* Get the timestamp of the latest commit that changed the specified branch or tag.
|
165 |
-
*
|
166 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
167 |
-
* @return string|null
|
168 |
-
*/
|
169 |
-
abstract public function getLatestCommitTime($ref);
|
170 |
-
|
171 |
-
/**
|
172 |
-
* Get the contents of the changelog file from the repository.
|
173 |
-
*
|
174 |
-
* @param string $ref
|
175 |
-
* @param string $localDirectory Full path to the local plugin or theme directory.
|
176 |
-
* @return null|string The HTML contents of the changelog.
|
177 |
-
*/
|
178 |
-
public function getRemoteChangelog($ref, $localDirectory) {
|
179 |
-
$filename = $this->findChangelogName($localDirectory);
|
180 |
-
if ( empty($filename) ) {
|
181 |
-
return null;
|
182 |
-
}
|
183 |
-
|
184 |
-
$changelog = $this->getRemoteFile($filename, $ref);
|
185 |
-
if ( $changelog === null ) {
|
186 |
-
return null;
|
187 |
-
}
|
188 |
-
|
189 |
-
/** @noinspection PhpUndefinedClassInspection */
|
190 |
-
return Parsedown::instance()->text($changelog);
|
191 |
-
}
|
192 |
-
|
193 |
-
/**
|
194 |
-
* Guess the name of the changelog file.
|
195 |
-
*
|
196 |
-
* @param string $directory
|
197 |
-
* @return string|null
|
198 |
-
*/
|
199 |
-
protected function findChangelogName($directory) {
|
200 |
-
if ( empty($directory) || !is_dir($directory) || ($directory === '.') ) {
|
201 |
-
return null;
|
202 |
-
}
|
203 |
-
|
204 |
-
$possibleNames = array('CHANGES.md', 'CHANGELOG.md', 'changes.md', 'changelog.md');
|
205 |
-
$files = scandir($directory);
|
206 |
-
$foundNames = array_intersect($possibleNames, $files);
|
207 |
-
|
208 |
-
if ( !empty($foundNames) ) {
|
209 |
-
return reset($foundNames);
|
210 |
-
}
|
211 |
-
return null;
|
212 |
-
}
|
213 |
-
|
214 |
-
/**
|
215 |
-
* Set authentication credentials.
|
216 |
-
*
|
217 |
-
* @param $credentials
|
218 |
-
*/
|
219 |
-
public function setAuthentication($credentials) {
|
220 |
-
$this->credentials = $credentials;
|
221 |
-
}
|
222 |
-
|
223 |
-
public function isAuthenticationEnabled() {
|
224 |
-
return !empty($this->credentials);
|
225 |
-
}
|
226 |
-
|
227 |
-
/**
|
228 |
-
* @param string $url
|
229 |
-
* @return string
|
230 |
-
*/
|
231 |
-
public function signDownloadUrl($url) {
|
232 |
-
return $url;
|
233 |
-
}
|
234 |
-
|
235 |
-
/**
|
236 |
-
* @param string $filterName
|
237 |
-
*/
|
238 |
-
public function setHttpFilterName($filterName) {
|
239 |
-
$this->httpFilterName = $filterName;
|
240 |
-
}
|
241 |
-
}
|
242 |
-
|
243 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/BaseChecker.php
DELETED
@@ -1,22 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !interface_exists('Puc_v4_Vcs_BaseChecker', false) ):
|
3 |
-
|
4 |
-
interface Puc_v4_Vcs_BaseChecker {
|
5 |
-
/**
|
6 |
-
* Set the repository branch to use for updates. Defaults to 'master'.
|
7 |
-
*
|
8 |
-
* @param string $branch
|
9 |
-
* @return $this
|
10 |
-
*/
|
11 |
-
public function setBranch($branch);
|
12 |
-
|
13 |
-
/**
|
14 |
-
* Set authentication credentials.
|
15 |
-
*
|
16 |
-
* @param array|string $credentials
|
17 |
-
* @return $this
|
18 |
-
*/
|
19 |
-
public function setAuthentication($credentials);
|
20 |
-
}
|
21 |
-
|
22 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/BitBucketApi.php
DELETED
@@ -1,253 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Vcs_BitBucketApi', false) ):
|
3 |
-
|
4 |
-
class Puc_v4_Vcs_BitBucketApi extends Puc_v4_Vcs_Api {
|
5 |
-
/**
|
6 |
-
* @var Puc_v4_OAuthSignature
|
7 |
-
*/
|
8 |
-
private $oauth = null;
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var string
|
12 |
-
*/
|
13 |
-
private $username;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var string
|
17 |
-
*/
|
18 |
-
private $repository;
|
19 |
-
|
20 |
-
public function __construct($repositoryUrl, $credentials = array()) {
|
21 |
-
$path = @parse_url($repositoryUrl, PHP_URL_PATH);
|
22 |
-
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
23 |
-
$this->username = $matches['username'];
|
24 |
-
$this->repository = $matches['repository'];
|
25 |
-
} else {
|
26 |
-
throw new InvalidArgumentException('Invalid BitBucket repository URL: "' . $repositoryUrl . '"');
|
27 |
-
}
|
28 |
-
|
29 |
-
parent::__construct($repositoryUrl, $credentials);
|
30 |
-
}
|
31 |
-
|
32 |
-
/**
|
33 |
-
* Figure out which reference (i.e tag or branch) contains the latest version.
|
34 |
-
*
|
35 |
-
* @param string $configBranch Start looking in this branch.
|
36 |
-
* @return null|Puc_v4_Vcs_Reference
|
37 |
-
*/
|
38 |
-
public function chooseReference($configBranch) {
|
39 |
-
$updateSource = null;
|
40 |
-
|
41 |
-
//Check if there's a "Stable tag: 1.2.3" header that points to a valid tag.
|
42 |
-
$updateSource = $this->getStableTag($configBranch);
|
43 |
-
|
44 |
-
//Look for version-like tags.
|
45 |
-
if ( !$updateSource && ($configBranch === 'master') ) {
|
46 |
-
$updateSource = $this->getLatestTag();
|
47 |
-
}
|
48 |
-
//If all else fails, use the specified branch itself.
|
49 |
-
if ( !$updateSource ) {
|
50 |
-
$updateSource = $this->getBranch($configBranch);
|
51 |
-
}
|
52 |
-
|
53 |
-
return $updateSource;
|
54 |
-
}
|
55 |
-
|
56 |
-
public function getBranch($branchName) {
|
57 |
-
$branch = $this->api('/refs/branches/' . $branchName);
|
58 |
-
if ( is_wp_error($branch) || empty($branch) ) {
|
59 |
-
return null;
|
60 |
-
}
|
61 |
-
|
62 |
-
return new Puc_v4_Vcs_Reference(array(
|
63 |
-
'name' => $branch->name,
|
64 |
-
'updated' => $branch->target->date,
|
65 |
-
'downloadUrl' => $this->getDownloadUrl($branch->name),
|
66 |
-
));
|
67 |
-
}
|
68 |
-
|
69 |
-
/**
|
70 |
-
* Get a specific tag.
|
71 |
-
*
|
72 |
-
* @param string $tagName
|
73 |
-
* @return Puc_v4_Vcs_Reference|null
|
74 |
-
*/
|
75 |
-
public function getTag($tagName) {
|
76 |
-
$tag = $this->api('/refs/tags/' . $tagName);
|
77 |
-
if ( is_wp_error($tag) || empty($tag) ) {
|
78 |
-
return null;
|
79 |
-
}
|
80 |
-
|
81 |
-
return new Puc_v4_Vcs_Reference(array(
|
82 |
-
'name' => $tag->name,
|
83 |
-
'version' => ltrim($tag->name, 'v'),
|
84 |
-
'updated' => $tag->target->date,
|
85 |
-
'downloadUrl' => $this->getDownloadUrl($tag->name),
|
86 |
-
));
|
87 |
-
}
|
88 |
-
|
89 |
-
/**
|
90 |
-
* Get the tag that looks like the highest version number.
|
91 |
-
*
|
92 |
-
* @return Puc_v4_Vcs_Reference|null
|
93 |
-
*/
|
94 |
-
public function getLatestTag() {
|
95 |
-
$tags = $this->api('/refs/tags?sort=-target.date');
|
96 |
-
if ( !isset($tags, $tags->values) || !is_array($tags->values) ) {
|
97 |
-
return null;
|
98 |
-
}
|
99 |
-
|
100 |
-
//Filter and sort the list of tags.
|
101 |
-
$versionTags = $this->sortTagsByVersion($tags->values);
|
102 |
-
|
103 |
-
//Return the first result.
|
104 |
-
if ( !empty($versionTags) ) {
|
105 |
-
$tag = $versionTags[0];
|
106 |
-
return new Puc_v4_Vcs_Reference(array(
|
107 |
-
'name' => $tag->name,
|
108 |
-
'version' => ltrim($tag->name, 'v'),
|
109 |
-
'updated' => $tag->target->date,
|
110 |
-
'downloadUrl' => $this->getDownloadUrl($tag->name),
|
111 |
-
));
|
112 |
-
}
|
113 |
-
return null;
|
114 |
-
}
|
115 |
-
|
116 |
-
/**
|
117 |
-
* Get the tag/ref specified by the "Stable tag" header in the readme.txt of a given branch.
|
118 |
-
*
|
119 |
-
* @param string $branch
|
120 |
-
* @return null|Puc_v4_Vcs_Reference
|
121 |
-
*/
|
122 |
-
protected function getStableTag($branch) {
|
123 |
-
$remoteReadme = $this->getRemoteReadme($branch);
|
124 |
-
if ( !empty($remoteReadme['stable_tag']) ) {
|
125 |
-
$tag = $remoteReadme['stable_tag'];
|
126 |
-
|
127 |
-
//You can explicitly opt out of using tags by setting "Stable tag" to
|
128 |
-
//"trunk" or the name of the current branch.
|
129 |
-
if ( ($tag === $branch) || ($tag === 'trunk') ) {
|
130 |
-
return $this->getBranch($branch);
|
131 |
-
}
|
132 |
-
|
133 |
-
return $this->getTag($tag);
|
134 |
-
}
|
135 |
-
|
136 |
-
return null;
|
137 |
-
}
|
138 |
-
|
139 |
-
/**
|
140 |
-
* @param string $ref
|
141 |
-
* @return string
|
142 |
-
*/
|
143 |
-
protected function getDownloadUrl($ref) {
|
144 |
-
return sprintf(
|
145 |
-
'https://bitbucket.org/%s/%s/get/%s.zip',
|
146 |
-
$this->username,
|
147 |
-
$this->repository,
|
148 |
-
$ref
|
149 |
-
);
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Get the contents of a file from a specific branch or tag.
|
154 |
-
*
|
155 |
-
* @param string $path File name.
|
156 |
-
* @param string $ref
|
157 |
-
* @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
|
158 |
-
*/
|
159 |
-
public function getRemoteFile($path, $ref = 'master') {
|
160 |
-
$response = $this->api('src/' . $ref . '/' . ltrim($path), '1.0');
|
161 |
-
if ( is_wp_error($response) || !isset($response, $response->data) ) {
|
162 |
-
return null;
|
163 |
-
}
|
164 |
-
return $response->data;
|
165 |
-
}
|
166 |
-
|
167 |
-
/**
|
168 |
-
* Get the timestamp of the latest commit that changed the specified branch or tag.
|
169 |
-
*
|
170 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
171 |
-
* @return string|null
|
172 |
-
*/
|
173 |
-
public function getLatestCommitTime($ref) {
|
174 |
-
$response = $this->api('commits/' . $ref);
|
175 |
-
if ( isset($response->values, $response->values[0], $response->values[0]->date) ) {
|
176 |
-
return $response->values[0]->date;
|
177 |
-
}
|
178 |
-
return null;
|
179 |
-
}
|
180 |
-
|
181 |
-
/**
|
182 |
-
* Perform a BitBucket API 2.0 request.
|
183 |
-
*
|
184 |
-
* @param string $url
|
185 |
-
* @param string $version
|
186 |
-
* @return mixed|WP_Error
|
187 |
-
*/
|
188 |
-
public function api($url, $version = '2.0') {
|
189 |
-
//printf('Requesting %s<br>' . "\n", $url);
|
190 |
-
|
191 |
-
$url = implode('/', array(
|
192 |
-
'https://api.bitbucket.org',
|
193 |
-
$version,
|
194 |
-
'repositories',
|
195 |
-
$this->username,
|
196 |
-
$this->repository,
|
197 |
-
ltrim($url, '/')
|
198 |
-
));
|
199 |
-
|
200 |
-
if ( $this->oauth ) {
|
201 |
-
$url = $this->oauth->sign($url,'GET');
|
202 |
-
}
|
203 |
-
|
204 |
-
$options = array('timeout' => 10);
|
205 |
-
if ( !empty($this->httpFilterName) ) {
|
206 |
-
$options = apply_filters($this->httpFilterName, $options);
|
207 |
-
}
|
208 |
-
$response = wp_remote_get($url, $options);
|
209 |
-
if ( is_wp_error($response) ) {
|
210 |
-
return $response;
|
211 |
-
}
|
212 |
-
|
213 |
-
$code = wp_remote_retrieve_response_code($response);
|
214 |
-
$body = wp_remote_retrieve_body($response);
|
215 |
-
if ( $code === 200 ) {
|
216 |
-
$document = json_decode($body);
|
217 |
-
return $document;
|
218 |
-
}
|
219 |
-
|
220 |
-
return new WP_Error(
|
221 |
-
'puc-bitbucket-http-error',
|
222 |
-
'BitBucket API error. HTTP status: ' . $code
|
223 |
-
);
|
224 |
-
}
|
225 |
-
|
226 |
-
/**
|
227 |
-
* @param array $credentials
|
228 |
-
*/
|
229 |
-
public function setAuthentication($credentials) {
|
230 |
-
parent::setAuthentication($credentials);
|
231 |
-
|
232 |
-
if ( !empty($credentials) && !empty($credentials['consumer_key']) ) {
|
233 |
-
$this->oauth = new Puc_v4_OAuthSignature(
|
234 |
-
$credentials['consumer_key'],
|
235 |
-
$credentials['consumer_secret']
|
236 |
-
);
|
237 |
-
} else {
|
238 |
-
$this->oauth = null;
|
239 |
-
}
|
240 |
-
}
|
241 |
-
|
242 |
-
public function signDownloadUrl($url) {
|
243 |
-
//Add authentication data to download URLs. Since OAuth signatures incorporate
|
244 |
-
//timestamps, we have to do this immediately before inserting the update. Otherwise
|
245 |
-
//authentication could fail due to a stale timestamp.
|
246 |
-
if ( $this->oauth ) {
|
247 |
-
$url = $this->oauth->sign($url);
|
248 |
-
}
|
249 |
-
return $url;
|
250 |
-
}
|
251 |
-
}
|
252 |
-
|
253 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/GitHubApi.php
DELETED
@@ -1,286 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_Vcs_GitHubApi', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_Vcs_GitHubApi extends Puc_v4_Vcs_Api {
|
6 |
-
/**
|
7 |
-
* @var string GitHub username.
|
8 |
-
*/
|
9 |
-
protected $userName;
|
10 |
-
/**
|
11 |
-
* @var string GitHub repository name.
|
12 |
-
*/
|
13 |
-
protected $repositoryName;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* @var string Either a fully qualified repository URL, or just "user/repo-name".
|
17 |
-
*/
|
18 |
-
protected $repositoryUrl;
|
19 |
-
|
20 |
-
/**
|
21 |
-
* @var string GitHub authentication token. Optional.
|
22 |
-
*/
|
23 |
-
protected $accessToken;
|
24 |
-
|
25 |
-
public function __construct($repositoryUrl, $accessToken = null) {
|
26 |
-
$path = @parse_url($repositoryUrl, PHP_URL_PATH);
|
27 |
-
if ( preg_match('@^/?(?P<username>[^/]+?)/(?P<repository>[^/#?&]+?)/?$@', $path, $matches) ) {
|
28 |
-
$this->userName = $matches['username'];
|
29 |
-
$this->repositoryName = $matches['repository'];
|
30 |
-
} else {
|
31 |
-
throw new InvalidArgumentException('Invalid GitHub repository URL: "' . $repositoryUrl . '"');
|
32 |
-
}
|
33 |
-
|
34 |
-
parent::__construct($repositoryUrl, $accessToken);
|
35 |
-
}
|
36 |
-
|
37 |
-
/**
|
38 |
-
* Get the latest release from GitHub.
|
39 |
-
*
|
40 |
-
* @return Puc_v4_Vcs_Reference|null
|
41 |
-
*/
|
42 |
-
public function getLatestRelease() {
|
43 |
-
$release = $this->api('/repos/:user/:repo/releases/latest');
|
44 |
-
if ( is_wp_error($release) || !is_object($release) || !isset($release->tag_name) ) {
|
45 |
-
return null;
|
46 |
-
}
|
47 |
-
|
48 |
-
$reference = new Puc_v4_Vcs_Reference(array(
|
49 |
-
'name' => $release->tag_name,
|
50 |
-
'version' => ltrim($release->tag_name, 'v'), //Remove the "v" prefix from "v1.2.3".
|
51 |
-
'downloadUrl' => $this->signDownloadUrl($release->zipball_url),
|
52 |
-
'updated' => $release->created_at,
|
53 |
-
));
|
54 |
-
|
55 |
-
if ( !empty($release->body) ) {
|
56 |
-
/** @noinspection PhpUndefinedClassInspection */
|
57 |
-
$reference->changelog = Parsedown::instance()->text($release->body);
|
58 |
-
}
|
59 |
-
if ( isset($release->assets[0]) ) {
|
60 |
-
$reference->downloadCount = $release->assets[0]->download_count;
|
61 |
-
}
|
62 |
-
|
63 |
-
return $reference;
|
64 |
-
}
|
65 |
-
|
66 |
-
/**
|
67 |
-
* Get the tag that looks like the highest version number.
|
68 |
-
*
|
69 |
-
* @return Puc_v4_Vcs_Reference|null
|
70 |
-
*/
|
71 |
-
public function getLatestTag() {
|
72 |
-
$tags = $this->api('/repos/:user/:repo/tags');
|
73 |
-
|
74 |
-
if ( is_wp_error($tags) || empty($tags) || !is_array($tags) ) {
|
75 |
-
return null;
|
76 |
-
}
|
77 |
-
|
78 |
-
$versionTags = $this->sortTagsByVersion($tags);
|
79 |
-
if ( empty($versionTags) ) {
|
80 |
-
return null;
|
81 |
-
}
|
82 |
-
|
83 |
-
$tag = $versionTags[0];
|
84 |
-
return new Puc_v4_Vcs_Reference(array(
|
85 |
-
'name' => $tag->name,
|
86 |
-
'version' => ltrim($tag->name, 'v'),
|
87 |
-
'downloadUrl' => $this->signDownloadUrl($tag->zipball_url),
|
88 |
-
));
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Get a branch by name.
|
93 |
-
*
|
94 |
-
* @param string $branchName
|
95 |
-
* @return null|Puc_v4_Vcs_Reference
|
96 |
-
*/
|
97 |
-
public function getBranch($branchName) {
|
98 |
-
$branch = $this->api('/repos/:user/:repo/branches/' . $branchName);
|
99 |
-
if ( is_wp_error($branch) || empty($branch) ) {
|
100 |
-
return null;
|
101 |
-
}
|
102 |
-
|
103 |
-
$reference = new Puc_v4_Vcs_Reference(array(
|
104 |
-
'name' => $branch->name,
|
105 |
-
'downloadUrl' => $this->buildArchiveDownloadUrl($branch->name),
|
106 |
-
));
|
107 |
-
|
108 |
-
if ( isset($branch->commit, $branch->commit->commit, $branch->commit->commit->author->date) ) {
|
109 |
-
$reference->updated = $branch->commit->commit->author->date;
|
110 |
-
}
|
111 |
-
|
112 |
-
return $reference;
|
113 |
-
}
|
114 |
-
|
115 |
-
/**
|
116 |
-
* Get the latest commit that changed the specified file.
|
117 |
-
*
|
118 |
-
* @param string $filename
|
119 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
120 |
-
* @return StdClass|null
|
121 |
-
*/
|
122 |
-
public function getLatestCommit($filename, $ref = 'master') {
|
123 |
-
$commits = $this->api(
|
124 |
-
'/repos/:user/:repo/commits',
|
125 |
-
array(
|
126 |
-
'path' => $filename,
|
127 |
-
'sha' => $ref,
|
128 |
-
)
|
129 |
-
);
|
130 |
-
if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
|
131 |
-
return $commits[0];
|
132 |
-
}
|
133 |
-
return null;
|
134 |
-
}
|
135 |
-
|
136 |
-
/**
|
137 |
-
* Get the timestamp of the latest commit that changed the specified branch or tag.
|
138 |
-
*
|
139 |
-
* @param string $ref Reference name (e.g. branch or tag).
|
140 |
-
* @return string|null
|
141 |
-
*/
|
142 |
-
public function getLatestCommitTime($ref) {
|
143 |
-
$commits = $this->api('/repos/:user/:repo/commits', array('sha' => $ref));
|
144 |
-
if ( !is_wp_error($commits) && is_array($commits) && isset($commits[0]) ) {
|
145 |
-
return $commits[0]->commit->author->date;
|
146 |
-
}
|
147 |
-
return null;
|
148 |
-
}
|
149 |
-
|
150 |
-
/**
|
151 |
-
* Perform a GitHub API request.
|
152 |
-
*
|
153 |
-
* @param string $url
|
154 |
-
* @param array $queryParams
|
155 |
-
* @return mixed|WP_Error
|
156 |
-
*/
|
157 |
-
protected function api($url, $queryParams = array()) {
|
158 |
-
$variables = array(
|
159 |
-
'user' => $this->userName,
|
160 |
-
'repo' => $this->repositoryName,
|
161 |
-
);
|
162 |
-
foreach ($variables as $name => $value) {
|
163 |
-
$url = str_replace('/:' . $name, '/' . urlencode($value), $url);
|
164 |
-
}
|
165 |
-
$url = 'https://api.github.com' . $url;
|
166 |
-
|
167 |
-
if ( !empty($this->accessToken) ) {
|
168 |
-
$queryParams['access_token'] = $this->accessToken;
|
169 |
-
}
|
170 |
-
if ( !empty($queryParams) ) {
|
171 |
-
$url = add_query_arg($queryParams, $url);
|
172 |
-
}
|
173 |
-
|
174 |
-
$options = array('timeout' => 10);
|
175 |
-
if ( !empty($this->httpFilterName) ) {
|
176 |
-
$options = apply_filters($this->httpFilterName, $options);
|
177 |
-
}
|
178 |
-
$response = wp_remote_get($url, $options);
|
179 |
-
if ( is_wp_error($response) ) {
|
180 |
-
return $response;
|
181 |
-
}
|
182 |
-
|
183 |
-
$code = wp_remote_retrieve_response_code($response);
|
184 |
-
$body = wp_remote_retrieve_body($response);
|
185 |
-
if ( $code === 200 ) {
|
186 |
-
$document = json_decode($body);
|
187 |
-
return $document;
|
188 |
-
}
|
189 |
-
|
190 |
-
return new WP_Error(
|
191 |
-
'puc-github-http-error',
|
192 |
-
'GitHub API error. HTTP status: ' . $code
|
193 |
-
);
|
194 |
-
}
|
195 |
-
|
196 |
-
/**
|
197 |
-
* Get the contents of a file from a specific branch or tag.
|
198 |
-
*
|
199 |
-
* @param string $path File name.
|
200 |
-
* @param string $ref
|
201 |
-
* @return null|string Either the contents of the file, or null if the file doesn't exist or there's an error.
|
202 |
-
*/
|
203 |
-
public function getRemoteFile($path, $ref = 'master') {
|
204 |
-
$apiUrl = '/repos/:user/:repo/contents/' . $path;
|
205 |
-
$response = $this->api($apiUrl, array('ref' => $ref));
|
206 |
-
|
207 |
-
if ( is_wp_error($response) || !isset($response->content) || ($response->encoding !== 'base64') ) {
|
208 |
-
return null;
|
209 |
-
}
|
210 |
-
return base64_decode($response->content);
|
211 |
-
}
|
212 |
-
|
213 |
-
/**
|
214 |
-
* Generate a URL to download a ZIP archive of the specified branch/tag/etc.
|
215 |
-
*
|
216 |
-
* @param string $ref
|
217 |
-
* @return string
|
218 |
-
*/
|
219 |
-
public function buildArchiveDownloadUrl($ref = 'master') {
|
220 |
-
$url = sprintf(
|
221 |
-
'https://api.github.com/repos/%1$s/%2$s/zipball/%3$s',
|
222 |
-
urlencode($this->userName),
|
223 |
-
urlencode($this->repositoryName),
|
224 |
-
urlencode($ref)
|
225 |
-
);
|
226 |
-
if ( !empty($this->accessToken) ) {
|
227 |
-
$url = $this->signDownloadUrl($url);
|
228 |
-
}
|
229 |
-
return $url;
|
230 |
-
}
|
231 |
-
|
232 |
-
/**
|
233 |
-
* Get a specific tag.
|
234 |
-
*
|
235 |
-
* @param string $tagName
|
236 |
-
* @return Puc_v4_Vcs_Reference|null
|
237 |
-
*/
|
238 |
-
public function getTag($tagName) {
|
239 |
-
//The current GitHub update checker doesn't use getTag, so I didn't bother to implement it.
|
240 |
-
throw new LogicException('The ' . __METHOD__ . ' method is not implemented and should not be used.');
|
241 |
-
}
|
242 |
-
|
243 |
-
public function setAuthentication($credentials) {
|
244 |
-
parent::setAuthentication($credentials);
|
245 |
-
$this->accessToken = is_string($credentials) ? $credentials : null;
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Figure out which reference (i.e tag or branch) contains the latest version.
|
250 |
-
*
|
251 |
-
* @param string $configBranch Start looking in this branch.
|
252 |
-
* @return null|Puc_v4_Vcs_Reference
|
253 |
-
*/
|
254 |
-
public function chooseReference($configBranch) {
|
255 |
-
$updateSource = null;
|
256 |
-
|
257 |
-
if ( $configBranch === 'master' ) {
|
258 |
-
//Use the latest release.
|
259 |
-
$updateSource = $this->getLatestRelease();
|
260 |
-
if ( $updateSource === null ) {
|
261 |
-
//Failing that, use the tag with the highest version number.
|
262 |
-
$updateSource = $this->getLatestTag();
|
263 |
-
}
|
264 |
-
}
|
265 |
-
//Alternatively, just use the branch itself.
|
266 |
-
if ( empty($updateSource) ) {
|
267 |
-
$updateSource = $this->getBranch($configBranch);
|
268 |
-
}
|
269 |
-
|
270 |
-
return $updateSource;
|
271 |
-
}
|
272 |
-
|
273 |
-
/**
|
274 |
-
* @param string $url
|
275 |
-
* @return string
|
276 |
-
*/
|
277 |
-
public function signDownloadUrl($url) {
|
278 |
-
if ( empty($this->credentials) ) {
|
279 |
-
return $url;
|
280 |
-
}
|
281 |
-
return add_query_arg('access_token', $this->credentials, $url);
|
282 |
-
}
|
283 |
-
|
284 |
-
}
|
285 |
-
|
286 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/PluginUpdateChecker.php
DELETED
@@ -1,198 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Vcs_PluginUpdateChecker') ):
|
3 |
-
|
4 |
-
class Puc_v4_Vcs_PluginUpdateChecker extends Puc_v4_Plugin_UpdateChecker implements Puc_v4_Vcs_BaseChecker {
|
5 |
-
/**
|
6 |
-
* @var string The branch where to look for updates. Defaults to "master".
|
7 |
-
*/
|
8 |
-
protected $branch = 'master';
|
9 |
-
|
10 |
-
/**
|
11 |
-
* @var Puc_v4_Vcs_Api Repository API client.
|
12 |
-
*/
|
13 |
-
protected $api = null;
|
14 |
-
|
15 |
-
/**
|
16 |
-
* Puc_v4_Vcs_PluginUpdateChecker constructor.
|
17 |
-
*
|
18 |
-
* @param Puc_v4_Vcs_Api $api
|
19 |
-
* @param string $pluginFile
|
20 |
-
* @param string $slug
|
21 |
-
* @param int $checkPeriod
|
22 |
-
* @param string $optionName
|
23 |
-
* @param string $muPluginFile
|
24 |
-
*/
|
25 |
-
public function __construct($api, $pluginFile, $slug = '', $checkPeriod = 12, $optionName = '', $muPluginFile = '') {
|
26 |
-
$this->api = $api;
|
27 |
-
$this->api->setHttpFilterName($this->getUniqueName('request_info_options'));
|
28 |
-
|
29 |
-
parent::__construct($api->getRepositoryUrl(), $pluginFile, $slug, $checkPeriod, $optionName, $muPluginFile);
|
30 |
-
}
|
31 |
-
|
32 |
-
public function requestInfo($unusedParameter = null) {
|
33 |
-
//We have to make several remote API requests to gather all the necessary info
|
34 |
-
//which can take a while on slow networks.
|
35 |
-
set_time_limit(60);
|
36 |
-
|
37 |
-
$api = $this->api;
|
38 |
-
|
39 |
-
$info = new Puc_v4_Plugin_Info();
|
40 |
-
$info->filename = $this->pluginFile;
|
41 |
-
$info->slug = $this->slug;
|
42 |
-
|
43 |
-
$this->setInfoFromHeader($this->getPluginHeader(), $info);
|
44 |
-
|
45 |
-
//Pick a branch or tag.
|
46 |
-
$updateSource = $api->chooseReference($this->branch);
|
47 |
-
if ( $updateSource ) {
|
48 |
-
$ref = $updateSource->name;
|
49 |
-
$info->version = $updateSource->version;
|
50 |
-
$info->last_updated = $updateSource->updated;
|
51 |
-
$info->download_url = $updateSource->downloadUrl;
|
52 |
-
|
53 |
-
if ( !empty($updateSource->changelog) ) {
|
54 |
-
$info->sections['changelog'] = $updateSource->changelog;
|
55 |
-
}
|
56 |
-
if ( isset($updateSource->downloadCount) ) {
|
57 |
-
$info->downloaded = $updateSource->downloadCount;
|
58 |
-
}
|
59 |
-
} else {
|
60 |
-
//There's probably a network problem or an authentication error.
|
61 |
-
return null;
|
62 |
-
}
|
63 |
-
|
64 |
-
//Get headers from the main plugin file in this branch/tag. Its "Version" header and other metadata
|
65 |
-
//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
|
66 |
-
$mainPluginFile = basename($this->pluginFile);
|
67 |
-
$remotePlugin = $api->getRemoteFile($mainPluginFile, $ref);
|
68 |
-
if ( !empty($remotePlugin) ) {
|
69 |
-
$remoteHeader = $this->getFileHeader($remotePlugin);
|
70 |
-
$this->setInfoFromHeader($remoteHeader, $info);
|
71 |
-
}
|
72 |
-
|
73 |
-
//Try parsing readme.txt. If it's formatted according to WordPress.org standards, it will contain
|
74 |
-
//a lot of useful information like the required/tested WP version, changelog, and so on.
|
75 |
-
if ( $this->readmeTxtExistsLocally() ) {
|
76 |
-
$this->setInfoFromRemoteReadme($ref, $info);
|
77 |
-
}
|
78 |
-
|
79 |
-
//The changelog might be in a separate file.
|
80 |
-
if ( empty($info->sections['changelog']) ) {
|
81 |
-
$info->sections['changelog'] = $api->getRemoteChangelog($ref, dirname($this->getAbsolutePath()));
|
82 |
-
if ( empty($info->sections['changelog']) ) {
|
83 |
-
$info->sections['changelog'] = __('There is no changelog available.', 'plugin-update-checker');
|
84 |
-
}
|
85 |
-
}
|
86 |
-
|
87 |
-
if ( empty($info->last_updated) ) {
|
88 |
-
//Fetch the latest commit that changed the tag or branch and use it as the "last_updated" date.
|
89 |
-
$latestCommitTime = $api->getLatestCommitTime($ref);
|
90 |
-
if ( $latestCommitTime !== null ) {
|
91 |
-
$info->last_updated = $latestCommitTime;
|
92 |
-
}
|
93 |
-
}
|
94 |
-
|
95 |
-
$info = apply_filters($this->getUniqueName('request_info_result'), $info, null);
|
96 |
-
return $info;
|
97 |
-
}
|
98 |
-
|
99 |
-
/**
|
100 |
-
* Check if the currently installed version has a readme.txt file.
|
101 |
-
*
|
102 |
-
* @return bool
|
103 |
-
*/
|
104 |
-
protected function readmeTxtExistsLocally() {
|
105 |
-
$pluginDirectory = dirname($this->pluginAbsolutePath);
|
106 |
-
if ( empty($this->pluginAbsolutePath) || !is_dir($pluginDirectory) || ($pluginDirectory === '.') ) {
|
107 |
-
return false;
|
108 |
-
}
|
109 |
-
return is_file($pluginDirectory . '/readme.txt');
|
110 |
-
}
|
111 |
-
|
112 |
-
/**
|
113 |
-
* Copy plugin metadata from a file header to a Plugin Info object.
|
114 |
-
*
|
115 |
-
* @param array $fileHeader
|
116 |
-
* @param Puc_v4_Plugin_Info $pluginInfo
|
117 |
-
*/
|
118 |
-
protected function setInfoFromHeader($fileHeader, $pluginInfo) {
|
119 |
-
$headerToPropertyMap = array(
|
120 |
-
'Version' => 'version',
|
121 |
-
'Name' => 'name',
|
122 |
-
'PluginURI' => 'homepage',
|
123 |
-
'Author' => 'author',
|
124 |
-
'AuthorName' => 'author',
|
125 |
-
'AuthorURI' => 'author_homepage',
|
126 |
-
|
127 |
-
'Requires WP' => 'requires',
|
128 |
-
'Tested WP' => 'tested',
|
129 |
-
'Requires at least' => 'requires',
|
130 |
-
'Tested up to' => 'tested',
|
131 |
-
);
|
132 |
-
foreach ($headerToPropertyMap as $headerName => $property) {
|
133 |
-
if ( isset($fileHeader[$headerName]) && !empty($fileHeader[$headerName]) ) {
|
134 |
-
$pluginInfo->$property = $fileHeader[$headerName];
|
135 |
-
}
|
136 |
-
}
|
137 |
-
|
138 |
-
if ( !empty($fileHeader['Description']) ) {
|
139 |
-
$pluginInfo->sections['description'] = $fileHeader['Description'];
|
140 |
-
}
|
141 |
-
}
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Copy plugin metadata from the remote readme.txt file.
|
145 |
-
*
|
146 |
-
* @param string $ref GitHub tag or branch where to look for the readme.
|
147 |
-
* @param Puc_v4_Plugin_Info $pluginInfo
|
148 |
-
*/
|
149 |
-
protected function setInfoFromRemoteReadme($ref, $pluginInfo) {
|
150 |
-
$readme = $this->api->getRemoteReadme($ref);
|
151 |
-
if ( empty($readme) ) {
|
152 |
-
return;
|
153 |
-
}
|
154 |
-
|
155 |
-
if ( isset($readme['sections']) ) {
|
156 |
-
$pluginInfo->sections = array_merge($pluginInfo->sections, $readme['sections']);
|
157 |
-
}
|
158 |
-
if ( !empty($readme['tested_up_to']) ) {
|
159 |
-
$pluginInfo->tested = $readme['tested_up_to'];
|
160 |
-
}
|
161 |
-
if ( !empty($readme['requires_at_least']) ) {
|
162 |
-
$pluginInfo->requires = $readme['requires_at_least'];
|
163 |
-
}
|
164 |
-
|
165 |
-
if ( isset($readme['upgrade_notice'], $readme['upgrade_notice'][$pluginInfo->version]) ) {
|
166 |
-
$pluginInfo->upgrade_notice = $readme['upgrade_notice'][$pluginInfo->version];
|
167 |
-
}
|
168 |
-
}
|
169 |
-
|
170 |
-
public function setBranch($branch) {
|
171 |
-
$this->branch = $branch;
|
172 |
-
return $this;
|
173 |
-
}
|
174 |
-
|
175 |
-
public function setAuthentication($credentials) {
|
176 |
-
$this->api->setAuthentication($credentials);
|
177 |
-
return $this;
|
178 |
-
}
|
179 |
-
|
180 |
-
public function getUpdate() {
|
181 |
-
$update = parent::getUpdate();
|
182 |
-
|
183 |
-
if ( isset($update) && !empty($update->download_url) ) {
|
184 |
-
$update->download_url = $this->api->signDownloadUrl($update->download_url);
|
185 |
-
}
|
186 |
-
|
187 |
-
return $update;
|
188 |
-
}
|
189 |
-
|
190 |
-
public function onDisplayConfiguration($panel) {
|
191 |
-
parent::onDisplayConfiguration($panel);
|
192 |
-
$panel->row('Branch', $this->branch);
|
193 |
-
$panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
|
194 |
-
$panel->row('API client', get_class($this->api));
|
195 |
-
}
|
196 |
-
}
|
197 |
-
|
198 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/Reference.php
DELETED
@@ -1,49 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
if ( !class_exists('Puc_v4_Vcs_Reference', false) ):
|
3 |
-
|
4 |
-
/**
|
5 |
-
* This class represents a VCS branch or tag. It's intended as a read only, short-lived container
|
6 |
-
* that only exists to provide a limited degree of type checking.
|
7 |
-
*
|
8 |
-
* @property string $name
|
9 |
-
* @property string|null version
|
10 |
-
* @property string $downloadUrl
|
11 |
-
* @property string $updated
|
12 |
-
*
|
13 |
-
* @property string|null $changelog
|
14 |
-
* @property int|null $downloadCount
|
15 |
-
*/
|
16 |
-
class Puc_v4_Vcs_Reference {
|
17 |
-
private $properties = array();
|
18 |
-
|
19 |
-
public function __construct($properties = array()) {
|
20 |
-
$this->properties = $properties;
|
21 |
-
}
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @param string $name
|
25 |
-
* @return mixed|null
|
26 |
-
*/
|
27 |
-
function __get($name) {
|
28 |
-
return array_key_exists($name, $this->properties) ? $this->properties[$name] : null;
|
29 |
-
}
|
30 |
-
|
31 |
-
/**
|
32 |
-
* @param string $name
|
33 |
-
* @param mixed $value
|
34 |
-
*/
|
35 |
-
function __set($name, $value) {
|
36 |
-
$this->properties[$name] = $value;
|
37 |
-
}
|
38 |
-
|
39 |
-
/**
|
40 |
-
* @param string $name
|
41 |
-
* @return bool
|
42 |
-
*/
|
43 |
-
function __isset($name) {
|
44 |
-
return isset($this->properties[$name]);
|
45 |
-
}
|
46 |
-
|
47 |
-
}
|
48 |
-
|
49 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vendor/yahnis-elsts/plugin-update-checker/Puc/v4/Vcs/ThemeUpdateChecker.php
DELETED
@@ -1,101 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
if ( !class_exists('Puc_v4_Vcs_ThemeUpdateChecker', false) ):
|
4 |
-
|
5 |
-
class Puc_v4_Vcs_ThemeUpdateChecker extends Puc_v4_Theme_UpdateChecker implements Puc_v4_Vcs_BaseChecker {
|
6 |
-
/**
|
7 |
-
* @var string The branch where to look for updates. Defaults to "master".
|
8 |
-
*/
|
9 |
-
protected $branch = 'master';
|
10 |
-
|
11 |
-
/**
|
12 |
-
* @var Puc_v4_Vcs_Api Repository API client.
|
13 |
-
*/
|
14 |
-
protected $api = null;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Puc_v4_Vcs_ThemeUpdateChecker constructor.
|
18 |
-
*
|
19 |
-
* @param Puc_v4_Vcs_Api $api
|
20 |
-
* @param null $stylesheet
|
21 |
-
* @param null $customSlug
|
22 |
-
* @param int $checkPeriod
|
23 |
-
* @param string $optionName
|
24 |
-
*/
|
25 |
-
public function __construct($api, $stylesheet = null, $customSlug = null, $checkPeriod = 12, $optionName = '') {
|
26 |
-
$this->api = $api;
|
27 |
-
$this->api->setHttpFilterName($this->getUniqueName('request_update_options'));
|
28 |
-
|
29 |
-
parent::__construct($api->getRepositoryUrl(), $stylesheet, $customSlug, $checkPeriod, $optionName);
|
30 |
-
}
|
31 |
-
|
32 |
-
public function requestUpdate() {
|
33 |
-
$api = $this->api;
|
34 |
-
|
35 |
-
$update = new Puc_v4_Theme_Update();
|
36 |
-
$update->slug = $this->slug;
|
37 |
-
|
38 |
-
//Figure out which reference (tag or branch) we'll use to get the latest version of the theme.
|
39 |
-
$updateSource = $api->chooseReference($this->branch);
|
40 |
-
if ( $updateSource ) {
|
41 |
-
$ref = $updateSource->name;
|
42 |
-
$update->download_url = $updateSource->downloadUrl;
|
43 |
-
} else {
|
44 |
-
$ref = $this->branch;
|
45 |
-
}
|
46 |
-
|
47 |
-
//Get headers from the main stylesheet in this branch/tag. Its "Version" header and other metadata
|
48 |
-
//are what the WordPress install will actually see after upgrading, so they take precedence over releases/tags.
|
49 |
-
$remoteHeader = $this->getFileHeader($api->getRemoteFile('style.css', $ref));
|
50 |
-
$update->version = Puc_v4_Utils::findNotEmpty(array(
|
51 |
-
$remoteHeader['Version'],
|
52 |
-
Puc_v4_Utils::get($updateSource, 'version'),
|
53 |
-
));
|
54 |
-
|
55 |
-
//The details URL defaults to the Theme URI header or the repository URL.
|
56 |
-
$update->details_url = Puc_v4_Utils::findNotEmpty(array(
|
57 |
-
$remoteHeader['ThemeURI'],
|
58 |
-
$this->theme->get('ThemeURI'),
|
59 |
-
$this->metadataUrl,
|
60 |
-
));
|
61 |
-
|
62 |
-
if ( empty($update->version) ) {
|
63 |
-
//It looks like we didn't find a valid update after all.
|
64 |
-
$update = null;
|
65 |
-
}
|
66 |
-
|
67 |
-
$update = $this->filterUpdateResult($update);
|
68 |
-
return $update;
|
69 |
-
}
|
70 |
-
|
71 |
-
//FIXME: This is duplicated code. Both theme and plugin subclasses that use VCS share these methods.
|
72 |
-
|
73 |
-
public function setBranch($branch) {
|
74 |
-
$this->branch = $branch;
|
75 |
-
return $this;
|
76 |
-
}
|
77 |
-
|
78 |
-
public function setAuthentication($credentials) {
|
79 |
-
$this->api->setAuthentication($credentials);
|
80 |
-
return $this;
|
81 |
-
}
|
82 |
-
|
83 |
-
public function getUpdate() {
|
84 |
-
$update = parent::getUpdate();
|
85 |
-
|
86 |
-
if ( isset($update) && !empty($update->download_url) ) {
|
87 |
-
$update->download_url = $this->api->signDownloadUrl($update->download_url);
|
88 |
-
}
|
89 |
-
|
90 |
-
return $update;
|
91 |
-
}
|
92 |
-
|
93 |
-
public function onDisplayConfiguration($panel) {
|
94 |
-
parent::onDisplayConfiguration($panel);
|
95 |
-
$panel->row('Branch', $this->branch);
|
96 |
-
$panel->row('Authentication enabled', $this->api->isAuthenticationEnabled() ? 'Yes' : 'No');
|
97 |
-
$panel->row('API client', get_class($this->api));
|
98 |
-
}
|
99 |
-
}
|
100 |
-
|
101 |
-
endif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
woo-discount-rules.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* Description: Simple Discount Rules for WooCommerce.
|
6 |
* Author: Flycart Technologies LLP
|
7 |
* Author URI: https://www.flycart.org
|
8 |
-
* Version: 1.9.
|
9 |
* Slug: woo-discount-rules
|
10 |
* Text Domain: woo-discount-rules
|
11 |
* Domain Path: /i18n/languages/
|
5 |
* Description: Simple Discount Rules for WooCommerce.
|
6 |
* Author: Flycart Technologies LLP
|
7 |
* Author URI: https://www.flycart.org
|
8 |
+
* Version: 1.9.2
|
9 |
* Slug: woo-discount-rules
|
10 |
* Text Domain: woo-discount-rules
|
11 |
* Domain Path: /i18n/languages/
|