← All changes
|
jetpack_vendor/automattic/jetpack-connection/src/class-package-version-tracker.php
+93
-3
13.0.2
→
16.3-beta
View file →
| @@ -6,8 +6,10 @@ | ||
| 6 | 6 | */ |
| 7 | 7 | |
| 8 | 8 | namespace Automattic\Jetpack\Connection; |
| 9 | 9 | |
| 10 | +use Jetpack_Options; | |
| 11 | + | |
| 10 | 12 | /** |
| 11 | 13 | * The Package_Version_Tracker class. |
| 12 | 14 | */ |
| 13 | 15 | class Package_Version_Tracker { |
| @@ -30,12 +32,48 @@ | ||
| 30 | 32 | */ |
| 31 | 33 | const CACHED_FAILED_REQUEST_EXPIRATION = 1 * HOUR_IN_SECONDS; |
| 32 | 34 | |
| 33 | 35 | /** |
| 36 | + * Transient key for rate limiting the package version requests; | |
| 37 | + */ | |
| 38 | + const RATE_LIMITER_KEY = 'jetpack_update_remote_package_last_query'; | |
| 39 | + | |
| 40 | + /** | |
| 41 | + * Only allow one versions check (and request) per minute. | |
| 42 | + */ | |
| 43 | + const RATE_LIMITER_TIMEOUT = MINUTE_IN_SECONDS; | |
| 44 | + | |
| 45 | + /** | |
| 46 | + * Runs the package version check on the `shutdown` hook. | |
| 47 | + * | |
| 48 | + * Static so the callback can be unregistered, and so the tracker is only | |
| 49 | + * constructed when the hook fires rather than during configuration. | |
| 50 | + */ | |
| 51 | + public static function update_on_shutdown() { | |
| 52 | + ( new self() )->maybe_update_package_versions(); | |
| 53 | + } | |
| 54 | + | |
| 55 | + /** | |
| 34 | 56 | * Uses the jetpack_package_versions filter to obtain the package versions from packages that need |
| 35 | 57 | * version tracking. If the package versions have changed, updates the option and notifies WPCOM. |
| 36 | 58 | */ |
| 37 | 59 | public function maybe_update_package_versions() { |
| 60 | + // Do not run too early or all the modules may not be loaded. | |
| 61 | + if ( ! did_action( 'init' ) ) { | |
| 62 | + return; | |
| 63 | + } | |
| 64 | + | |
| 65 | + // Only attempt to update the option on POST requests. | |
| 66 | + // This will prevent the option from being updated multiple times due to concurrent requests. | |
| 67 | + if ( ! ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] ) ) { | |
| 68 | + return; | |
| 69 | + } | |
| 70 | + | |
| 71 | + // The version check is being rate limited. | |
| 72 | + if ( $this->is_rate_limiting() ) { | |
| 73 | + return; | |
| 74 | + } | |
| 75 | + | |
| 38 | 76 | /** |
| 39 | 77 | * Obtains the package versions. |
| 40 | 78 | * |
| 41 | 79 | * @since 1.30.2 |
| @@ -64,15 +102,51 @@ | ||
| 64 | 102 | } |
| 65 | 103 | } |
| 66 | 104 | |
| 67 | 105 | /** |
| 68 | - * Updates the package versions: | |
| 106 | + * Updates the package versions option. | |
| 107 | + * | |
| 108 | + * @param array $package_versions The package versions. | |
| 109 | + */ | |
| 110 | + protected function update_package_versions_option( $package_versions ) { | |
| 111 | + if ( ! $this->is_sync_enabled() ) { | |
| 112 | + $this->update_package_versions_via_remote_request( $package_versions ); | |
| 113 | + // Remove the checksum for package versions, so it gets recalculated when sync gets activated. | |
| 114 | + $jetpack_callables_sync_checksum = Jetpack_Options::get_raw_option( 'jetpack_callables_sync_checksum' ); | |
| 115 | + if ( isset( $jetpack_callables_sync_checksum['jetpack_package_versions'] ) ) { | |
| 116 | + unset( $jetpack_callables_sync_checksum['jetpack_package_versions'] ); | |
| 117 | + Jetpack_Options::update_raw_option( 'jetpack_callables_sync_checksum', $jetpack_callables_sync_checksum ); | |
| 118 | + } | |
| 119 | + return; | |
| 120 | + } | |
| 121 | + | |
| 122 | + update_option( self::PACKAGE_VERSION_OPTION, $package_versions ); | |
| 123 | + } | |
| 124 | + | |
| 125 | + /** | |
| 126 | + * Whether Jetpack Sync is enabled. | |
| 127 | + * | |
| 128 | + * @return boolean true if Sync is present and enabled, false otherwise | |
| 129 | + */ | |
| 130 | + protected function is_sync_enabled() { | |
| 131 | + if ( class_exists( 'Automattic\Jetpack\Sync\Settings' ) && \Automattic\Jetpack\Sync\Settings::is_sync_enabled() ) { | |
| 132 | + | |
| 133 | + return true; | |
| 134 | + } | |
| 135 | + | |
| 136 | + return false; | |
| 137 | + } | |
| 138 | + | |
| 139 | + /** | |
| 140 | + * Fallback for updating the package versions via a remote request when Sync is not present. | |
| 141 | + * | |
| 142 | + * Updates the package versions as follows: | |
| 69 | 143 | * - Sends the updated package versions to wpcom. |
| 70 | 144 | * - Updates the 'jetpack_package_versions' option. |
| 71 | 145 | * |
| 72 | 146 | * @param array $package_versions The package versions. |
| 73 | 147 | */ |
| 74 | - protected function update_package_versions_option( $package_versions ) { | |
| 148 | + protected function update_package_versions_via_remote_request( $package_versions ) { | |
| 75 | 149 | $connection = new Manager(); |
| 76 | 150 | if ( ! $connection->is_connected() ) { |
| 77 | 151 | return; |
| 78 | 152 | } |
| @@ -87,9 +161,10 @@ | ||
| 87 | 161 | |
| 88 | 162 | $body = wp_json_encode( |
| 89 | 163 | array( |
| 90 | 164 | 'package_versions' => $package_versions, |
| 91 | - ) | |
| 165 | + ), | |
| 166 | + JSON_UNESCAPED_SLASHES | |
| 92 | 167 | ); |
| 93 | 168 | |
| 94 | 169 | $response = Client::wpcom_json_api_request_as_blog( |
| 95 | 170 | sprintf( '/sites/%d/jetpack-package-versions', $site_id ), |
| @@ -106,6 +181,21 @@ | ||
| 106 | 181 | update_option( self::PACKAGE_VERSION_OPTION, $package_versions ); |
| 107 | 182 | } else { |
| 108 | 183 | set_transient( self::CACHED_FAILED_REQUEST_KEY, time(), self::CACHED_FAILED_REQUEST_EXPIRATION ); |
| 109 | 184 | } |
| 185 | + } | |
| 186 | + | |
| 187 | + /** | |
| 188 | + * Check if version check is being rate limited, and update the rate limiting transient if needed. | |
| 189 | + * | |
| 190 | + * @return bool | |
| 191 | + */ | |
| 192 | + private function is_rate_limiting() { | |
| 193 | + if ( get_transient( static::RATE_LIMITER_KEY ) ) { | |
| 194 | + return true; | |
| 195 | + } | |
| 196 | + | |
| 197 | + set_transient( static::RATE_LIMITER_KEY, time(), static::RATE_LIMITER_TIMEOUT ); | |
| 198 | + | |
| 199 | + return false; | |
| 110 | 200 | } |
| 111 | 201 | } |