Ticket #7217: 7217.diff
File 7217.diff, 5.5 KB (added by , 14 months ago) |
---|
-
zip/class-serve.php
class Serve { 46 46 } elseif ( preg_match( '!^/plugin-checksums/(?P<slug>[a-z0-9-_]+)/(?P<version>.+?)(\.json)?$!i', $path, $m ) ) { 47 47 // Checksums 48 48 $checksum_request = true; 49 49 $signature_request = false; 50 50 } else { 51 51 throw new Exception( __METHOD__ . ': Invalid URL.' ); 52 52 } 53 53 54 54 $slug = strtolower( $m['slug'] ); 55 55 56 56 $version = 'trunk'; 57 57 if ( isset( $m['version'] ) && '' !== $m['version'] ) { 58 58 $version = $m['version']; 59 59 } 60 60 61 // Check to see if the plugin is closed. 62 if ( ! $checksum_request ) { 63 $closed_date = $this->get_post_meta( $slug, 'plugin_closed_date' ); 64 if ( $closed_date && strtotime( $closed_date ) + 5184000 /* 60 days */ < time() ) { 65 throw new Exception( __METHOD__ . ': Plugin is closed.' ); 66 } 67 } 68 61 69 // If the latest-stable is requested, determine the file to serve. 62 70 $is_latest_stable = ( 'latest-stable' == $version ); 63 71 if ( $is_latest_stable ) { 64 $version = $this->get_stable_tag( $slug ); 72 $version = $this->get_post_meta( $slug, 'stable_tag' ); 73 if ( ! $version ) { 74 throw new Exception( __METHOD__ . ': No stable version found.' ); 75 } 65 76 } 66 77 67 78 // Checksum requests for 'trunk' are not possible. 68 79 if ( $checksum_request && 'trunk' == $version ) { 69 80 throw new Exception( __METHOD__ . ': Checksum requests must include a version.' ); 70 81 } 71 82 72 83 $args = array( 73 84 'stats' => true, 74 85 ); 75 86 76 87 if ( $checksum_request || $signature_request ) { 77 88 $args['stats'] = false; 78 89 79 90 } elseif ( isset( $_GET['stats'] ) ) { 80 91 $args['stats'] = (bool) $_GET['stats']; 81 92 82 93 } elseif ( isset( $_GET['nostats'] ) ) { 83 94 $args['stats'] = ! empty( $_GET['nostats'] ); 84 95 } 85 96 86 87 97 return compact( 'zip', 'slug', 'version', 'args', 'checksum_request', 'signature_request', 'is_latest_stable' ); 88 98 } 89 99 90 100 /** 91 101 * Redirect to the latest stable version if requested. 92 102 * 93 103 * @param array $request The request array for the request. 94 104 */ 95 105 protected function maybe_redirect_latest_stable( $request ) { 96 106 if ( ! $request['is_latest_stable'] ) { 97 107 return; 98 108 } 99 109 100 110 $file = $this->get_file( $request ); 101 111 $redirect = 'https://downloads.wordpress.org/plugin/' . basename( $file ); … … class Serve { 107 117 // CORS, to match the ZIP passthrough. 108 118 header( 'Access-Control-Allow-Methods: GET, HEAD' ); 109 119 header( 'Access-Control-Allow-Origin: *' ); 110 120 111 121 // Tell browsers to only cache this for 5 minutes. 112 122 header( 'Cache-Control: max-age=300' ); 113 123 114 124 // Redirect to the file they want. 115 125 header( 'Location: ' . $redirect, 302 ); 116 126 exit; 117 127 } 118 128 119 129 /** 120 130 * Retrieve the stable_tag for a given plugin from Cache or the Database. 121 131 * 122 * @param string $plugin_slug The plugin slug 123 * @return string The stable_tag on success, Exception thrown on failure. 132 * @param string $plugin_slug The plugin slug. 133 * @param string $meta_key The meta_key to retrieve. 134 * @return string The meta_value on success, Exception thrown on failure. 124 135 */ 125 protected function get_ stable_tag( $plugin_slug) {136 protected function get_post_meta( $plugin_slug, $meta_key ) { 126 137 global $wpdb; 127 138 139 $value = false; 128 140 $post_id = $this->get_post_id( $plugin_slug ); 129 141 130 // Determine the stable_tag 131 $meta = wp_cache_get( $post_id, 'post_meta' ); 142 // Determine the value from the object cache first. 143 $meta = wp_cache_get( $post_id, 'post_meta' ); 144 $in_cache = isset( $meta[ $meta_key ][0] ); 132 145 133 $version = false; 134 if ( isset( $meta['stable_tag'][0] ) ) { 135 $version = $meta['stable_tag'][0]; 136 } 137 if ( ! $version ) { 138 $version = $wpdb->get_var( $wpdb->prepare( "SELECT meta_value FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = 'stable_tag' LIMIT 1", $post_id ) ); 139 } 140 if ( ! $version ) { 141 throw new Exception( __METHOD__ . ": A version for $plugin_slug cannot be determined." ); 146 if ( $in_cache ) { 147 $value = $meta[ $meta_key ][0]; 148 } else { 149 // Check our specific cache groups. 150 $value = wp_cache_get( $post_id, 'plugin-meta-' . $meta_key, false, $found ); 151 152 if ( ! $found ) { 153 $value = $wpdb->get_var( $wpdb->prepare( 154 "SELECT meta_value FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s LIMIT 1", 155 $post_id, 156 $meta_key 157 ) ); 158 159 wp_cache_set( $post_id, $value, 'plugin-meta-' . $meta_key, 300 /* 5 mins */ ); 160 } 142 161 } 143 162 144 return $v ersion;163 return $value; 145 164 } 146 165 147 166 /** 148 167 * Retrieve the post_id for a Plugin slug. 149 168 * 150 169 * This function uses the Object Cache and $wpdb directly to avoid 151 170 * a dependency upon WordPress. 152 171 * 153 172 * @param string $plugin_slug The plugin slug. 154 173 * @return int The post_id for the plugin. Exception thrown on failure. 155 174 */ 156 175 protected function get_post_id( $plugin_slug ) { 157 176 global $wpdb; 158 177 159 178 $post_id = wp_cache_get( $plugin_slug, 'plugin-slugs' ); 160 179 if ( false === $post_id ) { 161 $post_id = $wpdb->get_var( $wpdb->prepare( "SELECT ID from $wpdb->posts WHERE post_type = 'plugin' AND post_name = %s", $plugin_slug ) ); 180 $post_id = $wpdb->get_var( $wpdb->prepare( 181 "SELECT ID FROM $wpdb->posts WHERE post_type = 'plugin' AND post_name = %s LIMIT 1", 182 $plugin_slug 183 ) ); 184 162 185 wp_cache_add( $plugin_slug, $post_id, 'plugin-slugs' ); 163 186 } 164 187 165 188 if ( ! $post_id ) { 166 189 throw new Exception( __METHOD__ . ": A post_id for $plugin_slug cannot be determined." ); 167 190 } 168 191 169 192 return $post_id; 170 193 } 171 194 172 195 /** 173 196 * Returns the file to be served for the request. 174 197 * 175 198 * @param array $request The request object for the request. 176 199 * @return array The file to serve.